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