Doctrine Extension Translatable doesn't retrieve translation - symfony

I use personal translation of StofDoctrineExtensionsBundle.
I've configured my App but i can't retrieve the translated labels, i get always the default text.
config.yml
# Doctrine Configuration
doctrine:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
mappings:
menu_tree:
type: annotation
prefix: Gedmo\Tree\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
alias: MenuTree
is_bundle: false
gedmo_translatable:
type: annotation
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable # (optional) it will default to the name set for the mapping
is_bundle: false
gedmo_translator:
type: annotation
prefix: Gedmo\Translator\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translator/Entity"
alias: GedmoTranslator # (optional) it will default to the name set for the mapping
is_bundle: false
stof_doctrine_extensions:
default_locale: "%locale%"
translation_fallback: true
orm:
default:
tree: true
translatable: true
sluggable: true
Then i wrote my personal Entity, this is a MenuItem
<?php
namespace App\Entity\Menu;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
*
* #ORM\Table(name="mnu_item")
* #ORM\Entity(repositoryClass="App\Repository\Menu\MenuItem")
* #Gedmo\Tree(type="nested")
* #Gedmo\TranslationEntity(class="App\Entity\Menu\MenuItemTranslation")
*/
class MenuItem{
/**
*
* #var integer
*
* #ORM\Column(name="id", type="integer", options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #var string
* #Gedmo\Translatable
* #ORM\Column(name="label", type="string", length=255, nullable=true)
*/
private $label;
/**
* #Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
* and it is not necessary because globally locale can be set in listener
*/
private $locale;
/**
* #ORM\OneToMany(targetEntity="\App\Entity\Menu\MenuItemTranslation",
* mappedBy="object",
* cascade={"persist", "remove"})
*/
private $translations;
/**
* #var \App\Entity\Menu\Menu
*
* #ORM\ManyToOne(targetEntity="App\Entity\Menu\Menu", inversedBy="menuItems")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="menu_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
private $menu;
/**
* Constructor
*/
public function __construct() {
$this->ruoli = new \Doctrine\Common\Collections\ArrayCollection();
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set label
*
* #param string $label
*
* #return MenuItem
*/
public function setLabel($label) {
$this->label = $label;
return $this;
}
/**
* Get label
*
* #return string
*/
public function getLabel() {
return $this->label;
}
/**
* Set menu
*
* #param \App\Entity\Menu\Menu $menu
*
* #return MenuItem
*/
public function setMenu(\App\Entity\Menu\Menu $menu = null) {
$this->menu = $menu;
return $this;
}
/**
* Get menu
*
* #return \App\Entity\Menu\Menu
*/
public function getMenu() {
return $this->menu;
}
/**
*
* #return type
*/
public function getTranslations(){
return $this->translations;
}
/**
*
* #param \App\Entity\Menu\MenuItemTranslation $t
*/
public function addTranslation(MenuItemTranslation $t){
if (!$this->translations->contains($t)) {
$this->translations[] = $t;
$t->setObject($this);
}
}
public function setTranslatableLocale($locale){
$this->locale = $locale;
}
}
At least i have my Translator Class
<?php
namespace App\Entity\Menu;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation;
/**
* Description of MenuItemTranslation
/*
* #ORM\Entity
* #ORM\Table(name="mnu_menu_item_translations",
* uniqueConstraints={#ORM\UniqueConstraint(name="lookup_unique_idx", columns={
* "locale", "object_id", "field"
* })}
* )
*/
class MenuItemTranslation extends AbstractPersonalTranslation {
/**
* Convenient constructor
*
* #param string $locale
* #param string $field
* #param string $value
*/
public function __construct($locale, $field, $value)
{
$this->setLocale($locale);
$this->setField($field);
$this->setContent($value);
}
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Menu\MenuItem", inversedBy="translations")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $object;
}
I have translated my label and it works, but in a twig tempate, using item.label or item.getLabel() i obtain always the default MenuItem valu (E.g. Test insted of Prova, see images)
Menu Item
Menu Item Translation

I've messed with locale.
I changed the stof config 'cos my site is all in english and i need italian translation
stof_doctrine_extensions:
default_locale: "%locale%" #this is my error, just remove this line
# to set it back to en_US (default value).
# This indicates the locale of original table,
# if it's set to the same
# locale of the entire system it won't
# retrieve any translation
translation_fallback: true
orm:
default:
tree: true
translatable: true
sluggable: true
So the correct one is
Then i changed the stof config 'cos my site is all in english and i need italian translation
stof_doctrine_extensions:
translation_fallback: true
orm:
default:
tree: true
translatable: true
sluggable: true

Related

Error FOSUserBundle / User Entity already done

I have this error when i try to do http://localhost:8000/profile or any search :
(1/1) FatalErrorException
Compile Error: Access level to AppBundle\Entity\User::$id must be protected (as in class FOS\UserBundle\Model\User) or weaker
in User.php line 19
I just want to create a webpage for admin for my application (that webpage will be like a dashboard) and i don't know how to set access to this webpages for only admin so i tried with FOSUser with a login but if there is a quicker method just tell me (i tried the method : https://symfony.com/doc/current/security/form_login_setup.html but that don't work to it just reload the page when i click submit.)
pls help
My config.yml :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where
the app is deployed
#
https://symfony.com/doc/current/best_practices/configuration.html#
application-related-configuration
parameters:
locale: en
image_directory: '%kernel.project_dir%/web/uploads/images'
framework:
#esi: ~
translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
default_locale: '%locale%'
trusted_hosts: ~
session:
#
https://symfony.com/doc/current/reference/configuration/framework.html
#handler-id
handler_id: session.handler.native_file
save_path:
'%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path:
'%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
fos_user:
registration:
form:
type: AppBundle\Form\RegistrationType
db_driver: orm # other valid values are 'mongodb' and 'couchdb'
firewall_name: main
user_class: AppBundle\Entity\User
service: # this lines
mailer: fos_user.mailer.twig_swift # this lines
from_email:
address: "testapp#testapp.com"
sender_name: "Test App"
My security file :
# app/config/security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
default_target_path: /list
always_use_default_target_path : true
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
And that is my user entity :
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
/**
* User
*
* #ORM\Table(name="user", uniqueConstraints=
{#ORM\UniqueConstraint(name="user_id_uindex", columns={"id"}),
#ORM\UniqueConstraint(name="user_username_uindex", columns=
{"username"})}, indexes={#ORM\Index(name="user_profile_id_fk",
columns={"id_profile"}), #ORM\Index(name="user_localisation_id_fk",
columns={"id_location"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* #UniqueEntity("username", groups={"Default", "Patch"})
*/
class User extends BaseUser
{
const ROLE_USER = 'ROLE_USER';
const ROLE_ADMIN = 'ROLE_ADMIN';
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #Serializer\Groups({"Default", "Deserialize", "user_detail"})
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=32, nullable=false)
* #Serializer\Groups({"Default", "Deserialize", "user_detail"})
*/
private $username;
/**
* #var string
* #Serializer\Type("string")
* #Assert\Expression(
* "this.getPassword() === this.getRetypedPassword()",
* message="Password does not match",
* groups={"Default", "Patch"}
* )
* #Assert\NotBlank(groups={"Default"})
* #Serializer\Groups({"Deserialize"})
*/
private $retypedPassword;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255, nullable=false)
* #Serializer\Groups({"Deserialize", "user_detail"})
* #Assert\Regex(
* pattern="/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{7,}/",
* message="Password must be seven characters long and contain at least one digit code, upper case, and lower case letter!",
* groups={"Default", "Patch"}
* )
*/
private $password;
/**
* #var boolean
*
* #ORM\Column(name="enabled", type="boolean", nullable=false)
*/
private $enabled = '1';
/**
* #var \AppBundle\Entity\Localisation
*
* #ORM\ManyToOne(targetEntity="Localisation")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_location", referencedColumnName="id")
* })
*/
private $idLocation;
/**
* #var \AppBundle\Entity\Profile
*
* #ORM\ManyToOne(targetEntity="Profile")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_profile", referencedColumnName="id")
* })
*/
private $idProfile;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="User", inversedBy="idUserOne")
* #ORM\JoinTable(name="friend",
* joinColumns={
* #ORM\JoinColumn(name="id_user_one", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="id_user_two", referencedColumnName="id")
* }
* )
*/
private $idUserTwo;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Place", inversedBy="idUserInvited")
* #ORM\JoinTable(name="list_invited",
* joinColumns={
* #ORM\JoinColumn(name="id_user_invited", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="id_place_invited", referencedColumnName="id")
* }
* )
*/
private $idPlaceInvited;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Place", mappedBy="idUserPresent")
*/
private $idPlacePresent;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Place", inversedBy="idUserPlace")
* #ORM\JoinTable(name="user_place",
* joinColumns={
* #ORM\JoinColumn(name="id_user_place", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="id_place_place", referencedColumnName="id")
* }
* )
*/
private $idPlacePlace;
/**
* #var array
* #ORM\Column(type="simple_array", length=200)
* #Serializer\Exclude()
*/
private $roles;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->idUserTwo = new \Doctrine\Common\Collections\ArrayCollection();
$this->idPlaceInvited = new \Doctrine\Common\Collections\ArrayCollection();
$this->idPlacePresent = new \Doctrine\Common\Collections\ArrayCollection();
$this->idPlacePlace = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* #return string
*/
public function getUsername(): string
{
return $this->username;
}
/**
* #param string $username
*/
public function setUsername(string $username): void
{
$this->username = $username;
}
/**
* #return string
*/
public function getPassword(): string
{
return $this->password;
}
/**
* #param string $password
*/
public function setPassword(string $password): void
{
$this->password = $password;
}
/**
* #return bool
*/
public function isEnabled(): bool
{
return $this->enabled;
}
/**
* #param bool $enabled
*/
public function setEnabled(bool $enabled): void
{
$this->enabled = $enabled;
}
/**
* #return mixed
*/
public function getIdLocation()
{
return $this->idLocation;
}
/**
* #param mixed $idLocation
*/
public function setIdLocation($idLocation): void
{
$this->idLocation = $idLocation;
}
/**
* #return mixed
*/
public function getIdProfile()
{
return $this->idProfile;
}
/**
* #param mixed $idProfile
*/
public function setIdProfile($idProfile): void
{
$this->idProfile = $idProfile;
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdUserTwo(): \Doctrine\Common\Collections\Collection
{
return $this->idUserTwo;
}
/**
* #param \Doctrine\Common\Collections\Collection $idUserTwo
*/
public function setIdUserTwo(\Doctrine\Common\Collections\Collection $idUserTwo): void
{
$this->idUserTwo = $idUserTwo;
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdPlaceInvited(): \Doctrine\Common\Collections\Collection
{
return $this->idPlaceInvited;
}
/**
* #param \Doctrine\Common\Collections\Collection $idPlaceInvited
*/
public function setIdPlaceInvited(\Doctrine\Common\Collections\Collection $idPlaceInvited): void
{
$this->idPlaceInvited = $idPlaceInvited;
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdPlacePresent(): \Doctrine\Common\Collections\Collection
{
return $this->idPlacePresent;
}
/**
* #param \Doctrine\Common\Collections\Collection $idPlacePresent
*/
public function setIdPlacePresent(\Doctrine\Common\Collections\Collection $idPlacePresent): void
{
$this->idPlacePresent = $idPlacePresent;
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getIdPlacePlace(): \Doctrine\Common\Collections\Collection
{
return $this->idPlacePlace;
}
/**
* #param \Doctrine\Common\Collections\Collection $idPlacePlace
*/
public function setIdPlacePlace(\Doctrine\Common\Collections\Collection $idPlacePlace): void
{
$this->idPlacePlace = $idPlacePlace;
}
/**
* #return string
*/
public function getRetypedPassword(): string
{
return $this->retypedPassword;
}
/**
* #param string $retypedPassword
*/
public function setRetypedPassword(string $retypedPassword): void
{
$this->retypedPassword = $retypedPassword;
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return (Role|string)[] The user roles
*/
public function getRoles()
{
return $this->roles;
}
/**
* #param array $roles
*/
public function setRoles(array $roles)
{
$this->roles = $roles;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
// TODO: Implement getSalt() method.
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
}

FOSRestBundle not use JMSSerializerBundle

I have configured Symfony 3 to auto serialize my action. It works, but the relations aren't serialized:
0
id 1
name "Liste de course"
creation_date "2017-07-07T00:00:00+00:00"
last_update_date "2017-07-07T20:57:06+00:00"
user_entity
_todo_entity_entities
_parent_entity
1
id 2
name "domotique"
creation_date "2017-07-07T00:00:00+00:00"
last_update_date "2017-07-07T21:22:52+00:00"
user_entity
_todo_entity_entities
_parent_entity
If I explicitly use JMSSerializerBundle, it works (user_entity is an object):
0
id 1
name "Liste de course"
creation_date "2017-07-07T00:00:00+00:00"
last_update_date "2017-07-07T20:57:06+00:00"
user_entity Object
_todo_entity_entities
1
id 2
name "domotique"
creation_date "2017-07-07T00:00:00+00:00"
last_update_date "2017-07-07T21:22:52+00:00"
user_entity Object
_todo_entity_entities
I think FOSRestBundle uses the default seralizer, not JMSSerializerBundle:
/**
* #Rest\Get("/projects")
* #View(
* serializerGroups = {"all"}
* )
*/
public function getProjectsAction()
{
$projectEntity = $this->getDoctrine()->getRepository('todoListAdminBundle:Project');
$projects = $projectEntity->findAll();
/*
$data = $this->get('jms_serializer')->serialize($projects, 'json');
// this is work !
$response = new Response($data);
$response->headers->set('Content-Type', 'application/json');
return $response;
*/
return $projects;
}
The entity I serialize :
/**
* Project
*
* #ORM\Table(name="project")
* #ORM\Entity(repositoryClass="todoListAdminBundle\Repository\ProjectRepository")
*/
class Project
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Serializer\Groups({"all"})
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #Assert\Length(max=50)
* #Assert\Type(type="string")
* #Serializer\Groups({"all"})
*/
private $name;
/**
* #var \DateTime
*
* #ORM\Column(name="creation_date", type="date")
* #Assert\DateTime()
* #Serializer\Groups({"all"})
*/
private $creationDate;
/**
* #var \DateTime
*
* #ORM\Column(name="last_update_date", type="datetime")
* #Assert\DateTime()
* #Serializer\Groups({"all"})
*/
private $lastUpdateDate;
/**
*
* #ORM\ManyToOne(targetEntity="PW\UserBundle\Entity\User", inversedBy="projectEntities" , cascade={"persist"}, inversedBy="projectEntities")
* #Assert\Type(type="integer")
* #Serializer\Groups({"all"})
*/
private $userEntity;
/**
* #ORM\OneToMany(targetEntity="todoListAdminBundle\Entity\TodoEntity", mappedBy="projectEntity", fetch="EAGER")
* #Serializer\Groups({"all"})
*/
private $TodoEntityEntities;
/**
* #var int
*
* #ORM\JoinColumn(nullable=true, referencedColumnName="id")
* #ORM\OneToOne(targetEntity="todoListAdminBundle\Entity\Project")
* #Assert\Type(type="integer")
* #Serializer\Groups({"all"})
*/
private $ParentEntity;
My configuration :
fos_rest:
param_fetcher_listener: true
body_listener: true
zone:
- { path: ^/api/* }
body_converter:
enabled: true
view:
formats: { json: true, xml: false, rss: false }
view_response_listener: true
serializer:
serialize_null: true
format_listener:
enabled: true
rules:
- { path: '^/api', priorities: ['json'], fallback_format: 'json' }
routing_loader:
default_format: json
sensio_framework_extra:
view: { annotations: true }
How can I use JMSSerializerBundle automatically ?
First of all, you need to configure JMSSerializer in your config.yml like:
jms_serializer:
metadata:
cache: file
debug: "%kernel.debug%"
file_cache:
dir: "%kernel.cache_dir%/serializer"
auto_detection: true
Then, create directory with serializer for the given entity YourBundleName/Resources/config/serializer/Entity.Project.yml with this code:
YourBundleName\Entity\Project:
exclusion_policy: ALL
properties:
id:
expose: true
name:
expose: true
"exclusion_policy: ALL" - exclude all the fields from the serialized result. And then you add needed fields with "expose: true". Just do not add "ParentEntity" there and you will not see it in the serialized data (also, I do not think, that mix of camel and pascal case is a good practice, but it's the question of taste).

StofDoctrineExtensionsBundle seems to not work with Entities configured by YML

I try to use softdelete in my application, but it doesn't work. When I delete an entity, it's also deleted from the database.
I installed "stof/doctrine-extensions-bundle": "1.2.*#dev" and added it to the Kernel.
My Configuration:
stof_doctrine_extensions:
orm:
default:
...
softdeleteable: true
doctrine:
...
orm:
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
enabled: true
My YML-Definition:
...\Entity\Person:
type: entity
table: person
id:
id:
...
fields:
salutation:
type: string
length: 255
...
deletedAt:
type: datetime
nullable: true
My Entity:
<?php
namespace ...\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Person
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class Person
{
...
/**
* #var \DateTime
*/
private $deletedAt;
...
/**
* Set deletedAt
*
* #param \DateTime $deletedAt
* #return NaturalPerson
*/
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* Get deletedAt
*
* #return \DateTime
*/
public function getDeletedAt()
{
return $this->deletedAt;
}
}

Symfony2 - translatable field - The class 'Gedmo\Translatable\Entity\Translation' was not found in the chain configured namespaces

I'm trying to translate some fields of my entity and I have the following error when I'm try create an object...
<?php
namespace XXXX\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Translatable;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Line
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="XXXX\Entity\LineRepository")
*/
class Line implements Translatable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Line
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
public function setTranslatableLocale($locale)
{
$this->locale = $locale;
}
}
And the error:
[Doctrine\Common\Persistence\Mapping\MappingException]
The class 'Gedmo\Translatable\Entity\Translation' was not found in the chain configured namespaces
I'm using Symfony 2.5, but in 2.4 occurs too. Any idea how I can solve this?
You need to configure the translatable Entity to use as well. In config.yml:
orm:
(....)
mappings:
translatable:
type: annotation
is_bundle: false
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable
Update for Symfony 5 :
Configure the /config/packages/doctrine.yaml file and add the following
orm:
(....)
mappings:
translatable:
type: annotation
is_bundle: false
prefix: Gedmo\Translatable\Entity
dir: '%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Translatable/Entity'
alias: GedmoTranslatable

Unrecognized field: usernameCanonical for symfony2 FosUserbundle

I have a problem with the FOSUserBundle.
A know problem : 'Unrecognized field: usernameCanonical for symfony2 FosUserbundle' when I try a login
AND
on schema update I get this error:
Duplicate definition of column 'username' on entity 'Acme\ProjectBundle\Entity\User' in a field or discriminator column mapping.
I get this error ONLY IF I add the 'FOSUserBundle: ~' to settings of doctrine's mapping in the config.yml
I have tried a lot of solutions but I don't have resoved my problem :/
Please help me.
I have followed the FOS' team: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md
Before everything worked perfectly ...
I have Symfony 2.1.9
My config.yml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
service:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
#auto_mapping: true
default_entity_manager: default
entity_managers:
default:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
connection: default
mappings:
FOSUserBundle: ~
AcmeProjectBundle: {type: yml, dir: Resources/config/doctrine/ } #also tried wit '~'
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: Acme\ProjectBundle\Entity\User
My Acme\ProjectBundle\Entity\User.php:
namespace Acme\ProjectBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
class User extends BaseUser implements UserInterface, \Serializable
{
const TYPE_ADMIN = 0;
const TYPE_USER = 2;
const TYPE_ARTIST = 3;
/**
* #var string $salt
*/
protected $salt;
/**
* #var boolean $is_active
*/
private $is_active;
protected $id;
private $name;
protected $username;
protected $email;
/**
* #var tinyint $type
*/
private $type;
protected $password;
private $description;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set type
*
* #param integer $type
* #return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Set description
*
* #param string $description
* #return User
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set username
*
* #param string $username
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
public function isPasswordName()
{
return ($this->name != $this->password);
}
public function isPassUsername()
{
return ($this->password != $this->username);
}
/**
* #var \DateTime $date
*/
private $date;
/**
* Set date
*
* #param \DateTime $date
* #return User
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
private $updateDate;
/**
* Set updateDate
*
* #param \DateTime $updateDate
* #return User
*/
public function setUpdateDate($updateDate)
{
$this->updateDate = $updateDate;
return $this;
}
/**
* Get updateDate
*
* #return \DateTime
*/
public function getUpdateDate()
{
return $this->updateDate;
}
public function setIsActive($value)
{
$this->is_active = $value;
return $this;
}
public function gettIsActive()
{
return $this->is_active;
return $this;
}
/**
* Set salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
public function getRoles()
{
switch ($this->getType())
{
case 0:
return array('ROLE_ADMIN');
break;
case 1:
case 2:
case 3:
return array('ROLE_USER');
break;
}
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
/**
* #var integer $first_login
*/
private $first_login;
/**
* Get is_active
*
* #return boolean
*/
public function getIsActive()
{
return $this->is_active;
}
/**
* Set first_login
*
* #param integer $firstLogin
* #return User
*/
public function setFirstLogin($firstLogin)
{
$this->first_login = $firstLogin;
return $this;
}
/**
* Get first_login
*
* #return integer
*/
public function getFirstLogin()
{
return $this->first_login;
}
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $userPoints;
/**
* #var integer $privacy
*/
private $privacy;
/**
* Set privacy
*
* #param integer $privacy
* #return User
*/
public function setPrivacy($privacy)
{
$this->privacy = $privacy;
return $this;
}
/**
* Get privacy
*
* #return integer
*/
public function getPrivacy()
{
return $this->privacy;
}
/**
* #var integer
*/
private $enable;
/**
* Set enable
*
* #param integer $enable
* #return User
*/
public function setEnable($enable)
{
$this->enable = $enable;
return $this;
}
/**
* Get enable
*
* #return integer
*/
public function getEnable()
{
return $this->enable;
}
}
My security.yml
security:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
csrf_provider: form.csrf_provider
logout: true
anonymous: true
providers:
fos_userbundle:
id: fos_user.user_provider.username
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
It seems your version of the FOSUserBundle is not good ... I had the same problem with a 1.3.* that I solved just changing this to version "~2.0#dev".
You can check this looking at your "fos_user" table ; if it just contains a single "id" field, your User entity is not extending the right "FOS\Entity\User" object ... try to upgrade your required version of the bundle in your "composer.json" and then rebuild your tables (below a full HARD rebuild - data are lost):
php app/console doctrine:schema:drop --force
php app/console doctrine:schema:create
If your "fos_user" table have all required fields, then you're good.
Review the docs on creating a use class: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md
Your User class should not be repeating all the properties (username etc) from the base class. It should only have the new properties like name and id.
And while you didn't show your doctrine mapping file, I'm guessing your probably duplicated everything in there is well? Only map the new properties.
In fact, i guess, you should have some piece of code on config.yml as
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: Acme\ProjectBundle\Entity\User
and you should have no need to add sth. to orm settings for FOSUser.
orm:
auto_generate_proxy_classes: "%kernel.debug%"
#auto_mapping: true
default_entity_manager: default
entity_managers:
default:
// that's for APCu or APC
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
in dev env APC disabled, that's why you get this error. You have to comment it for dev or enable cacheClassLoader
I had this trouble and applied PieroWbmstr's suggestion, and started using 2.0 instead of 1.3.6... with doctrine.orm.auto_mapping set to true in config.yml
Once I made the composer.json version switch and upgraded, my doctrine:schema:update instantly recognised the new fields as missing in the current database instance, and applied them.
The newer version of the user class within FOS/UserBundle doesn't seem to have any significant changes that would force the mapping to play nicely. Does anyone have an idea as to what the difference is in these two versions? Or more directly, why the older version somehow didn't let doctrine recognise it's xml mappings (hint: in both of my FOS/UserBundle versions, I had my local custom bundles set to use annotations).
Thanks

Resources