sonata-project / SonataAdminBundle

The missing Symfony Admin Generator
https://docs.sonata-project.org/projects/SonataAdminBundle
MIT License
2.11k stars 1.26k forks source link

List view crashes dev-master #2967

Closed mrjingles closed 9 years ago

mrjingles commented 9 years ago

Some of my list views crash with the following error:

[2015-05-05 09:56:15] request.CRITICAL: Uncaught PHP Exception Twig_Error_Runtime: "An exception has been thrown during the rendering of a template ("Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Foo\Bundle\BarBundle\Entity\BarTranslation' does not have a method '_action'") in "SonataAdminBundle:CRUD:base_list_inner_row.html.twig" at line 18." at /var/www/app/cache/dev_mobile/classes.php line 4791 {"exception":"[object](Twig_Error_Runtime%28code: 0%29: An exception has been thrown during the rendering of a template %28"Warning: call_user_func_array%28%29 expects parameter 1 to be a valid callback, class) in \"SonataAdminBundle:CRUD:base_list_inner_row.html.twig\" at line 18. at /var/www/app/cache/dev_mobile/classes.php:4791, Symfony\Component\Debug\Exception\ContextErrorException(code: 0): Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Foo\Bundle\BarBundle\Entity\BarTranslation' does not have a method '_action' at /var/www/vendor/knplabs/doctrine-behaviors/src/Model/Translatable/TranslatableMethods.php:144)"} []

I am using sonata with the following setup:

"sonata-project/core-bundle": "dev-master",
"sonata-project/doctrine-orm-admin-bundle": "dev-master",
"sonata-project/admin-bundle": "dev-master",
"sonata-project/datagrid-bundle": "dev-master",
"sonata-project/easy-extends-bundle": "dev-master",
"sonata-project/classification-bundle": "dev-master",
"sonata-project/user-bundle": "dev-master",
"sonata-project/media-bundle": "dev-master",
"sonata-project/news-bundle": "dev-master",

and

"knplabs/doctrine-behaviors": "~1.0",

for translation.

If I remove the "_action" section in configureListFields() the problems seems to be resolved:

->add('_action', 'actions', [
    'actions' => [
        'edit' => [],
        'delete' => [],
    ]
])
soullivaneuh commented 9 years ago

Are your sonata dependencies up to date?

Can you please provide the result of composer info -i | grep sonata?

mrjingles commented 9 years ago

Yes of course.

This is the state when everything works fine:

sonata-project/admin-bundle              dev-master dceaa26 Symfony SonataAdminBundle
sonata-project/block-bundle              2.3.0              Symfony SonataBlockBundle
sonata-project/cache                     1.0.5              Cache library
sonata-project/classification-bundle     dev-master aa8c7e0 Symfony SonataClassificationBundle
sonata-project/core-bundle               dev-master e2ccc45 Symfony SonataCoreBundle
sonata-project/datagrid-bundle           dev-master 270ea21 Symfony SonataDatagridBundle
sonata-project/doctrine-extensions       1.0.2              Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle dev-master 802a70b Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       dev-master a29ed7c Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.3.4              Lightweight Exporter library
sonata-project/formatter-bundle          2.3.3              Symfony SonataFormatterBundle
sonata-project/google-authenticator      1.0.2              Library to integrate Google Authenticator into a PHP project
sonata-project/intl-bundle               2.2.1              Symfony SonataIntlBundle
sonata-project/media-bundle              dev-master f969bfa Symfony SonataMediaBundle
sonata-project/news-bundle               dev-master 960137d Symfony SonataNewsBundle
sonata-project/notification-bundle       2.3.0              Symfony SonataNotificationBundle
sonata-project/user-bundle               dev-master 1cbbd16 Symfony SonataUserBundle

This is when the error above comes up:

sonata-project/admin-bundle              dev-master 31f1aba Symfony SonataAdminBundle
sonata-project/block-bundle              2.3.0              Symfony SonataBlockBundle
sonata-project/cache                     1.0.5              Cache library
sonata-project/classification-bundle     dev-master f6d6faf Symfony SonataClassificationBundle
sonata-project/core-bundle               dev-master ba31927 Symfony SonataCoreBundle
sonata-project/datagrid-bundle           dev-master 270ea21 Symfony SonataDatagridBundle
sonata-project/doctrine-extensions       1.0.2              Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle dev-master e114b10 Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle       dev-master a29ed7c Symfony SonataEasyExtendsBundle
sonata-project/exporter                  1.3.4              Lightweight Exporter library
sonata-project/formatter-bundle          2.3.3              Symfony SonataFormatterBundle
sonata-project/google-authenticator      1.0.2              Library to integrate Google Authenticator into a PHP project
sonata-project/intl-bundle               2.2.1              Symfony SonataIntlBundle
sonata-project/media-bundle              dev-master 3a5fb70 Symfony SonataMediaBundle
sonata-project/news-bundle               dev-master 39723dc Symfony SonataNewsBundle
sonata-project/notification-bundle       2.3.0              Symfony SonataNotificationBundle
sonata-project/user-bundle               dev-master eccfe2d Symfony SonataUserBundle
soullivaneuh commented 9 years ago

You said "Some of my list views". Which one? Can I get full Admin configuration (class and service) of this one?

Can't reproduce it.

@rande any idea?

mrjingles commented 9 years ago

After searching for differences between the admin configurations that work and that who will not I found the problem. It crashes on entities containing a magic __call() method like this:

/**
     * Proxy translated fields.
     *
     * @param string $method
     * @param array $arguments
     * @return string
     */
    public function __call($method, $arguments)
    {
        return $this->proxyCurrentLocaleTranslation($method, $arguments);
    }

If I remove that method, it works. Seem to a problem with something like is_callable in verifying if a list element is an entity attribute.

See https://github.com/KnpLabs/DoctrineBehaviors#proxy-translations understanding what that method is for.

Thanks for your time and help.

soullivaneuh commented 9 years ago

The __call method is on your entity class?

soullivaneuh commented 9 years ago

I have difficulties to reproduce it.

Can you provide the following information?

Thanks.

mrjingles commented 9 years ago

Actually I cannot find the full stacktrace in log files. If I remove the __call() method everything works as expected (what I did now).

Entity:

<?php

namespace Foo\Bundle\BarBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;

/**
 * Level.
 *
 * @ORM\Table("foo_bar_level")
 * @ORM\Entity(repositoryClass="Foo\Bundle\BarBundle\Entity\LevelRepository")
 */
