Closed vyshkant closed 6 years ago
Any ideas about this? Maybe I'm doing something wrong?
What is the expected behavior on my case? How should the target entity choice possibility be shown? Should it be the radio button, or dropdown, or something like the provider selection window in SonataMediaBundle
?
@greg0ire @OskarStark @Soullivaneuh @core23 @jordisala1991
Sorry for concern, but I would like to understand: is the functionality described in the "Subject" section supported by SonataAdminBundle
?
How should I configure SonataAdminBundle
and admin pages to be able to choose (change or set for new objects) one of the classes in the "CTI" model? Is this functionality provided by SonataAdminBundle
?
I would gladly write a patch, but, of course, I really need your advice.
Hello, I can't help because I never used CTI with admin bundle. I remember using inheritance, but I think it wasn't CTI. I'd say that anything that is not documented should be considered not supported.
If you want to contribute something, there will be a need for detailed docs and tests, because this is quite complicated, as you have shown.
I think it's quite obvious that this functionality requires some discussion. If I decide to add this functionality (to write a PR), should I open a new issue, or can I put my thoughts here?
You can put your thoughts here, or you can create a PR with only docs, as you wish.
IMO this issue is almost the same as #4519 but there is a differenece on how you want to access the inheritance.
I would like to centralize all the conversation on one issue. WDYT on closing this one?
@jordisala1991 I'm not sure it's really the same. But I'm also not sure if my issue is up-to-date.
So I think it can be closed (at least for now).
Ok, ping me to reopen or reopen yourself when you find out.
AFAIK there is no more work for inheritance on Sonata since you posted your issue, so if it was not working before, it wont work now.
IMO, this is a general issue of sonata admin not being able to handle discriminator mapped fields and should either be stayed open or another issue should be created (whether it's a "bug" or "feature request" is another question), but it's most definitely something that admin would ideally support. I don't have the solutions, but it's definitely a roadblock I'm hitting at the moment.
I currently have a doctrine CTI setup (User parent with Employee and Customer subclasses and more possibly in the future) and the only reason I chose this option for my data in the first place was because if I instead had one User
entity with my own type
field (for example), then I'd need to specify admin_code
in many places in my code to avoid ambiguity because I'd have 2 or more admins pointing to one entity.
Would be super useful, it is really a roadblock....
Environment
Sonata packages
```bash $ composer show sonata-project/* sonata-project/admin-bundle 3.20.1 The missing Symfony Admin Generator sonata-project/block-bundle 3.3.2 Symfony SonataBlockBundle sonata-project/cache 1.0.7 Cache library sonata-project/core-bundle 3.4.0 Symfony SonataCoreBundle sonata-project/datagrid-bundle 2.2.1 Symfony SonataDatagridBundle sonata-project/doctrine-extensions 1.0.2 Doctrine2 behavioral extensions sonata-project/doctrine-orm-admin-bundle 3.1.5 Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle sonata-project/easy-extends-bundle 2.2.0 Symfony SonataEasyExtendsBundle sonata-project/exporter 1.7.1 Lightweight Exporter library sonata-project/media-bundle 3.5.1 Symfony SonataMediaBundle sonata-project/notification-bundle 3.1.0 Symfony SonataNotificationBundle ```Symfony packages
```bash $ composer show symfony/* symfony/assetic-bundle v2.8.1 Integrates Assetic into Symfony2 symfony/monolog-bundle v3.1.0 Symfony MonologBundle symfony/phpunit-bridge v3.3.3 Symfony PHPUnit Bridge symfony/polyfill-apcu v1.4.0 Symfony polyfill backporting apcu_* functions to lower PHP versions symfony/polyfill-intl-icu v1.4.0 Symfony polyfill for intl's ICU-related data and classes symfony/polyfill-mbstring v1.4.0 Symfony polyfill for the Mbstring extension symfony/polyfill-php56 v1.4.0 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions symfony/polyfill-php70 v1.4.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions symfony/polyfill-util v1.4.0 Symfony utilities for portability of PHP codes symfony/security-acl v3.0.0 Symfony Security Component - ACL (Access Control List) symfony/swiftmailer-bundle v2.6.2 Symfony SwiftmailerBundle symfony/symfony v3.2.10 The Symfony PHP framework ```Doctrine packages
```bash $ composer show doctrine/* doctrine/annotations v1.4.0 Docblock Annotations Parser doctrine/cache v1.6.1 Caching library offering an object-oriented API for many cache backends doctrine/collections v1.4.0 Collections Abstraction library doctrine/common v2.7.2 Common Library for Doctrine projects doctrine/data-fixtures v1.2.2 Data Fixtures for all Doctrine Object Managers doctrine/dbal v2.5.12 Database Abstraction Layer doctrine/doctrine-bundle 1.6.8 Symfony DoctrineBundle doctrine/doctrine-cache-bundle 1.3.0 Symfony Bundle for Doctrine Cache doctrine/doctrine-fixtures-bundle 2.3.0 Symfony DoctrineFixturesBundle doctrine/doctrine-migrations-bundle v1.2.1 Symfony DoctrineMigrationsBundle doctrine/inflector v1.1.0 Common String Manipulations with regard to casing and singular/plural rules. doctrine/instantiator 1.0.5 A small, lightweight utility to instantiate objects in PHP without invoking their constructors doctrine/lexer v1.0.1 Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. doctrine/migrations v1.5.0 Database Schema migrations using Doctrine DBAL doctrine/orm v2.5.6 Object-Relational-Mapper for PHP ```PHP version
```bash $ php -v PHP 7.1.6-1~ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jun 9 2017 08:26:34) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.1.6-1~ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2017, by Zend Technologies with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans ```Subject
Suppose that we need to describe at the database level and administer using
SonataAdminBundle
the following data structure.There is a document. A document can consist of several pages. The page can be written by hand, or printed on the printer. The handwritten and printed pages have very different attributes.
For this purpose, the following data structure was created.
The
Document
doctrine-entity has apages
field, which is an array ofPage
doctrine-entities.Document
is linked to thePage
by theOneToMany
relation.Document class
```php /** * @ORM\Table(name="document") * @ORM\Entity */ class Document { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var Page[] * * @ORM\OneToMany(targetEntity="Page", cascade={"persist"}, mappedBy="document", orphanRemoval=true) * @ORM\OrderBy({"name": "ASC"}) */ private $pages; } ```The
Page
doctrine-entity has the propertywayOfObtaining
, the value of which is one of the child entities of the classAbstractWayOfObtaining
(more about this below).Page
is connected to theAbstractWayOfObtaining
by theOneToOne
relation.Page class
```php /** * @ORM\Table(name="page") * @ORM\Entity */ class Page { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var AbstractWayOfObtaining * * @ORM\OneToOne(targetEntity="AbstractWayOfObtaining", cascade={"persist"}) * @ORM\JoinColumn(name="way_of_obtaining_id", referencedColumnName="id") */ private $wayOfObtaining; /** * @var Document * * @ORM\ManyToOne(targetEntity="Document", cascade={"persist"}, inversedBy="pages") * @ORM\JoinColumn(name="document_id", referencedColumnName="id", nullable=false) */ private $document; } ```The
AbstractWayOfObtaining
doctrine-entity is an abstract class used as the base class in the Doctrine ORMClass Table Inheritance
mapping.AbstractWayOfObtaining class
```php /** * @ORM\Table(name="way_of_obtaining") * @ORM\Entity * @ORM\InheritanceType("JOINED") * @ORM\DiscriminatorColumn(name="obtain_type", type="string") * @ORM\DiscriminatorMap({"handwritten" = "HandwriteWayOfObtaining", "printed" = "PrintWayOfObtaining"}) */ abstract class AbstractWayOfObtaining { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; } ```The
AbstractWayOfObtaining
class has two child doctrine-entities classes:HandwriteWayOfObtaining
andPrintWayOfObtaining
, the data for each of which are very different, therefore the entities are stored in different tables.HandwriteWayOfObtaining class
```php /** * @ORM\Table(name="handwrite_way_of_obtaining") * @ORM\Entity */ class HandwriteWayOfObtaining extends AbstractWayOfObtaining { } /** * @ORM\Table(name="print_way_of_obtaining") * @ORM\Entity */ class PrintWayOfObtaining extends AbstractWayOfObtaining { } ```This is what is.
My task is to administer this structure using
SonataAdminBundle
.For these purposes I created a service of admin class
AbstractWayOfObtainingAdmin
. Since the entities of theAbstractWayOfObtaining
are related to thePage
entity by theOneToOne
connection, I did not create a separate page for this admin class (show_in_dashboard: false
).AbstractWayOfObtainingAdmin service configuration
``` admin.abstract_way_of_obtaining: class: MyBundle\Admin\AbstractWayOfObtainingAdmin arguments: [~, MyBundle\Entity\AbstractWayOfObtaining, ~] calls: - [addSubClass, [MyBundle\Entity\HandwriteWayOfObtaining]] - [addSubClass, [MyBundle\Entity\PrintWayOfObtaining]] tags: - name: sonata.admin manager_type: orm show_in_dashboard: false ```In the admin class
AbstractWayOfObtainingAdmin
in theconfigureFormFields
method, I made sure that the fields are configured depending on which entity is actually present.AbstractWayOfObtainingAdmin class
```php class AbstractWayOfObtainingAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { $subject = $this->getSubject(); if ($subject instanceof HandwriteWayOfObtaining) { $formMapper ->add('propertyOfHandwrite', TextType::class) // adding other HandwriteWayOfObtaining fields ; } elseif ($subject instanceof PrintWayOfObtaining) { $formMapper ->add('propertyOfPrint', TextType::class) // adding other PrintWayOfObtaining fields ; } } } ```Next, I configured the admin class
PageAdmin
:PageAdmin class
```php class PageAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('wayOfObtaining', AdminType::class, array( 'data_class' => null, ), array( 'admin_code' => 'admin.abstract_way_of_obtaining', )) ; } } ```The
PageAdmin
class is not shown in the admin panel itself, it is embade toDocumentAdmin
page:DocumentAdmin class
```php class DocumentAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('pages', CollectionType::class, array( 'required' => false, ), array( 'edit' => 'inline', 'inline' => 'table', 'admin_code' => 'admin.page', )) ; } } ```My goal is to make it so that you can go into the document entity admin and edit its attributes (including pages, including obtaining way of each page).
As a result, the code shown above allows me to view the already create data. And nothing more:
1) When I try to save the form data (for example, with the
HandwriteWayOfObtaining
object), I see an error:Here is backtrace:
As you can see, there is an attempt to access the data of class
PrintWayOfObtaining
on the object of classHandwriteWayOfObtaining
.So I cannot save the form.
2) When I try to add one more page (the
link_add
button), thewayOfObtaining
section of just created page form is empty (that is, there are no fields of theHandwriteWayOfObtaining
entity, nor the fields of thePrintWayOfObtaining
entity, nor the possibility of selecting the desired entity).So I cannot add new
Page
to theDocument
usingSonataAdminBundle
.My question is: am I doing something wrong, or is this a probable bug? What should I do to be able to edit a document, pages and obtaining ways using
DocumentAdmin
?I'll gladly give you any information and write any patches, if you tell me which way to look and give some advice.