json_array attribute empty while persisting in DB

0

Good Galeri.

I have a curious problem when using DoctrineFixturesBundle. I have an Application class of type Entity Class that maps to the system table. In this class there is an attribute called options which is of type json_array mapped to the sistema opções column and I initialize it as a ArrayCollection . Options is logically encoded so that each element of this collection is an Object (OptionAttribute Entity). I did this because I needed to have a Form that had the ability to add / remove / edit each element of this collection, and then created the Entity OptionAttribute that is not mapped to the Database. I created the FormType for both Application and OptionAttribute and everything worked to the satisfaction.

Now I have created Fixtures for the Application Entity and the system column options are only with '{}', that is, empty. There is no execution error, just the collection of OptionAttribute entities is not persisting.

Follow the classes

The class of fixtures for Application

class ApplicationFixtures extends Fixture
{
    public function load(ObjectManager $oManager)
    {
        $types = ['TextType', 'TextareaType', 'EmailType', 'IntegerType', 'MoneyType',
            'NumberType', 'UrlType', 'TelType', 'DateType', 'DateTimeType', 'TimeType', 'PercentType',
            'SearchType', 'BirthdayType', 'CheckboxType', 'FileType'];
        $appsAlias = [1 => 'Facebook', 'Twitter', 'Instagram', 'Tumbler', 'Tinder'];
        foreach ($appsAlias as $k => $app) {
            /* @var $application Application */
            $application = new Application();
            $application->setName('Application Number ' . $k)
                ->setIsActive(true)
                ->setAlias($app);

            $rand_keys = array_rand($types, 5);

            foreach ($rand_keys as $typesKey) {
                $optionAttribute = new OptionAttribute();
                $optionAttribute->setName('Option ' . str_replace('Type', '', $types[$typesKey]))
                    ->setDefaultValue('Default Value for Option ' . $typesKey)
                    ->setRequired(($typesKey % 2 == 1))
                    ->setType($types[$typesKey]);

                $application->addOption($optionAttribute);
            }

            $oManager->persist($application);
        }
        $oManager->flush();
    }

}

Application Entity

/**
 * @ORM\Table(name="sistema")
 * @ORM\Entity
 */
class Application
{

    // Several attributes...

    /**
     * @var ArrayCollection|OptionAttribute[]
     * @ORM\Column(name="sistema_opcoes", type="json_array", length=255, nullable=true)
     */
    private $options;

    public function __construct() {
        // ...
        $this->options = new ArrayCollection();
    }

    // Several getters and setters for ordinary fields
    /**
     * @return ArrayCollection
     */
    public function getOptions()
    {
        $options = new ArrayCollection();
        foreach($this->options as $k => $value) {
            /* @var $option OptionAttribute */
            $option = new OptionAttribute();
            $option->unserialize($value);
            $options->add($option);
        }
        return $options;
    }

    /**
     * @param ArrayCollection $options
     * @return Application
     */
    public function setOptions(ArrayCollection $options)
    {
        foreach ($options as $option) {
            $this->addOption($option);
        }
        return $this;
    }

    /**
     * @param OptionAttribute $option
     * @return $this
     */
    public function addOption(OptionAttribute $option)
    {
        $this->options->add($option->serialize());
        return $this;
    }

}

And the OptionAttribute Entity

class OptionAttribute implements \Serializable
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $defaultvalue;

    /**
     * @var string
     */
    private $type;

    /**
     * @var boolean
     */
    private $required = false;

    // Getters and Setters

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->name,
            $this->defaultvalue,
            $this->type,
            $this->required,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->name,
            $this->defaultvalue,
            $this->type,
            $this->required,
            ) = unserialize($serialized);
    }
}

Where am I going wrong?

    
asked by anonymous 20.04.2018 / 02:11

1 answer

0

For those who have the same problem.

I realized that the ArrayCollection conversion to json_array did not work as I expected, so I changed the code so that the attribute was filled only with the type array in the attribute in question and everything worked as expected.

I did not need to change the getOptions method.

Follow the changes

/**
 * @ORM\Table(name="sistema")
 * @ORM\Entity
 */
class Application
{

    // Several attributes...

    /**
     * @var array
     * @ORM\Column(name="sistema_opcoes", type="json_array", length=255, nullable=true)
     */
    private $options;

    public function __construct() {
        // ...
        $this->options = [];
    }

    // Several getters and setters for ordinary fields

    /**
     * @param ArrayCollection $options
     * @return Application
     */
    public function setOptions(ArrayCollection $options)
    {
        $this->options = [];
        foreach ($options as $option) {
            $this->addOption($option);
        }
        return $this;
    }

    /**
     * @param OptionAttribute $option
     * @return $this
     */
    public function addOption(OptionAttribute $option)
    {
        $options = $this->getOptions();
        if ($options->contains($option)) {
            return;
        }
        $this->options[]= ($option->serialize());
        return $this;
    }

}

From this point I was able to use the Fixture class normally.

    
27.04.2018 / 23:38