1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: namespace picon;
24:
25: 26: 27: 28: 29: 30: 31: 32: 33:
34: abstract class AbstractChoice extends FormComponent
35: {
36: private $choiceRenderer;
37:
38: private $choices;
39:
40: private $isDisabled;
41:
42: 43: 44: 45: 46: 47:
48: public function __construct($id, $choices, ChoiceRenderer $choiceRenderer = null, Model $model = null, $isDisabled = null)
49: {
50: parent::__construct($id, $model);
51: Args::isArray($choices, 'choices');
52:
53: $this->choices = $choices;
54:
55: if($choiceRenderer==null)
56: {
57: $choiceRenderer = new ChoiceRenderer();
58: }
59: $this->choiceRenderer = $choiceRenderer;
60:
61: if($isDisabled!=null)
62: {
63: Args::callBackArgs($isDisabled, 2, 'isDisabled');
64: $this->isDisabled = $isDisabled;
65: }
66: }
67:
68: protected function getChoiceRenderer()
69: {
70: return $this->choiceRenderer;
71: }
72:
73: protected function getChoices()
74: {
75: return $this->choices;
76: }
77:
78: public abstract function isSelected($choice, $index);
79:
80:
81: 82: 83: 84:
85: protected function renderOption($name, $value, $selected, $disabled)
86: {
87: $this->getResponse()->write('<option');
88: if($selected)
89: {
90: $this->getResponse()->write(' selected="selected"');
91: }
92: if($disabled)
93: {
94: $this->getResponse()->write(' disabled="disabled"');
95: }
96: $this->getResponse()->write(' value="'.htmlentities($value).'"');
97:
98: $this->getResponse()->write('>');
99: $this->getResponse()->write(htmlentities($name));
100: $this->getResponse()->write('</option>');
101: }
102:
103: protected function renderOptGroup($name, $options, $index)
104: {
105: $this->getResponse()->write('<optgroup');
106: $this->getResponse()->write(' label="'.htmlentities($name).'"');
107: $this->getResponse()->write('>');
108: $this->renderOptions($options, $index);
109: $this->getResponse()->write('</optgroup>');
110: }
111:
112: protected function renderOptions($choices = null, $outerIndex = 1)
113: {
114: if($choices==null)
115: {
116: $choices = $this->choices;
117: }
118: $i = 1;
119: foreach($choices as $index => $choice)
120: {
121: $actualIndex = $i * $outerIndex;
122: if(is_array($choice))
123: {
124: $this->renderOptGroup($index, $choice, $i);
125: }
126: else
127: {
128: $selected = $this->isSelected($choice, $actualIndex);
129: $disabled = $this->isDisabled($choice, $actualIndex);
130: $this->renderOption($this->choiceRenderer->getDisplay($choice, $actualIndex), $this->choiceRenderer->getValue($choice, $actualIndex), $selected, $disabled);
131: }
132: $i++;
133: }
134: }
135:
136: protected function isDisabled($choice, $index)
137: {
138: if($this->isDisabled!=null)
139: {
140: $callable = $this->isDisabled;
141: return $callable($choice, $index);
142: }
143: return false;
144: }
145:
146: protected final function valueForChoice($choice, $value, $index)
147: {
148: return $this->choiceRenderer->getValue($choice, $index)==$value;
149: }
150:
151: protected function validateModel()
152: {
153: if(count($this->choices)>0)
154: {
155:
156:
157:
158:
159:
160:
161:
162: $firstType = gettype($this->choices[0]);
163:
164:
165:
166:
167: foreach($this->choices as $choice)
168: {
169: if(is_array($choice) && !$this->supportNestedArray())
170: {
171: throw new \InvalidArgumentException('Choices array may not contain nested arrays');
172: }
173: else if(is_array($choice) && $this->supportNestedArray())
174: {
175: foreach($choice as $option)
176: {
177: if(is_array($option))
178: {
179: throw new \InvalidArgumentException('Nested choice arrays may contain nested arrays');
180: }
181: }
182: }
183:
184: 185: 186: 187:
188: }
189: }
190: }
191:
192: public function getValue()
193: {
194: $input = null;
195: if($this->disabled)
196: {
197: $input = $this->getModelObject();
198: }
199: if($this->rawInput==null)
200: {
201: if($this->emptyInput==true)
202: {
203: return null;
204: }
205: else
206: {
207: $input = $this->getModelObject();
208: }
209: }
210: else
211: {
212: $input = $this->rawInput;
213: }
214: return $input;
215: }
216:
217: protected function supportNestedArray()
218: {
219: return false;
220: }
221: }
222:
223: ?>
224: