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

ModelAutocompleteType not working with AbstractAdminExtension #7194

Closed JustDylan23 closed 3 years ago

JustDylan23 commented 3 years ago

I am currently using the Alpha 2 version but this issue was present long before that.

RuntimeException:
The field "owner" does not exist.

  at vendor/sonata-project/admin-bundle/src/Action/RetrieveAutocompleteItemsAction.php:218
  at Sonata\AdminBundle\Action\RetrieveAutocompleteItemsAction->retrieveFormFieldDescription(object(SongAdmin), 'owner')
     (vendor/sonata-project/admin-bundle/src/Action/RetrieveAutocompleteItemsAction.php:74)
  at Sonata\AdminBundle\Action\RetrieveAutocompleteItemsAction->__invoke(object(Request))
     (vendor/symfony/http-kernel/HttpKernel.php:157)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:79)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:195)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public_html/index.php:20) 

The autocompletion works fine as long as I use it in an admin directly. You can easily reproduce this by creating a class that extends AbstractAdminExtension and simply adding a field of the type ModelAutocompleteType:class to the configureFormFields method like this:

public function configureFormFields(FormMapper $formMapper): void
{
    $formMapper
        ->add('owner', ModelAutocompleteType::class, [
            'property' => 'username'
        ])
    ;
}
JustDylan23 commented 3 years ago

It can't retrieve the parent field description for some reason, which results in a 500 error.

JustDylan23 commented 3 years ago

I found out that only the field description of the fields that were initially on the admin are avaiable to the extension

VincentLanglet commented 3 years ago

https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Action/RetrieveAutocompleteItemsAction.php#L217

Call https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Admin/AbstractAdmin.php#L1212

Which call https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Admin/AbstractAdmin.php#L2433

Which call https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Admin/AbstractAdmin.php#L892

Which does https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Admin/AbstractAdmin.php#L910-L916

Which is supposed to call https://github.com/sonata-project/SonataAdminBundle/blob/23df35c1b6b943e290d7f5fef185f32ed81a59ac/src/Form/FormMapper.php#L158

You could try to debug these calls to see which one is not made.

JustDylan23 commented 3 years ago
public function add($name, ?string $type = null, array $options = [], array $fieldDescripti
{
    if ($name === 'owner') throw new \Error('owner');

I have confirmed that the owner field is in fact not being added and also confirmed in the foreach that the extension is in fact being iterated through

JustDylan23 commented 3 years ago
public function configureFormFields(FormMapper $formMapper): void
{
    if (!$this->security->isGranted('ROLE_SUPER_ADMIN')) {
        throw new \Error('insufficient permissions');
        return;
    }

    $isNewEntity = $formMapper->getAdmin()->getSubject()->getId() === null;

    if ($isNewEntity) {
        throw new \Error('new entity');
    }

    if ($isNewEntity || $formMapper->getAdmin()->hasParentFieldDescription()) {
        throw new \Error('no parent description');
        return;
    }

    $formMapper
        ->tab('Metadata')
        ->with('Source')
        ->add('owner', ModelAutocompleteType::class, [
            'property' => 'username',
        ])
        ->end()
        ->end()
    ;
}

I did some debugging and apparently the variable named $isNewEntity is set to true, this would indicate that for some reason it is not able to retrieve the subject.

JustDylan23 commented 3 years ago

I replaced the getSubject check with $formMapper->getAdmin()->isCurrentRoute('create') now it does what it needs to do.