alterphp / EasyAdminMongoOdmBundle

Provides support of Doctrine ODM documents in EasyAdmin
MIT License
5 stars 0 forks source link

Can't use AdminController if no ORM Entities configured #1

Open you-ser opened 6 years ago

you-ser commented 6 years ago

Hi, i try to install this bundle on empty project and got some errors. I have created and configured a few documents, but i haven't any ORM Entity in my project. My packages config:

#packages/easy_admin.yaml
easy_admin:
    design:
        menu:
        - { label: History, route: easyadmin_mongo_odm, params: { document: History } }
        - { label: Video, route: easyadmin_mongo_odm, params: { document: Video } }
        - { label: Article, route: easyadmin_mongo_odm, params: { document: Article } }

#packages/easy_admin_mongo_odm.yaml
easy_admin_mongo_odm:
    documents:
        - App\Document\History
        - App\Document\Video
        - App\Document\Article

And default routing config for EasyAdmin:

#routes/easy_admin.yaml
easy_admin_bundle:
    resource: '@EasyAdminBundle/Controller/AdminController.php'
    prefix: /admin
    type: annotation

At this step i got first error from vendor/easycorp/easyadmin-bundle/src/Controller/AdminController.php line 96: The backend is empty because you haven't configured any Doctrine entity to manage.

After that i try to change controller parameter in my routes:

#routes/easy_admin.yaml
easy_admin_bundle:
    resource: '@EasyAdminMongoOdmBundle/Controller/AdminController.php'
    prefix: /admin
    type: annotation

At this step i got next two errors: 1) Undefined class constant 'TO_MANY' at vendor/alterphp/easyadmin-mongo-odm-bundle/src/Configuration/MetadataConfigPass.php line 87: Possible solution: replace & ClassMetadata::TO_MANY to && ClassMetadata::REFERENCE_MANY constant at that line (FQCN Doctrine\ODM\MongoDB\Mapping\ClassMetadata)?

2) If manually fix the first error i got the second one: Attempted to call an undefined method named "redirectToBackendHomepage" of class "AlterPHP\EasyAdminMongoOdmBundle\Controller\AdminController". from vendor/alterphp/easyadmin-mongo-odm-bundle/src/Controller/AdminController.php line 38 Possible solution: class AlterPHP\EasyAdminMongoOdmBundle\Controller\AdminController should extend EasyCorp\Bundle\EasyAdminBundle\Controller or that method must be implemented with some redirect?

Package versions:

doctrine/mongodb - 1.6.3
doctrine/mongodb-odm - 1.2.5
doctrine/mongodb-odm-bundle - 3.4.4
easycorp/easyadmin-bundle - v1.17.14   
alterphp/easyadmin-extension-bundle - v1.2.10
alterphp/easyadmin-mongo-odm-bundle - dev-master d89751a

Will be glad to any advice, thanks.

alterphp commented 6 years ago

Hi @you-ser !

Thanks for this first issue report !

I've fixed the constant for associations REFERENCE_MANY instead of TO_MANY. And I also made AdminController extends the one from EasyAdmin.

Can test this modifications and tell me ?

Thanks,

you-ser commented 6 years ago

Hi, i got your last commit and have next situation. 1) Extending Controller from EasyAdmin is not needed, because it's break logic from method parent::initialize which we can't use for the reason described in the first post. Instead of this we can extend default symfony controller and just replace undefined method to redirect

// easyadmin-mongo-odm-bundle/src/Controller/AdminController.php

//return $this->redirectToBackendHomepage();
return $this->redirectToRoute('easyadmin');

at this point we separate orm / odm controllers, and keep default easyadmin functionalities.

To fix situation with only ODM documents and no ORM entities we need to make few things: 1) Mark one of documents as homepage menu (add default: true parameter):

#packages/easy_admin.yaml
easy_admin:
    design:
        menu:
        - { label: History, route: easyadmin_mongo_odm, params: { document: History }, default: true }

2) Create some tricky controller to prevent exception from first post and use it in easyadmin routes:

// alterphp/easyadmin-mongo-odm-bundle/src/Controller/OdmAdminController.php
<?php

