1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Forms\Controls;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17: 18:
19: abstract class MultiChoiceControl extends BaseControl
20: {
21: 22: 23: 24:
25: public $checkAllowedValues = true;
26:
27:
28: private $items = [];
29:
30:
31: public function __construct($label = null, array $items = null)
32: {
33: parent::__construct($label);
34: if ($items !== null) {
35: $this->setItems($items);
36: }
37: }
38:
39:
40: 41: 42: 43:
44: public function loadHttpData()
45: {
46: $this->value = array_keys(array_flip($this->getHttpData(Nette\Forms\Form::DATA_TEXT)));
47: if (is_array($this->disabled)) {
48: $this->value = array_diff($this->value, array_keys($this->disabled));
49: }
50: }
51:
52:
53: 54: 55: 56: 57: 58:
59: public function setValue($values)
60: {
61: if (is_scalar($values) || $values === null) {
62: $values = (array) $values;
63: } elseif (!is_array($values)) {
64: throw new Nette\InvalidArgumentException(sprintf("Value must be array or null, %s given in field '%s'.", gettype($values), $this->name));
65: }
66: $flip = [];
67: foreach ($values as $value) {
68: if (!is_scalar($value) && !method_exists($value, '__toString')) {
69: throw new Nette\InvalidArgumentException(sprintf("Values must be scalar, %s given in field '%s'.", gettype($value), $this->name));
70: }
71: $flip[(string) $value] = true;
72: }
73: $values = array_keys($flip);
74: if ($this->checkAllowedValues && ($diff = array_diff($values, array_keys($this->items)))) {
75: $set = Nette\Utils\Strings::truncate(implode(', ', array_map(function ($s) { return var_export($s, true); }, array_keys($this->items))), 70, '...');
76: $vals = (count($diff) > 1 ? 's' : '') . " '" . implode("', '", $diff) . "'";
77: throw new Nette\InvalidArgumentException("Value$vals are out of allowed set [$set] in field '{$this->name}'.");
78: }
79: $this->value = $values;
80: return $this;
81: }
82:
83:
84: 85: 86: 87:
88: public function getValue()
89: {
90: return array_values(array_intersect($this->value, array_keys($this->items)));
91: }
92:
93:
94: 95: 96: 97:
98: public function getRawValue()
99: {
100: return $this->value;
101: }
102:
103:
104: 105: 106: 107:
108: public function isFilled()
109: {
110: return $this->getValue() !== [];
111: }
112:
113:
114: 115: 116: 117: 118: 119:
120: public function setItems(array $items, $useKeys = true)
121: {
122: $this->items = $useKeys ? $items : array_combine($items, $items);
123: return $this;
124: }
125:
126:
127: 128: 129: 130:
131: public function getItems()
132: {
133: return $this->items;
134: }
135:
136:
137: 138: 139: 140:
141: public function getSelectedItems()
142: {
143: return array_intersect_key($this->items, array_flip($this->value));
144: }
145:
146:
147: 148: 149: 150: 151:
152: public function setDisabled($value = true)
153: {
154: if (!is_array($value)) {
155: return parent::setDisabled($value);
156: }
157:
158: parent::setDisabled(false);
159: $this->disabled = array_fill_keys($value, true);
160: $this->value = array_diff($this->value, $value);
161: return $this;
162: }
163:
164:
165: 166: 167: 168:
169: public function getHtmlName()
170: {
171: return parent::getHtmlName() . '[]';
172: }
173:
174:
175: 176: 177:
178: public function checkDefaultValue($value = true)
179: {
180: $this->checkAllowedValues = $value;
181: return $this;
182: }
183: }
184: