Burgov / KeyValueFormBundle

A form type for managing key-value pairs
MIT License
44 stars 32 forks source link

Implementing with Symfony, which ORM type ? #26

Open Mopster opened 7 years ago

Mopster commented 7 years ago

Which ORM Column type should I be using to save this to the database ? I tried text and simple_array, but I can't get it to work. When using text, it saves as 'Array', when using simple_array, it only saves the value of the last item in the collection.

Entity :

/**
     * Store key-value options
     * @ORM\Column(type="simple_array", name="options", nullable=true)
     */
    protected $options;

public function getOptions()
    {
        return $this->options;
    }

    public function setOptions($options)
    {
        $this->options = $this->convertToArray($options);
    }

    private function convertToArray($data)
    {
        if (is_array($data)) {
            return $data;
        }

        if ($data instanceof KeyValueContainer) {
            return $data->toArray();
        }

        if ($data instanceof \Traversable) {
            return iterator_to_array($data);
        }

        throw new \InvalidArgumentException(sprintf('Expected array, Traversable or KeyValueContainer, got "%s"', is_object($data) ? getclass($data) : get_type($data)));
    }

Form :

$builder->add('options', KeyValueType::class, [
            'required' => false,
            'value_type' => TextType::class,
            'use_container_object' => true,
        ]);
enekochan commented 6 years ago

Try object or json. I've used this approach to store an array of keys/values:

class Blablabla
{
    /**
     * @ORM\Column(type="object", nullable=true)
     */
    protected $features;

    public function getFeatures()
    {
        return $this->features;
    }

    public function setFeatures($features)
    {
        $this->features = $features;

        return $this;
    }

    public function getFeature($name)
    {
        return $this->getElement($this->features, $name);
    }

    public function setFeature($name, $value)
    {
        $this->setElement($this->features, $name, $value);

        return $this;
    }

    public function removeFeature($name)
    {
        return $this->removeElement($this->features, $name);
    }

    public function hasFeature($name)
    {
        return $this->hasProperty($this->features, $name);
    }

    protected function hasProperty($collection, $name)
    {
        return !is_null($collection) && !empty($collection) && is_array($collection) && array_key_exists($name, $collection);
    }

    protected function setElement(&$collection, $name, $value)
    {
        if (is_null($collection) || empty($collection) || !is_array($collection)) {
            $this->clearCollection($collection);
        }
        $collection[$name] = $value;

        return $collection;
    }

    protected function getElement($collection, $name)
    {
        if ($this->hasProperty($collection, $name)) {
            return $collection[$name];
        }

        return null;
    }

    protected function removeElement(&$collection, $name)
    {
        if ($this->hasProperty($collection, $name)) {
            unset($collection[$name]);

            return true;
        }

        return false;
    }

    protected function clearCollection(&$collection)
    {
        return $collection = [];
    }
}