A
A
Alexander Evgenievich2015-10-28 16:30:40
symfony
Alexander Evgenievich, 2015-10-28 16:30:40

How to use choices in forms with ArrayCollection but not with Entity but with regular class?

Hello.
There is a collection of Skills objects (it contains both getters and setters), which are formed from a YML file.
There is my field type (SET) in the User entity:

/**
     * @ORM\Column(type="skills", nullable=true)
     * @var ArrayCollection
     */
    private $skills;

Tried like this:
//@UserType
            ->add('skills', 'collection', array(
                'type' => 'choice',
                'options' => array(
                    'choice_list' => new ObjectChoiceList(
                        $this->skillManager->getAllSkills()->toArray(),
                        'name',
                        array(),
                        null,
                        'alias'
                    ),
                    'multiple' => true
                )
            ));

Doesn't write values ​​to the skills field in the entity when I pass an array (skills : ["skill_alias1", "skill_alias2"] ...). Just an empty collection. I add the 'allow_add' => true parameter to the " collection " field , then the collection is stuffed with empty values ​​(although it should work with objects of the Skill class). When I just change to choice:
//@UserType
            ->add('skills', 'choice', array(
                'choice_list' => new ObjectChoiceList(
                    $this->skillManager->getAllSkills()->toArray(),
                    'name',
                    array(),
                    null,
                    'alias'
                ),
                'multiple' => true
            ));

, instead of collection, it throws an error: Unable to transform value for property path "skills": Expected an array.
---------------------------------
Quite the mind went beyond the mind. ArrayCollection is a Doctrine class, so the form component does not know how to work with it, but works with the standard array() . As I understand it, now I just need to write my own DataTransformer for this field and that's it?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Evgenievich, 2015-10-28
@banderos120

In short, I quickly made this miracle:

class ChoicesCollectionToArrayTransformer implements DataTransformerInterface
{

    private $choiceList;

    public function __construct(ChoiceListInterface $choiceList)
    {
        $this->choiceList = $choiceList;
    }

    public function transform($collection)
    {
        if (null === $collection) {
            return array();
        }

        if (is_array($collection)) {
            return $collection;
        }

        if (!$collection instanceof Collection) {
            throw new TransformationFailedException('Expected a Doctrine\Common\Collections\Collection object.');
        }

        return $this->choiceList->getValuesForChoices($collection->toArray());
    }

    public function reverseTransform($array)
    {
        if ('' === $array || null === $array) {
            $array = array();
        } else {
            $array = (array) $array;
        }

        $choices = $this->choiceList->getChoicesForValues($array);

        if (count($choices) !== count($array)) {
            throw new TransformationFailedException('Could not find all matching choices for the given values');
        }

        return new ArrayCollection($choices);
    }
}

And used in UserType:
$skillsChoiceList = new ObjectChoiceList(
            $this->skillManager->getAllSkills()->toArray(),
            'name',
            array(),
            null,
            'alias'
        );

$builder ->add('skills', 'choice', array(
                'choice_list' => $skillsChoiceList,
                'multiple' => true
            ));

$builder->get('skills')->resetViewTransformers()->addViewTransformer(new ChoicesCollectionToArrayTransformer($skillsChoiceList));

Works.

D
Denis, 2015-10-28
@prototype_denis

@ORM\Column(type="skills", nullable=true)
(type="skills", nullable=true)
type="skills"
O_o

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question