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