Sonataadminbundle: No output of array value or entity property with ShowMapper

Created on 28 Sep 2017  路  12Comments  路  Source: sonata-project/SonataAdminBundle

I have data in a database row stored with doctrine as type json_array. I would output different values from this array in show view but I get null as value. The same when a embedded Entity is not registered in doctrine entity manager.

Here are some examples. I have a entity:

class MyEntity
{
    // ...
    /**
     * @ORM\Column(type="json_array")
     * @var array
     */
    private $data;
}

My test_template.html.twig:

{% extends 'SonataAdminBundle:CRUD:base_show_field.html.twig' %}

{% block field %}
    {{ dump(value) }}
{% endblock %}

In show mapper:

$showMapper->add('data', null, ['template' => 'test_template.html.twig']);

Result: Values of array data

$showMapper->add('data.name', null, ['template' => 'test_template.html.twig']);

Result: null

Next example with a entity:

class MyEntity
{
    // ...
    /**
     * @ORM\Column(type="json_array")
     * @var array
     */
    private $data;

    /**
     * Array from $data serialised to OtherEntity
     * @var OtherEntity $dataEntity
     */
    private $dataEntity;
}

In show mapper:

$showMapper->add('dataEntity', null, ['template' => 'test_template.html.twig']);

Result: Entity with values

$showMapper->add('dataEntity.name', null, ['template' => 'test_template.html.twig']);

Result: null

I wonder why I can't output a field of the array or the value of a class with configureShowFields.

$showMapper->add('data.name') // null
    ->add('otherValue') // works
    ->add('data.otherThing') // null
    ->add('nextValue'); // works

In template it works {{ dump(entity.data.otherValue) }}. But I can't use a template and output only this value I need, because I get a Exception with "Duplicate field name "data" in show mapper. Names should be unique."

Has anyone a idea?

bug pending author stale

Most helpful comment

@fadoe @greg0ire I can confirm the bug (I just tested it).

@fadoe What's your installed version of the admin-bundle?

All 12 comments

Hi, we try to keep Github issues for bug reports and feature requests only. If you have a question, please ask it on Stack Overflow or on #sonata on the symfony-devs slack.

@greg0ire This is a bug for me (until you say anything else). Thank you for your help.

Might be, it's not very clear to me yet, so let's reopen. Please post a full stack trace of the exception you get, it might help.

@fadoe @greg0ire I can confirm the bug (I just tested it).

@fadoe What's your installed version of the admin-bundle?

@jlamur Great :) Version 3.23.0

I found where the problem is and it seems that it never worked before.

The BaseFieldDescription::getFieldValue() method (which is responsible of getting the value variable injected in the twig template) does not handle the dot notation because the BaseFieldDescription::$fieldName property is set by BaseFieldDescription::setName() with this code:

public function setName($name)
{
    $this->name = $name;

    if (!$this->getFieldName()) {
        $this->setFieldName(substr(strrchr('.'.$name, '.'), 1));
    }
}

You can see here that the dot notation is discarded to keep only the part after the last dot.

Anyway, inside the BaseFieldDescription::getFieldValue() method, there is nothing to get the value of a field name with a dot notation.

Both of these methods have to be updated, but IMO it would take some time to make sure everything is BC.

@fadoe If you feel comfortable enough with the code mentioned before, could you try to write a PR?

@jlamur Thanks for your debugging. I will try to fix this.

@jlamur I tried to debug the problem. The method setName is called in the ModelManager. And there the field description needs meta data (from doctrine). But there are no meta data because the object is serialized from json how I wrote. So far I see it is not possible to output data from a class that is not managed by the doctrine orm.

I found a solution by calling 'code':

$showMapper->add('data.otherThing', null, ['template' => 'other_thing_template.html.twig', 'code' => 'data.otherThing']);

It is not documented anywhere but works at the moment for me. In the template I can use the value or the object.

@fadoe @jlamur @greg0ire I want use this but for $listMapper i try change $showMapper by $listMapper but this not work

@foji2 You are right. This only works with the show mapper.

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Was this page helpful?
0 / 5 - 0 ratings