class Level
{
    /**
     * @see https://github.com/KnpLabs/DoctrineBehaviors#translatable
     */
    use ORMBehaviors\Translatable\Translatable;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="xp", type="integer", length=7)
     */
    private $xp;

    /**
     * Get id.
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set xp requirement.
     *
     * @param integer $xp
     * @return Level
     */
    public function setXp($xp)
    {
        $this->xp = $xp;
        return $this;
    }

    /**
     * Get xp requirement.
     *
     * @return integer
     */
    public function getXp()
    {
        return $this->xp;
    }

    /**
     * Get the name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->translate()->getName();
    }

    /**
     * Get the description.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->translate()->getDescription();
    }

    /**
     * Get localized slug.
     *
     * @return string
     */
    public function getSlug()
    {
        return $this->translate()->getSlug();
    }

    /**
     * Proxy translated fields.
     *
     * @param string $method
     * @param array $arguments
     * @return string
     */
    public function __call($method, $arguments)
    {
        return $this->proxyCurrentLocaleTranslation($method, $arguments);
    }

    /**
     * String representation.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->getName();
    }
}

Admin:

<?php
namespace Foo\Bundle\BarBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class LevelAdmin extends Admin
{
    /**
     * Default Datagrid values
     *
     * @var array
     */
    protected $datagridValues = [
        '_sort_order' => 'ASC',
        '_sort_by' => 'xp' // name of the ordered field
    ];

    /**
     * Fields to be shown on create/edit forms
     *
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('translations', 'a2lix_translations', [
                'fields' => [
                    'slug' => ['display' => false],
                ]
            ])
            ->add('xp')
        ;
    }

    //Fields to be shown on filter forms
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('xp')
        ;
    }

    //Fields to be shown on lists
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name', null, ['route' => ['name' => 'show']])
            ->add('slug')
            ->add('xp')
            ->add('_action', 'actions', [
                'actions' => [
                    'edit' => [],
                    'delete' => [],
                ]
            ])
        ;
    }

    protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
            ->add('id')
            ->add('name')
            ->add('description')
            ->add('slug')
            ->add('xp')
        ;
    }
}

Config:

<service id="foo_bar.admin.level" class="Foo\Bundle\BarBundle\Admin\LevelAdmin">
            <argument />
            <argument>Foo\Bundle\BarBundle\Entity\Level</argument>
            <argument />
            <call method="setTranslationDomain">
                <argument>FooBarBundle</argument>
            </call>
            <tag name="sonata.admin" manager_type="orm" group="bar" label="level" />
        </service>
soullivaneuh commented 9 years ago

Thanks. So bad for stack trace, could be helpful.

Still investigate, can't figure out your issue for the moment.

Maybe @rande or another official contributors will better understand. :-)

soullivaneuh commented 9 years ago

Maybe caused by commit https://github.com/sonata-project/SonataAdminBundle/commit/418d8b3bc39b3535527b25f917fd6e7b61ece787 introduced by @EmmanuelVella.

@mrjingles Can you test with parent version https://github.com/sonata-project/SonataAdminBundle/commit/61c2b522816fb2e42dde9cd2fefba22fb61f34f8 version and then with https://github.com/sonata-project/SonataAdminBundle/commit/418d8b3bc39b3535527b25f917fd6e7b61ece787 to see if it's make difference?

soullivaneuh commented 9 years ago

Related PR: #2830

EmmanuelVella commented 9 years ago

This should have been fixed by https://github.com/sonata-project/SonataAdminBundle/pull/2931

soullivaneuh commented 9 years ago

@EmmanuelVella Weird, @mrjingles seems to use the latest version of sonata-admin.

EmmanuelVella commented 9 years ago

Ok, PR https://github.com/sonata-project/SonataAdminBundle/pull/2931 was incorrect : it's "actions" and not "action". This explains the issue !

soullivaneuh commented 9 years ago

@EmmanuelVella indeed, didn't see that. Are you planning a PR to fix it? If no time, I can manage to do it too.

EmmanuelVella commented 9 years ago

@Soullivaneuh Done https://github.com/sonata-project/SonataAdminBundle/pull/2975

mrjingles commented 9 years ago

@Soullivaneuh @EmmanuelVella Thx a lot for your quick help!

lemoinem commented 9 years ago

Sorry to have missed that...

ghost commented 7 years ago

Hi,

I have the exact same problem in my project. I'm doing some tests with the A2lix-Demo project (https://github.com/a2lix/Demo) and added Sonata Admin & Sonata ORM Admin Bundles. A2lix project works but when adding Sonata Admin, clicking on list button in backend cause this issue:

An exception has been thrown during the rendering of a template ("Neither the property "_action" nor one of the methods "getAction()", "action()", "isAction()", "hasAction()", "__get()" exist and have public access in class "A2lix\DemoTranslationBundle\Entity\ProductTranslation".").

Remove _call function in entity class solves the problem but I can' use this function anymore...

Did you find a workaround or a _call function that works?

Composer.json:

}, "require": { "php": ">=5.5.9", "symfony/symfony": "3.1.*", "doctrine/orm": "^2.5", "doctrine/doctrine-bundle": "^1.6", "doctrine/doctrine-cache-bundle": "^1.2", "symfony/monolog-bundle": "^2.8", "symfony/polyfill-apcu": "^1.0", "sensio/distribution-bundle": "^5.0", "sensio/framework-extra-bundle": "^3.0.2", "incenteev/composer-parameter-handler": "^2.0", "knplabs/doctrine-behaviors": "@stable", "a2lix/i18n-doctrine-bundle": "@stable", "a2lix/auto-form-bundle": "0.x@dev", "a2lix/translation-form-bundle": "3.x@dev", "sonata-project/admin-bundle": "^3.23", "sonata-project/doctrine-orm-admin-bundle": "^3.1" }, "require-dev": { "sensio/generator-bundle": "^3.0", "symfony/phpunit-bridge": "^3.0", "friendsofphp/php-cs-fixer": "@dev" },

Thanks.

comur commented 5 years ago

Hi, If someone has the same problem (I just had it) the following code will throw the same exception:

           ->add('_action', null, [
                'actions' => [
                    'show' => [],
                    'edit' => [],
                    'delete' => [],
                ],
            ]);

To fix, you need to specify "actions" as type (by default with make it will create as null):

            ->add('_action', 'actions', [
                'actions' => [
                    'show' => [],
                    'edit' => [],
                    'delete' => [],
                ],
            ]);
benrcole commented 3 years ago

This issue just caught me, the example here: https://symfony.com/doc/4.x/bundles/SonataAdminBundle/reference/action_list.html#customizing-the-fields-displayed-on-the-list-page needs an updated