简体   繁体   中英

How to show array in a list field of Sonata

I have a CRUD created with SonataAdminBundle, everything works fine except when listing the existing profiles, they contain a "roles" field, which is composed of several roles and in the entity is defined as an array. Well, when you try to render the data obtained from the database, it throws an error where it indicates that it can not be converted from "array" to "string", the error is exactly the following:

An exception has been thrown during the rendering of a template ("Notice: Array to string conversion").

I have this configureListFields :

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper
        ->add('id', 'integer',
            array(
                'label' =>  'ID'
            )
        )
        ->addIdentifier('name', 'string',
            array(
                'label' =>  'Name'
            )
        )
        ->add('slug', 'string',
            array(
                'label' =>  'Slug'
            )
        )
        ->add('roles', 'array',
            array(
                'label' =>  'Roles'
            )
        )
    ;
}

The entity "Profile":

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

 /**
  * @var string
  *
  * @Gedmo\Versioned()
  * @ORM\Column(name="name", type="string", length=100)
  * @Gedmo\Translatable
  */
 private $name;

 /**
  * @var string
  *
  * @Gedmo\Versioned()
  * @ORM\Column(name="slug", type="string", length=120, unique=true)
  */
 private $slug;

 /**
  * @var array
  *
  * @Gedmo\Versioned()
  * @ORM\Column(name="roles", type="array")
  */
 private $roles;

 /**
  * @Gedmo\Locale
  */
 private $locale;

 public function setTranslatableLocale($locale)
 {
     $this->locale = $locale;
 }

 /**
  * Constructor
  */
 public function __construct()
 {
     $this->roles = array();
 }

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

 /**
  * Set name
  *
  * @param string $name
  *
  * @return Profile
  */
 public function setName($name)
 {
     $this->name = $name;
     $this->slug = Tools::getSlug($name);

     return $this;
 }

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

 /**
  * Set slug
  *
  * @param string $slug
  *
  * @return Profile
  */
 public function setSlug($slug)
 {
     $this->slug = $slug;

     return $this;
 }

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

 /**
  * @param $role
  * @return $this
  */
 public function addRole($role)
 {
     if (!$this->hasRole($role)) {
         $this->roles[] = strtoupper($role);
     }
     return $this;
 }

 /**
  * Remove role
  *
  * @param array $role
  */
 public function removeRole($role)
 {
     $this->roles->removeElement($role);
 }

 /**
  * @return array|Array
  */
 public function getRoles()
 {
     return $this->roles;
 }

 /**
  * @param $role
  * @return bool
  */
 public function hasRole($role)
 {
     return in_array(strtoupper($role), $this->roles, true);
 }

 public function __toString()
 {
     return $this->name;
 }
}

And when I load the list in the browser, it shows me the error mentioned above.

I tried this too, and the result is the same:

->add('roles', 'collection',
            array(
                'label' =>  'Roles'
            )
        )

What should I do to show a String in the list and render the template correctly?

NOTE: If within the configureListFields () method, I remove the "roles" field, everything works normally.

You can create a custom. If the list field is not working with the type array (though it should... if ugly), you might do better to add a method to the Profile to convert to a nicer string:

public function getRolesAsString()
{
    return implode(',', $this->roles);
}

Then in listMapper:

->add('rolesAsString', 'string', ['label' =>  'Roles'])

EDIT: Misread, you meant list fields... this for the form - see above for lists

You can use choice type with multiple allowed:

$roles = [
    'ROLE_ADMIN' => 'Admin',
    'ROLE_USER'  => 'User',
    'ROLE_GOD'   => 'Hallelujah',
];

$formMapper
    ->add('roles', 'choice', [
        'choices'  => $roles,
        'expanded' => false,
        'multiple' => true,
    ])
;

I think by default this stores a serialized array string and transforms it back for the form.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM