I'm using Symfony 3.4 and knp doctrine behaviors for translation.
My entity Article looks like:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Article
*
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ArticleRepository")
*/
class Article
{
use ORMBehaviors\Translatable\Translatable;
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//...
}
Then I have entity ArticleTranslation
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* #ORM\Entity
*/
class ArticleTranslation
{
use ORMBehaviors\Translatable\Translation;
/**
* #ORM\Column(type="string", length=128)
*/
protected $headline;
//...
}
Now my app throws me an error:
Unable to find the association target class of "headline" in AppBundle\Entity\Article.
It expects a relation between Article and ArticleTranslation. There is a sentence in the documentation:
The default naming convention (or its customization via trait methods) avoids you to manually handle entity associations. It is handled automatically by the TranslationSubscriber.
Why does this happen? What am I missing?
edit
bin/console doctrine:schema:update
[OK] Nothing to update - your database is already in sync with the current entity metadata.
bin/console debug:config knp_doctrine_behaviors
knp_doctrine_behaviors:
translatable: true
blameable: false
geocodable: false
loggable: false
sluggable: false
soft_deletable: false
sortable: false
timestampable: false
tree: false
I'm using this in sonata admin, with a2lix translatable.
ArticleAdmin.php:
<?php
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use A2lix\TranslationFormBundle\Form\Type\TranslationsType;
final class ArticleAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('headline', TranslationsType::class);
}
//...
}
Try to use
$formMapper->add('translations', TranslationsType::class);
I had the same problem. Probably the field name needs to be exactly translations.
Related
I have a problem on fixtures with fzaninotto/faker on a symfony project, i have some table with relations ManyToOne who not complete automaticaly when I load fixtures since i have update bundles on composer.
There is an error and a message who tell me to add cascad persist but if i do that the entry is create twice. The is my code and my error message, sorry for my bad english...
Project entity:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #ORM\Table(name="`user`");
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $firstname;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $lastname;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Role")
* #ORM\JoinColumn(nullable=false)
*/
private $role;
Role Entity:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\RoleRepository")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=100, unique=true)
*/
private $name;
/**
* #ORM\Column(type="string", length=100, unique=true)
*/
private $code;
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="role")
*/
private $users;
Fixtures file:
<?php
namespace App\DataFixtures;
use Faker\Factory;
use App\Entity\Tag;
use App\Entity\Role;
use App\Entity\User;
use App\Entity\Skill;
use App\Entity\Follow;
use App\Entity\Statut;
use App\Entity\Techno;
use App\Entity\Comment;
use App\Entity\Project;
use App\Entity\Request;
use App\DataFixtures\Provider;
use Faker\ORM\Doctrine\Populator;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
$generator = Factory::create('fr_FR');
// Ajout provider custom Provider
$generator->addProvider(new Provider($generator));
$populator = new Populator($generator, $manager);
// REMPLIT LES TABLES SIMPLES
// table "role"
$populator->addEntity(
Role::class,
2,
[
'name' => function () use ($generator) {
return $generator->unique()->randomElement(['Administrateur', 'Utilisateur']);
}
]
);
// table "user"
$populator->addEntity(
User::class,
10,
[
'firstname' => function () use ($generator) {
return ($generator->firstName());
},
'lastname' => function () use ($generator) {
return ($generator->lastName());
},
]
);
And my error message when i load fixtures:
In ORMInvalidArgumentException.php line 105:
Multiple non-persisted new entities were found through the given association graph:
* A new entity was found through the relationship 'App\Entity\User#role' that was not configured to cascade persist operations
for entity: Administrateur. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or conf
igure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}).
* A new entity was found through the relationship 'App\Entity\User#role' that was not configured to cascade persist operations
for entity: Utilisateur. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configu
re cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}).
Same issue with 1.9 version, so just downgrade :
1/ Remove faker folder in vendor.
2/ Change composer.json from
"fzaninotto/faker": "^1.9"
to
"fzaninotto/faker": "1.8"
3/ Run composer update
--> Breath now...
I am a beginner in symfony 3. I currently have problems after installing FOSUserBundle. By creating my User entity I get this error: Error when access to app_dev.php
Here my entity User.php :
namespace SocialclockBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="SocialclockBundle\Repository\UserRepository")
*/
class User extends BaseUser
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
And my UserRepository.php :
use Doctrine\ORM\EntityRepository;
namespace SocialclockBundle\Repository;
/**
* UserRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends EntityRepository
{
}
Thank for your help !!!
florian
You need to put the use after the namespace
namespace SocialclockBundle\Repository;
use Doctrine\ORM\EntityRepository;
I want to extend default user entity attributes. In database after extending FOSUserBundle with SonataUserBunle there are 2 tables for storing users: fos_user and fos_user_user. I want to extend fos_user
Here is app/AppKernel.php:
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),
new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),
in app/config.yml file I set:
fos_user:
db_driver: orm<br>
firewall_name: main<br>
user_class: Acme\DemoBundle\Entity\User<br>
group:<br>
group_class: Application\Sonata\UserBundle\Entity\Group<br>
sonata_user:
security_acl: true
class:
user: Acme\DemoBundle\Entity\User
admin:
user:
class: Acme\DemoBundle\Admin\UserAdmin
parameters:
sonata.user.admin.user.class: Blogger\BlogBundle\Admin\UserAdmin
sonata.user.admin.user.entity: Blogger\BlogBundle\Entity\User
doctrine:
orm:
auto_mapping: auto
SonataUserBundle is created in src/Application/Sonata/UserBundle
To override SonataUserBundle, i extended UserAdmin by creating another UserAdmin class in src/Acme/DemoBundle/Admin/UserAdmin and all works fine
Now I want to extend User entity (fos_user table) to add new attributes.
Here is my Acme/Demo/Entity/User.php that I want to extend the default User entity
namespace Acme\DemoBundle\Entity;
use FOS\UserBundle\Entity\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;
/*
* #ORM\Column(type="string", name="newAttribute")
*/
protected $newAttribute;
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
What should I do to extend default fos_user table with php app/console doctrine:generate:entities Acme/DemoBundle
I've read many posts about this issue but none of the solutions helped me. I tried to extend Model class instead of Entity class but also nothing changed
You don't have to.
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle')
Here your are telling the SonataUserBundle to use the FOSUserBundle as well.
Then in your User entity you set:
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="User")
*/
class User extends BaseUser
Because you have said to the SonataUserBundle "use the fosuserbundle" and you extend from the sonata user bundle user entity he's gonna "merge" those 2 models into 1 and add your custom fields from in your user entity as well.
I am trying to sort by a property which is not in relation but part of current entity.
For some reason sortable wont work for me if property with #Gedmo\SortableGroup is part of current entitty.
Here is my Entity:
https://gist.github.com/rat4m3n/91df50da8c653edfa3d0
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #Gedmo\SortableGroup
* #ORM\Column(name="total_chips", type="integer")
*/
private $total_chips = 0;
/**
* #Gedmo\SortablePosition
* #ORM\Column(name="ranking", type="integer")
*/
private $ranking = 0;
Is this simply not possible / supported ?
Else... how could I accomplish such behaviour in any other way?
If you still have a problem with the SortablePosition and the SortableGroup feature of Gedmo, you can follow this :
Do not affect values to the property.
Activate the features in the config.yml
stof_doctrine_extensions:
default_locale: fr_FR
orm:
default:
sortable: true
tree: true
And add the listener to your entity :
namespace Acme\AcmeBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeAcmeBundle extends Bundle
{
public function boot()
{
$em = $this->container->get('doctrine.orm. default_entity_manager');
$evm = $em->getEventManager();
$evm->addEventSubscriber(new \Gedmo\Sortable\ SortableListener);
}
}
I have a custom validator in src/VNN/PressboxBundle/Component/Validator/CurrentPasswordValidator.php:
<?php
namespace VNN\PressboxBundle\Component\Validator\Constraints;
use Symfony\Component\Validator\ConstraintValidator,
Symfony\Component\Validator\Constraint,
Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface,
Symfony\Component\Security\Core\SecurityContextInterface,
JMS\DiExtraBundle\Annotation\Validator,
JMS\DiExtraBundle\Annotation\InjectParams,
JMS\DiExtraBundle\Annotation\Inject;
/**
* #Validator("user.validator.current_password")
*/
class CurrentPasswordValidator extends ConstraintValidator
{
// ...
}
And then I have this at src/VNN/PressboxBundle/Component/Validator/Contraints/CurrentPassword.php:
<?php
namespace VNN\PressboxBundle\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class CurrentPassword extends Constraint
{
public $message = "Your current password is not valid";
/**
* #return string
*/
public function validatedBy()
{
return 'user.validator.current_password';
}
}
For some reason, when I try to add an annotation that uses this validator, I get an error. Here's my entity/annotation:
<?php
namespace VNN\PressboxBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinTable as JoinTable;
use Doctrine\ORM\Mapping\JoinColumn as JoinColumn;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContext;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\MaxLength;
use Symfony\Component\Validator\Constraints\Email;
use VNN\PressboxBundle\Component\Validator\Constraints\CurrentPassword;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* VNN\PressboxBundle\Entity\User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #var string $password
* #Assert\NotBlank()
* #CurrentPassword()
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
}
The error I'm getting is:
AnnotationException: [Semantical Error] The annotation
"#VNN\PressboxBundle\Component\Validator\Constraints\CurrentPassword"
in property VNN\PressboxBundle\Entity\User::$password does not exist,
or could not be auto-loaded.
What am I doing wrong?
Check that VNN\PressboxBundle\VNNPressboxBundle() is correctly registered with the kernel in AppKernel.php.
Update: If it is correctly registered, and src/ is registered as a fallback with the autoloader (assuming VNN/ is under src/), you may want to try and load the service yourself manually and check the stack trace if/when it fails:
$validator = $container->get('user.validator.current_password');
// Pretending this is a unit test:
// $this->assertInstanceOf('VNN\PressboxBundle\Component\Validator\Constraints\CurrentPasswordValidator', $validator);
Also, make sure you have cleared the cache (if not testing in dev environment).
Side note (but unrelated to your problem) - if you start to add more validators, it will be more useful to use this syntax:
<?php
namespace VNN\PressboxBundle\Entity;
use VNN\PressboxBundle\Component\Validator\Constraints as VNN;
class User implements UserInterface, \Serializable
{
/**
* #VNN\CurrentPassword
*/
private $password;
}