1<?php
2
3
4namespace ComboStrap;
5
6
7/**
8 * @package ComboStrap
9 * An array, ie list of value metadata
10 *   * Multiple select if the possible values are set
11 *   * Text with a {@link  MetadataMultiple::getStringSeparator() separator}
12 * Ie:
13 *   * keyword1, keyword2
14 *   * usage1, usage2, ...
15 *
16 * By default, the data type is text, if number, the implementation should overwrite the {@link MetadataMultiple::getDataType()}
17 */
18abstract class MetadataMultiple extends Metadata
19{
20
21    /**
22     * @var array|null
23     */
24    protected $array;
25
26
27    /**
28     * @param null|array $value
29     * @return Metadata
30     * @throws ExceptionCombo
31     */
32    public function setValue($value): Metadata
33    {
34        if ($value === null) {
35            $this->array = $value;
36            return $this;
37        }
38        if (!is_array($value)) {
39            throw new ExceptionCombo("The value is not an array. Value: " . var_export($value, true));
40        }
41        $this->array = $value;
42        return $this;
43    }
44
45    public function getDataType(): string
46    {
47        return DataType::TEXT_TYPE_VALUE;
48    }
49
50    public function getValue(): ?array
51    {
52        $this->buildCheck();
53        return $this->array;
54    }
55
56    public function getDefaultValue()
57    {
58        return null;
59    }
60
61    public function getValueOrDefaults(): array
62    {
63        $value = $this->getValue();
64        if ($value !== null) {
65            return $value;
66        }
67        return $this->getDefaultValue();
68    }
69
70
71    public function valueIsNotNull(): bool
72    {
73        return $this->array !== null;
74    }
75
76    public function toStoreValue()
77    {
78        $this->buildCheck();
79        if ($this->array === null) {
80            return null;
81        }
82        return implode($this->getStringSeparator(), $this->array);
83    }
84
85    public function toStoreDefaultValue()
86    {
87        if ($this->getDefaultValue() === null) {
88            return null;
89        }
90        return implode($this->getStringSeparator(), $this->getDefaultValue());
91    }
92
93
94    /**
95     * @return string - the separator used when we receive or store/send an element
96     */
97    function getStringSeparator(): string
98    {
99        return ",";
100    }
101
102    /**
103     * @throws ExceptionCombo
104     */
105    public function setFromStoreValue($value): Metadata
106    {
107        $values = $this->toArrayOrNull($value);
108        $possibleValues = $this->getPossibleValues();
109        if ($possibleValues !== null) {
110            foreach ($values as $value) {
111                if (!in_array($value, $possibleValues)) {
112                    throw new ExceptionCombo("The value ($value) for ($this) is not a possible value (" . implode(",", $possibleValues) . ")", $this->getCanonical());
113                }
114            }
115        }
116        $this->array = $values;
117        return $this;
118    }
119
120    /**
121     * @throws ExceptionCombo
122     */
123    protected function toArrayOrNull($value): ?array
124    {
125        if ($value === null || $value === "") {
126            return null;
127        }
128
129        /**
130         * Array
131         */
132        if (is_array($value)) {
133            return $value;
134        }
135
136        /**
137         * String
138         */
139        if (!is_string($value)) {
140            LogUtility::msg("The value for $this is not an array, nor a string (value: $value)");
141        }
142        $stringSeparator = $this->getStringSeparator();
143        if ($stringSeparator === null) {
144            LogUtility::msg("This array value is a string but has no separator defined. Value: $value");
145        }
146        return explode($stringSeparator, $value);
147
148    }
149
150
151    public function buildFromStoreValue($value): Metadata
152    {
153        try {
154            $this->array = $this->toArrayOrNull($value);
155        } catch (ExceptionCombo $e) {
156            LogUtility::msg($e->getMessage(), $e->getCanonical());
157        }
158        return $this;
159
160    }
161}
162