A
A
Anton Dyshkant2017-06-22 18:48:34
symfony
Anton Dyshkant, 2017-06-22 18:48:34

How to use child entity class or decorator class in SonataAdminBundle (Symfony3, Doctrine ORM)?

Hello!
There was a need to display in the admin panel (SonataAdminBundle) not bare data, but slightly modified ones. For example, in a list of entities, display concatenated fields, or in ManyToOne and ManyToMany forms, display something special (and not just one of the entity fields).
This is implemented, in general, quite simply: in the corresponding methods of the Admin class, instead of the names of the properties, we indicate the names of our methods:

// в Admin-классе MyEntity
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
//            ->addIdentifier('name')
            ->addIndentifier('someCustomField')
        ;
    }

// в стороннем Admin-классе, добавляя сущность MyEntity по связи ManyToOne
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
//                    ->add('foo', ModelType::class, array(
//                        'class' => MyEntity::class,
//                        'property' => 'name'
//                    ))
                    ->add('foo', ModelType::class, array(
                        'class' => MyEntity::class,
                        'property' => 'someOtherCustomField'
                    ))
        ;
    }

// в Entity-классе
    public function getSomeCustomField()
    {
        return $this->name . ' foo';
    }

    public function getSomeOtherCustomField()
    {
        return $this->name . ' bar';
    }

There is a quite natural desire to move these methods somewhere else (or even to other places), because they are not directly related to the MyEntity entity (but are related to the representation of this entity in different parts of the admin panel).
Here's what I did: moved these methods to the MyEntityAdminDecorator class, making it an inheritor of the MyEntity entity class;
/**
 * @ORM\Table(name="my_entity")
 * @ORM\Entity
 */
class MyEntity
{

}

class MyEntityAdminDecorator extends MyEntity
{

}

Next, in the admin service configuration for MyEntity, I replaced the MyEntity argument with MyEntityAdminDecorator:
my_entity_sonata_admin_service:
    class: MyBundle\Admin\MyEntityAdmin
    arguments: [~, MyBundle\Entity\MyEntityAdminDecorator, ~] # было MyEntity
    tags:
        - name: sonata.admin
          manager_type: orm

Next, I tried to go to the admin panel and saw an error message:
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "..." as such route does not exist.").

I added two fields to the MyEntityAdmin class:
class MyEntityAdmin extends AbstractAdmin
{
    protected $baseRouteName = 'sonata_my_entity';
    protected $baseRoutePattern = 'my-entity';
    //...

After that, the admin panel loaded and I tried to go to the entity list page, but I didn’t succeed:
No entity manager defined for class MyBundle\Entity\MyEntityAdminDecorator

Those. Doctrine ORM (SUDDENLY) considers it to be some completely different entity for which there is no mapping information.
I use annotations (in the MyEntity class), but attempts to switch to xml or yml did not bring anything: I would have to duplicate the information in MyEntity.orm.xml and MyEntityAdminDecorator.orm.xml.
The steps described in the Doctrine ORM decorator class manual did not lead to the result that was expected.
Question: how to deal with this error? Or how to solve the problem described above in another way?
Thank you.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Denis, 2017-06-22
@prototype_denis

No need to inherit anything, decorate and create new methods
For list - custom template
For forms - listeners or types

S
shaqster, 2017-06-25
@shaqster

Those. Doctrine ORM (SUDDENLY) considers it to be some completely different entity for which there is no mapping information.
Sorry, but how else should she react? You have created a new entity in the entities folder and annotated it with an entity. From the fact that it is mapped from a table with which another entity is already mapped, the doctrine is neither hot nor cold.
Of course, because the article is a bit not about your problem. And besides that, you missed the key piece, namely:
** @MappedSuperclass */
abstract class Decorator extends Component

To solve the problem, we already wrote above: you need to make your own template for the field. Pick a bundle like SonataNews, there were definitely custom templates for the sheet.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question