sonata-project / SonataDoctrineMongoDBAdminBundle

Symfony Sonata / Integrate Doctrine MongoDB ODM into the SonataAdminBundle
https://docs.sonata-project.org/projects/SonataDoctrineMongoDBAdminBundle
MIT License
65 stars 95 forks source link

Accessing property on embedded document via dot-notation works with filters but not list view #545

Closed webdevilopers closed 3 years ago

webdevilopers commented 3 years ago

Sonata packages

    "require": {
        "php": "^7.4",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "sonata-project/admin-bundle": "dev-master#c8fc9cc6fc0ad08a2f6fc56bfb644e72f7fe033e",
        "sonata-project/doctrine-mongodb-admin-bundle": "dev-master",
        "symfony/apache-pack": "^1.0",
        "symfony/console": "5.2.*",
        "symfony/dotenv": "5.2.*",
        "symfony/flex": "^1.3.1",
        "symfony/framework-bundle": "5.2.*",
        "symfony/yaml": "5.2.*"
    },

The SonataAdminBundle is currently being prepared for Symfony 5. As @VincentLanglet states:

The persistence bundle are not up-to-date with the latest changes from SonataAdmin.

https://github.com/sonata-project/SonataAdminBundle/pull/6476#issuecomment-800249328

That is why I use the recommended commit which worked fine for installing this bundle.

He also added:

I recommend you to fix the doctrine mongodb admin bundle commit too.

If I understood correctly there could be an equivalent commit in this bundle that should work. But I couldn't figure out how to determine that commit. Maybe one can help me with is.

I suppose that commit could then possibly fix the bug I am going to describe. If so thanks in advance.

I defined an Admin Class for a BusinessProfile document. This document has an embedded ContactInformation document.

<?php declare(strict_types=1);

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document(collection="business_profile_details", readOnly=true)
 */
class BusinessProfile
{
    /**
     * @MongoDB\EmbedOne(targetDocument=ContactInformation::class)
     */
    protected $contactInformation;

    public function contactInformation(): ContactInformation
    {
        return $this->contactInformation;
    }
}
<?php declare(strict_types=1);

namespace App\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\EmbeddedDocument()
 */
class ContactInformation
{
    /**
     * @MongoDB\Field(type="string")
     */
    protected $name;

    /**
     * @MongoDB\Field(type="collection")
     */
    protected $phoneNumber;

    /**
     * @MongoDB\Field(type="string")
     */
    protected $emailAddress;

    /**
     * @MongoDB\Field(type="collection")
     */
    protected $address;

    public function __toString()
    {
        return $this->name;
    }

    public function name()
    {
        return $this->name;
    }

    public function phoneNumber()
    {
        return $this->phoneNumber;
    }

    public function emailAddress()
    {
        return $this->emailAddress;
    }

    public function address()
    {
        return $this->address;
    }
}

As far as I understand it should be possible to get the properties of the embed document via dot-notation:

<?php declare(strict_types=1);

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Route\RouteCollectionInterface;

final class BusinessProfileAdmin extends AbstractAdmin
{
    protected function _configureDatagridFilters(DatagridMapper $datagridMapper): void
    {
        $datagridMapper
            ->add('contactInformation.name')
        ;
    }

    protected function configureListFields(ListMapper $listMapper): void
    {
        $listMapper
            ->add('contactInformation.name');

But the listView throws Cannot access property "contactInformation.name".

While the dot-notation does indeed work for the datagridFilters!

My current workaround is a custom template:

            ->add('contactInformation', 'string', [
                'template' => 'list_contactInformation.html.twig',
            ])
{% extends '@SonataAdmin/CRUD/base_list_field.html.twig' %}

{% block field%}
    {{ object.contactInformation.name }}<br>
    Telefon: {{ object.contactInformation.phoneNumber.countryCallingCode }} {{ object.contactInformation.phoneNumber.number }}<br>
    E-Mail: {{ object.contactInformation.emailAddress }}<br>
    <br>
    Adresse:<br>
    {{ object.contactInformation.address.street }}<br>
    {{ object.contactInformation.address.countryCode }}-{{ object.contactInformation.address.postalCode }} {{ object.contactInformation.address.city }}<br>
{% endblock %}

But this way I have to use a single list field for the entire embed document. I would prefer separate ones for name, emailAddress etc..

Thanks in advance.

webdevilopers commented 3 years ago

I managed to get the expected behaviour by downgrading to the following packages:


{
    "require": {
        "php": "^7.4",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "sonata-project/admin-bundle": "^3.93",
        "sonata-project/doctrine-mongodb-admin-bundle": "^3.7",
        "sonata-project/exporter": "2.4.0",
        "symfony/apache-pack": "^1.0",
        "symfony/dotenv": "4.4.*",
        "symfony/flex": "^1.12",
        "symfony/framework-bundle": "4.4.*",
        "symfony/yaml": "4.4.*"
    }
}
franmomu commented 3 years ago

Thanks for reporting! So if I had understood correctly, it works in the stable branch, but not in master, we have a test for filtering using embeddable value, I'll also add to show the value.

webdevilopers commented 3 years ago

Thanks for the fast response. That is correct!

franmomu commented 3 years ago

@webdevilopers we've just updated master branch, if you could give it a try to see if it works would be great.

webdevilopers commented 3 years ago

I can confirm that it did work in ^3.7.0 with admin-bundle ^3.93

        "sonata-project/admin-bundle": "^3.93",
        "sonata-project/doctrine-mongodb-admin-bundle": "dev-master",

Testing dev-master would require updating to admin-bundle **4.***. That update is currently not possible for me.

  Problem 1
    - Can only install one of: sonata-project/admin-bundle[4.x-dev, 3.93.0].
    - Can only install one of: sonata-project/admin-bundle[4.x-dev, 3.93.0].
    - Can only install one of: sonata-project/admin-bundle[4.x-dev, 3.94.0].
    - Can only install one of: sonata-project/admin-bundle[4.x-dev, 3.95.0].
    - Can only install one of: sonata-project/admin-bundle[4.x-dev, 3.x-dev].
    - sonata-project/doctrine-mongodb-admin-bundle dev-master requires sonata-project/admin-bundle 4.x-dev -> satisfiable by sonata-project/admin-bundle[4.x-dev].
    - Installation request for sonata-project/doctrine-mongodb-admin-bundle dev-master -> satisfiable by sonata-project/doctrine-mongodb-admin-bundle[dev-master].
    - Installation request for sonata-project/admin-bundle ^3.93 -> satisfiable by sonata-project/admin-bundle[3.93.0, 3.94.0, 3.95.0, 3.x-dev].

Hope this helps anyway?

VincentLanglet commented 3 years ago

Closing then, if it works

franmomu commented 3 years ago

The problem was using master branch, so we don't know for sure if it works, but at least the test I added works.