How to get child object in embedded Admin class in Sonata Admin?

sonata-admin, symfony

Solution

Thanks to Tautrimas for some ideas, but I managed to figure out an answer to this:

In ImageAdmin set this:

protected function configureFormFields(FormMapper $formMapper)
{
    if($this->hasParentFieldDescription()) { // this Admin is embedded
        $getter = 'get' . $this->getParentFieldDescription()->getFieldName();
        $parent = $this->getParentFieldDescription()->getAdmin()->getSubject();
        if ($parent) {
          $image = $parent->$getter();
        } else {
          $image = null;
        }
    } else { // this Admin is not embedded
        $image = $this->getSubject();
    }

    // You can then do things with the $image, like show a thumbnail in the help:
    $fileFieldOptions = array('required' => false);
    if ($image && ($webPath = $image->getWebPath())) {
        $fileFieldOptions['help'] = '<img src="'.$webPath.'" class="admin-preview" />';
    }

    $formMapper
        ->add('file', 'file', $fileFieldOptions)
    ;
}

I'll post this in the upcoming SonataAdmin cookbook soon!

https://github.com/sonata-project/SonataAdminBundle/issues/1546

Problem

I'm trying to get and manipulate the actual object related to a ImageAdmin class in SonataAdmin (using Symfony 2.3). This works fine when the ImageAdmin class is the only one being used. But when ImageAdmin is embedded in another Admin it goes horribly wrong. Here's what works when you don't have embedded Admins: ``` class ImageAdmin extends Admin { protected $baseRoutePattern = 'image'; protected function configureFormFields(FormMapper $formMapper) { $subject = $this->getSubject(); } } ``` But when you embed ImageAdmin in ParentAdmin using this: ``` class PageAdmin extends Admin { protected function configureFormFields(FormMapper $formMapper) { $formMapper->add('image1', 'sonata_type_admin'); } } ``` Then when you're editing a Parent item with id 10 and call getSubject() in ImageAdmin you get the Image with id 10! In other words getSubject() extracts the id from the URL then calls `$this->getModelManager()->find($this->getClass(), $id);`, which cross-references the Parent id and the Image id. Oops! So... what I want to do is be able to get hold of the actual object that is being rendered/edited in the current ImageAdmin instance, whether it's being edited directly or via an embedded form, and then be able to do things with it. Maybe getSubject() is the wrong tree to be barking up, but I note that `$this->getCurrentChild()` returns false when called from ImageAdmin::configureFormFields(), even when that ImageAdmin is embedded using the sonata_type_admin field type. I'm quite confused... Anyway, I hope it is possible to get hold of the object in some obvious way that I've overlooked and somebody here can help enlighten me!

Original source