namespace AlterPHP\EasyAdminMongoOdmBundle\Controller;

use EasyCorp\Bundle\EasyAdminBundle\Controller\AdminController as BaseAdminController;
use Symfony\Component\HttpFoundation\Request;
use EasyCorp\Bundle\EasyAdminBundle\Exception\NoEntitiesConfiguredException;
use AlterPHP\EasyAdminMongoOdmBundle\Exception\NoDocumentsConfiguredException;

class OdmAdminController extends BaseAdminController
{
    /**
     * Try to check if we have only ODM documents configured
     * and prevent exception if any
     *
     * @param Request $request
     */
    protected function initialize(Request $request)
    {
        try {
            parent::initialize($request);
        } catch (NoEntitiesConfiguredException $e) {
            $mongoOdmConfig = $this->get('easyadmin_mongo_odm.config.manager')->getBackendConfig();

            if (0 === count($mongoOdmConfig['documents'])) {
                throw new NoDocumentsConfiguredException();
            }
        }
    }
}

routes:

#routes/easy_admin.yaml
easy_admin_bundle:
    resource: '@EasyAdminMongoOdmBundle/Controller/OdmAdminController.php'
    prefix: /admin
    type: annotation
  1. Add routes from EasyAdminMongoOdmBundle with another prefix to avoid /admin/ path duplication at indexAction (added /admin/odm prefix)
    #routes/easy_admin_mongo_odm.yaml
    easy_admin_mongo_odm_bundle:
    resource: '@EasyAdminMongoOdmBundle/Controller/AdminController.php'
    prefix: /admin/odm
    type: annotation

Now its work good with only ODM documents, and we can add ORM entities without any problems.

In addition to this we steel have two errors need to be fixed: 1) File alterphp/easyadmin-mongo-odm-bundle/src/Configuration/MetadataConfigPass.php line 87

if ($associationMetadata['type'] & ClassMetadata::REFERENCE_MANY) {

should be replaced to double &&

if ($associationMetadata['type'] && ClassMetadata::REFERENCE_MANY) {

because of Warning: A non-numeric value encountered

2) File /var/www/symfony.loc/vendor/alterphp/easyadmin-mongo-odm-bundle/src/Twig/EasyAdminMongoOdmTwigExtension.php lines 214 - 224

       if ('image' === $fieldType) {
            $parameters = $this->addImageFieldParameters($parameters);
        }

        if ('file' === $fieldType) {
            $parameters = $this->addFileFieldParameters($parameters);
        }

        if ('association' === $fieldType) {
            $parameters = $this->addAssociationFieldParameters($parameters);
        }

should be removed (because of UndefinedMethodException) or commented as well as methods if not supported yet.

alterphp commented 6 years ago

I don't understand something : do you prefer extending base EasyAdmin AdminController or not ? Because you say it's not needed and breaking something and then you put code relying on parent...

About MetadataConfigPass, it's a no-sense to put a && operator with a constant on a side... It's a bit mask operator to check if your relation's type has REFERENCE_MANY characteristic... Please dump the value of $associationMetadata['type'] in your case (I have no example with relations).

I've commented the calls of undefined methods in the Twig extension.

you-ser commented 6 years ago

Hi, i prefer to not extend base EasyAdmin AdminController and replace undefined method redirectToBackendHomepage with redirect to 'easyadmin' route.

About MetadataConfigPass: I have document with ReferenceOne relation

/**
 * @MongoDB\Document
 */
class History
{
    ...

    /**
     * @MongoDB\ReferenceOne(targetDocument="Article")
     */
    protected $url;

so in the associations mapping i have:

//$associationMetadata
array:31 [▼
  "fieldName" => "url"
  "type" => "one"
  "reference" => true
   ...
]

that's why i have the Warning: A non-numeric value encountered.

it looks like that line should be replaced with

if ($associationMetadata['type'] & ClassMetadata::MANY) {

(if we have string association type) instead of using ClassMetadata::REFERENCE_MANY

alterphp commented 6 years ago

Ok, I need to think a bit more about the need to extend Base AdminController or not.

For the ClassMetadata error, I will correct with an equal operator, & is a non sense for strings.

thanks