I have got logging working on my entity so that when I make a change to a product field with the #Gedmo\Versioned annotation a new version is created. However the only problem is that the username field remains NULL. There is an authenticated user as the update is performed in Sonata Admin backend.
<?php
namespace MyApp\CmsBundle\Entity\Log;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry;
use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
/**
* #ORM\Entity(repositoryClass="Gedmo\Loggable\Entity\Repository\LogEntryRepository", readOnly=true)
* #ORM\Table(
* name="log_product",
* indexes={
* #ORM\Index(name="log_class_lookup_idx", columns={"object_class"}),
* #ORM\Index(name="log_date_lookup_idx", columns={"logged_at"}),
* #ORM\Index(name="log_user_lookup_idx", columns={"username"}),
* }
* )
*/
class ProductLog extends AbstractLogEntry
{
}
So it would appear the log_user_lookup_idx isn't working correctly, is there a particular bit of config I require for this?
It appears I was missing a bit of config, adding the following to the main app/config/config.yml file did the trick.
stof_doctrine_extensions:
default_locale: en
orm:
default:
loggable: true
I did originally have this in my bundles' services.yml config:
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "#annotation_reader" ] ]
This managed to track the entity being modified but not the user, I have since removed this config and the logging remains to work with just the stof_doctrine_extensions config setting.
If you have both in your code base then everything will be logged twice I found.
Related
I want to use annotations with overblog graphql in symfony. When i create a provider with an query I get an error about the schema.
error: At least one schema should be declare
I don`t know how to config the schema in the config file. Normally I use yaml as type.
When I use the defaults its using CoreQuery whats pointing to the yaml config file. I don`t know how to change this for using annotations in php. When I remove the schema from definitions i get the same error.
What do I need to change to use annotation with overblog graphql bundle?
/config/packages/graphql.yaml
overblog_graphql:
definitions:
schema:
default:
query: CoreQuery
# mutation: CoreMutation
show_debug_info: '%kernel.debug%'
mappings:
auto_discover: false
types:
- type: annotation
dir: "%kernel.project_dir%/src/GraphQL"
suffix: ~
/src/Graphql/Types/SensorProviders.php
namespace App\Graphql\Types;
use Overblog\GraphQLBundle\Annotation as GQL;
/**
* #GQL\Provider
*/
class SensorProviders {
/**
* #GQL\Query(type="[Sensor]", name="sensors")
*/
public function getSensors() {
return [];
}
}
/src/Graphql/Types/Sensor.php
namespace App\Graphql\Types;
use Overblog\GraphQLBundle\Annotation as GQL;
/**
* #GQL\Type
*/
class Sensor
{
/**
* #GQL\Field(type="Integer!")
*/
public $id;
}
I had the same issues, but after hours of debugging, i figured it out:
With your graphql.yaml you would need following additional file:
/src/Graphql/Types/CoreQuery.php:
namespace App\Graphql\Types;
use Overblog\GraphQLBundle\Annotation as GQL;
/**
* #GQL\Type
*/
class CoreQuery
{
}
Basically you need to define an empty root type and all annotated queries get automatically added.
Same for mutations.
I use Symfony 3.4 with FOSUserBundle and EasyAdminBundle.
I've been stuck for a while on the following problem: when I create a new user via EasyAdmin, the password entered is not hashed, it remains clear in the database and in the edit form of the created user (in EasyAdmin), while there is no problem when I create a user via the form generated by FOSUserBundle (register).
My User entity :
<?php
// src/Repas/UserBundle/Entity/User.php
namespace Repas\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
My AdminController.php file :
<?php
namespace Repas\MenusBundle\Controller;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AdminController as BaseAdminController;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
class AdminController extends BaseAdminController
{
public function createNewUserEntity()
{
return $this->get('fos_user.user_manager')->createUser();
}
public function persistUserEntity($user)
{
$this->get('fos_user.user_manager')->updateUser($user, false);
parent::persistEntity($user);
}
public function updateUserEntity($user)
{
$this->get('fos_user.user_manager')->updateUser($user, false);
parent::updateEntity($user);
}
}
In my config.yml file :
easy_admin:
entities:
User:
class: Repas\UserBundle\Entity\User
export_path: '%kernel.root_dir/../var/export/user'
password_encoding: { algorithm: 'bcrypt', cost: 12 }
In my security.yml file :
encoders:
Repas\UserBundle\Entity\User: bcrypt
In my routing.yml file :
fos_user:
resource: "#FOSUserBundle/Resources/config/routing/all.xml"
easy_admin_bundle:
resource: "#RepasMenusBundle/Controller/AdminController.php"
type: annotation
prefix: /admin
I've been through many forums, as well as the official docs, I think I followed everything properly but I certainly missed something.
Thank you for your help.
The EasyAdminBundle doesn't define an option to encrypt the password, it only provides options to save the entities (a crud) which you can extend by defining custom actions based on routes or actions inside an overrided AdminController in order to integrate with FOSUserBundle.
Example
easy_admin:
entities:
User:
list:
actions:
- { name: 'create_user', type: 'route' } //or nothing on type to use the action option
At this point you already have either a defined controller accessible by route or an overriden controller which handles the specified User actions. You only need to use the FOSUser methods to encrypt the password properly, as read in this doc.
Hope it helps!
Ok, I guess my mistake is that in the form generated by Easyadmin to create a new user, Easyadmin generates a field named "password" instead of "plainPassword" which is the one FOSUser uses to encrypt the entered password. So I think I just have to create a new "plainPassword" field in my "Easyadmin new user" form and enter the user password in that field to encrypt it. Then the encrypted password will be stored in "password" field of the database.
I will tell you if that is the solution.
I want to split up my documentation for the api I am building. I am using NelmioApiDocBundle and they have a perfect way with the view annotation. Nelmio view The problem is my method stays in default view and not in the suggested oauth view:
So /doc/api/oauth/ or /api/doc/oauth ends in 404
//config.yml
# app/config/config.yml
nelmio_api_doc: ~
// app/config/routing.yml
NelmioApiDocBundle:
resource: "#NelmioApiDocBundle/Resources/config/routing.yml"
prefix: /api/doc
// routing.yml
profile_rest_oauth:
resource: "#ProfileBundle/Rest/Oauth/RestController.php"
type: rest
prefix: /api/oauth
profile_rest:
resource: "#ProfileBundle/Rest/Xwsse/RestController.php"
type: rest
prefix: /api
//RestController
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\HttpFoundation\Request;
class RestController extends FOSRestController
{
/**
* #ApiDoc(
* description="Update profile for user",
* section="profile",
* https=true,
* statusCodes={
* 200="OK, user profile updated",
* 400="Wrong input, no update"
* },
* views = { "oauth" }
* )
*/
public function putProfileAction(Request $request)
{
}
//composer.json
"nelmio/api-doc-bundle": "2.7.0",
To answer my own question: the version "2.7.0" in not compatible with the view parameter you need atleast 2.9.0". It's hard to understand it from the symfony documentation because it show version 2.x symfony documentation
Looks good man. At least i can say if you set up everything right - the /api/doc/oauth should never give you 404.
Try to change both your
resource: "#ProfileBundle/Rest/Xwsse/RestController.php"
to this like
resource: "#ProfileBundle/Resources/config/routing.yml"
I just want to make a multilingual application site so I red and saw translatable and other bundle.
I use translatable and a2lix... so I read the doc but when I try to use a2lix, I get this error message :
Class c2c\AppBundle\Entity\PeriodTranslation does not exist 500 Internal Server Error - ReflectionException
I set my entityTranslation in a subfolder like so Entity>Translation>MyEntityTranslation
Is there a way to say to a2lix... that it should look inside my sub-folder ?
Thank you for your help.
Entity
namespace c2c\AppBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Translatable;
/**
* Period
*
* #ORM\Table(name="Periods")
* #ORM\Entity(repositoryClass="c2c\AppBundle\Entity\PeriodRepository")
* #Gedmo\TranslationEntity(class="c2c\AppBundle\Entity\Translation\PeriodTranslation")
*/
class Period implements Translatable
...
Entity Translation
namespace c2c\AppBundle\Entity\Translation;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation;
/**
* PeriodTranslation is used fo
*
* #author blucas
*/
/**
* #ORM\Table(name="ext_translations_period", indexes={
* #ORM\Index(name="period_translation_idx", columns={"locale", "object_class", "field", "foreign_key"})
* })
* #ORM\Entity(repositoryClass="Gedmo\Translatable\Entity\Repository\TranslationRepository")
*/
class PeriodTranslation extends AbstractTranslation
{
/**
* All required columns are mapped through inherited superclass
*/
}
Config
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
mappings:
gedmo_translatable:
type: annotation
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable
is_bundle: false
...
# Soft Doctrine extendions
stof_doctrine_extensions:
default_locale: en_US
# Only used if you activated the Uploadable extension
# uploadable:
# Default file path: This is one of the three ways you can configure the path for the Uploadable extension
# default_file_path: %kernel.root_dir%/../web/uploads
# Mime type guesser class: Optional. By default, we provide an adapter for the one present in the HttpFoundation component of Symfony
# mime_type_guesser_class: Stof\DoctrineExtensionsBundle\Uploadable\MimeTypeGuesserAdapter
# Default file info class implementing FileInfoInterface: Optional. By default we provide a class which is prepared to receive an UploadedFile instance.
# default_file_info_class: Stof\DoctrineExtensionsBundle\Uploadable\UploadedFileInfo
orm:
default:
# sluggable: true
translatable: true
...
# Give a way to translate form
a2lix_translation_form:
locale_provider: default
locales: [en,fr,nl]
default_locale: en
required_locales: [en]
manager_registry: doctrine
templating: "A2lixTranslationFormBundle::default.html.twig"
The error is thrown becous the newest version of a2lix is not compatible with the stable version of Gedmo
check this answer https://stackoverflow.com/a/22018321/2160958
If you want to use Gedmo strategy you will have to downgrade your "a2lix/translation-form-bundle" to "1.*#dev" if you want to use the newest version of "a2lix/translation-form-bundle" you will have to use
wip2.4 Gedmo version, with is unstable yet.
check this https://github.com/a2lix/TranslationFormBundle/blob/master/UPGRADE-2.0.md
Edit:
I've prepared a tar.gz which once uncompressed and after running ./bin/vendors install fails to load the fixtures through php scripts/createAll.php. In the tar.gz there are 2 bundles using 2 different connections everyone with its own database.
I think Symfony2 fails to manage them properly. If you take a look at scripts/createAll.php will see how symfony fails to load both fixtures, but if you remove a random fixture (it doesn't matter Var_.php or Foo_.php everything runs fine, which seems to me that symfony is failing to manage entities correctly.)
LINK: http://www.2shared.com/file/2u4GhFVX/SymfonyTestCasetar.html
i want to tell Symfony2 to use different entity managers for different Bundle
directories so my config.yml looks like:
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
myVendorURLCoreBundle: ~
myVendormyBundleBundle: ~
myVendormyBundleFooBundle:
prefix: "myVendor\myBundleFooBundle\Entity"
type: annotation
is_bundle: true
dir: "/Entity"
formacions:
connection: formacions
mappings:
myVendormyBundleFooBarBundle:
prefix: "myVendor\myBundleFooBarBundle\View"
type: annotation
is_bundle: false
dir: "%kernel.root_dir%/../src/myVendor/myBundleFooBarBundle/View"
The problem is when using relationships between the entities in the different directories i get the following error caused by vendor/doctrine/lib/Doctrine/ORM/Mapping/MappingException.php at line 142
Class FRJPC\SalleUrlFormacionsBundle\Entity\EspecialitatContingut is
not a valid entity or mapped super class
The probem is that sometimes "\" before the vendor name breaks the namespace. It's really strange.
Here is how i i link entities between each other:
namespace myVendor\myBundleFooBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity( repositoryClass="myVendor\myBundleFooBundle\Repository\ARepository" )
* #ORM\ChangeTrackingPolicy( "DEFERRED_EXPLICIT" )
* #ORM\Table( name="a" )
*/
class A
{
/**
* #ORM\Id
* #ORM\Column( type="integer", length="4" )
* #ORM\GeneratedValue( strategy="AUTO" )
*/
private $id;
/**
* #ORM\ManyToOne( targetEntity="\myVendor\myBundleFooBarBundle\Entity\B", inversedBy="a", cascade={"persist"} )
* #ORM\JoinColumn( name="FooBar", nullable=true, referencedColumnName="FooBar", onDelete="CASCADE" )
*/
private $fooBar;
}
Second entity:
namespace myVendor\myBundleFooBarBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity( repositoryClass="myVendor\myBundleFooBarBundle\Repository\ARepository" )
* #ORM\ChangeTrackingPolicy( "DEFERRED_EXPLICIT" )
* #ORM\Table( name="a" )
*/
class B
{
/**
* #ORM\Id
* #ORM\Column( type="integer", length="4" )
* #ORM\GeneratedValue( strategy="AUTO" )
*/
private $id;
/** #ORM\OneToMany( targetEntity="\myVendor\myBundleFooBundle\Entity\EspecialitatContingut", mappedBy="fooBar" ) */
private $a;
}
Does any one has a clue on how should i link each entity ?
PD: Both entities work like charm when they're in the same bundle and same directory.
All these Foos and Bars combined with an error message with a real name make it a bit difficult to follow and leaves open the possibility that posted code really doesn't match the actual code. The FooBarBundle/View seems to be an unlikely place to store entities.
In any event a given entity manager such as formacions needs to be able to see all the relevant entities including those involved in relations. It looks like you defined A in the foo bundle and B in the bar bundle and they both cross reference each other?
From your config, I don't see how the formacion em can see your A entity and likewise I don't see how the default em can see the B entity. The fully qualified class name in the relation is not enough to share the entity doctrine metadata. Hence the error messages.
I'd would actually be glad to be proven wrong about this. It's a bit frustrating not to be able to do these sorts of things.