web-dev-qa-db-fra.com

Ajouter un ImageType dans un formulaire: "impossible de lire l'index ... n'implémente pas \ ArrayAccess"?

J'ai un petit problème avec un type personnalisé dans un champ d'un formulaire: j'essaye d'ajouter un "ImageType" lié à une entité "Image", qui a "url" et "alt" comme variables.
J'obtiens cette erreur:

Impossible de lire l'index "url" de l'objet de type "Proxies__CG __\OC\PlatformBundle\Entity\Image" car il n'implémente pas\ArrayAccess.

Voici le type:

<?php
// src/OC/PlatformBundle/Form/ImageType.php

namespace OC\PlatformBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class ImageType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
      ->add('url', TextType::class)
      ->add('alt', TextType::class)
    ;
  }

  public function setDefaultOptions(OptionsResolverInterface $resolver)
  {
    $resolver->setDefaults(array(
      'data_class' => 'OC\PlatformBundle\Entity\Image'
    ));
  }

  public function getName()
  {
    return 'oc_platformbundle_image';
  }
}

La forme:

class AdvertType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
      ->add('title', TextType::class)
      ->add('date', DateType::class)
      ->add('categories', EntityType::class, array(
            'class'    => 'OCPlatformBundle:Category',
            'choice_label' => 'name',
            'multiple' => true
          ))
      ->add('image', ImageType::class)
      ->add('save', SubmitType::class, array('label' => 'Create Task'))    ;
  }

Et l'entité:

<?php

namespace OC\PlatformBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Image
 *
 * @ORM\Table(name="image")
 * @ORM\Entity(repositoryClass="OC\PlatformBundle\Repository\ImageRepository")
 */
class Image
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="url", type="string", length=255)
     */
    private $url;

    /**
     * @var string
     *
     * @ORM\Column(name="alt", type="string", length=255)
     */
    private $alt;


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

    /**
     * Set url
     *
     * @param string $url
     *
     * @return Image
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }

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

    /**
     * Set alt
     *
     * @param string $alt
     *
     * @return Image
     */
    public function setAlt($alt)
    {
        $this->alt = $alt;

        return $this;
    }

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

Je n'ai pas de tableau dans la classe Image, donc je ne sais pas ce qui jette le problème.

22
Paul

Vous recevez cette erreur car Symfony recherche la classe de données de votre type de formulaire mais ne la trouve pas. Votre code aurait fonctionné pour les versions Symfony 2.x, où setDefaultOptions() était valide. Depuis Symfony 2.7, cette méthode était déconseillée au profit de configureOptions() et supprimée entièrement dans 3.0.

Ainsi, votre fonction existe dans votre classe de formulaire mais elle ne sera jamais référencée par Symfony. Votre barre d'outils de débogage peut même ne pas afficher cette dépréciation car elle a été entièrement supprimée dans 3.0. Les types de formulaire plus simples peuvent ne pas générer d'erreur si vous faites la même erreur, mais setDefaultOptions() ne sera jamais appelé dans les deux cas, donc je passerais en revue et vérifierais vos autres formulaires pour m'assurer qu'ils sont également valides.

Comme solution, changez ceci:

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class AdvertType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'OC\PlatformBundle\Entity\Image',
        ));
    }
}

pour ça:

use Symfony\Component\OptionsResolver\OptionsResolver;

class AdvertType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'OC\PlatformBundle\Entity\Image',
        ));
    }
}
47
Jason Roman