1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
25: class FormContainer extends ComponentContainer implements ArrayAccess
26: {
27:
28: public $onValidate;
29:
30:
31: protected $currentGroup;
32:
33:
34: protected $valid;
35:
36:
37:
38:
39:
40:
41:
42: 43: 44: 45: 46: 47:
48: public function setDefaults($values, $erase = FALSE)
49: {
50: $form = $this->getForm(FALSE);
51: if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
52: $this->setValues($values, $erase);
53: }
54: return $this;
55: }
56:
57:
58:
59: 60: 61: 62: 63: 64:
65: public function setValues($values, $erase = FALSE)
66: {
67: if ($values instanceof Traversable) {
68: $values = iterator_to_array($values);
69:
70: } elseif (!is_array($values)) {
71: throw new InvalidArgumentException("First parameter must be an array, " . gettype($values) ." given.");
72: }
73:
74: $cursor = & $values;
75: $iterator = $this->getComponents(TRUE);
76: foreach ($iterator as $name => $control) {
77: $sub = $iterator->getSubIterator();
78: if (!isset($sub->cursor)) {
79: $sub->cursor = & $cursor;
80: }
81: if ($control instanceof IFormControl) {
82: if ((is_array($sub->cursor) || $sub->cursor instanceof ArrayAccess) && array_key_exists($name, $sub->cursor)) {
83: $control->setValue($sub->cursor[$name]);
84:
85: } elseif ($erase) {
86: $control->setValue(NULL);
87: }
88: }
89: if ($control instanceof FormContainer) {
90: if ((is_array($sub->cursor) || $sub->cursor instanceof ArrayAccess) && isset($sub->cursor[$name])) {
91: $cursor = & $sub->cursor[$name];
92: } else {
93: unset($cursor);
94: $cursor = NULL;
95: }
96: }
97: }
98: return $this;
99: }
100:
101:
102:
103: 104: 105: 106:
107: public function getValues()
108: {
109: $values = array();
110: $cursor = & $values;
111: $iterator = $this->getComponents(TRUE);
112: foreach ($iterator as $name => $control) {
113: $sub = $iterator->getSubIterator();
114: if (!isset($sub->cursor)) {
115: $sub->cursor = & $cursor;
116: }
117: if ($control instanceof IFormControl && !$control->isDisabled() && !($control instanceof ISubmitterControl)) {
118: $sub->cursor[$name] = $control->getValue();
119: }
120: if ($control instanceof FormContainer) {
121: $cursor = & $sub->cursor[$name];
122: $cursor = array();
123: }
124: }
125: return $values;
126: }
127:
128:
129:
130:
131:
132:
133:
134: 135: 136: 137:
138: public function isValid()
139: {
140: if ($this->valid === NULL) {
141: $this->validate();
142: }
143: return $this->valid;
144: }
145:
146:
147:
148: 149: 150: 151:
152: public function validate()
153: {
154: $this->valid = TRUE;
155: $this->onValidate($this);
156: foreach ($this->getControls() as $control) {
157: if (!$control->getRules()->validate()) {
158: $this->valid = FALSE;
159: }
160: }
161: }
162:
163:
164:
165:
166:
167:
168:
169: 170: 171: 172:
173: public function setCurrentGroup(FormGroup $group = NULL)
174: {
175: $this->currentGroup = $group;
176: return $this;
177: }
178:
179:
180:
181: 182: 183: 184:
185: public function getCurrentGroup()
186: {
187: return $this->currentGroup;
188: }
189:
190:
191:
192: 193: 194: 195: 196: 197: 198: 199:
200: public function addComponent(IComponent $component, $name, $insertBefore = NULL)
201: {
202: parent::addComponent($component, $name, $insertBefore);
203: if ($this->currentGroup !== NULL && $component instanceof IFormControl) {
204: $this->currentGroup->add($component);
205: }
206: }
207:
208:
209:
210: 211: 212: 213:
214: public function getControls()
215: {
216: return $this->getComponents(TRUE, 'IFormControl');
217: }
218:
219:
220:
221: 222: 223: 224: 225:
226: public function getForm($need = TRUE)
227: {
228: return $this->lookup('Form', $need);
229: }
230:
231:
232:
233:
234:
235:
236:
237: 238: 239: 240: 241: 242: 243: 244:
245: public function addText($name, $label = NULL, $cols = NULL, $maxLength = NULL)
246: {
247: return $this[$name] = new TextInput($label, $cols, $maxLength);
248: }
249:
250:
251:
252: 253: 254: 255: 256: 257: 258: 259:
260: public function addPassword($name, $label = NULL, $cols = NULL, $maxLength = NULL)
261: {
262: $control = new TextInput($label, $cols, $maxLength);
263: $control->setType('password');
264: return $this[$name] = $control;
265: }
266:
267:
268:
269: 270: 271: 272: 273: 274: 275: 276:
277: public function addTextArea($name, $label = NULL, $cols = 40, $rows = 10)
278: {
279: return $this[$name] = new TextArea($label, $cols, $rows);
280: }
281:
282:
283:
284: 285: 286: 287: 288: 289:
290: public function addFile($name, $label = NULL)
291: {
292: return $this[$name] = new FileUpload($label);
293: }
294:
295:
296:
297: 298: 299: 300: 301: 302:
303: public function addHidden($name, $default = NULL)
304: {
305: $control = new HiddenField;
306: $control->setDefaultValue($default);
307: return $this[$name] = $control;
308: }
309:
310:
311:
312: 313: 314: 315: 316: 317:
318: public function addCheckbox($name, $caption = NULL)
319: {
320: return $this[$name] = new Checkbox($caption);
321: }
322:
323:
324:
325: 326: 327: 328: 329: 330: 331:
332: public function addRadioList($name, $label = NULL, array $items = NULL)
333: {
334: return $this[$name] = new RadioList($label, $items);
335: }
336:
337:
338:
339: 340: 341: 342: 343: 344: 345: 346:
347: public function addSelect($name, $label = NULL, array $items = NULL, $size = NULL)
348: {
349: return $this[$name] = new SelectBox($label, $items, $size);
350: }
351:
352:
353:
354: 355: 356: 357: 358: 359: 360: 361:
362: public function addMultiSelect($name, $label = NULL, array $items = NULL, $size = NULL)
363: {
364: return $this[$name] = new MultiSelectBox($label, $items, $size);
365: }
366:
367:
368:
369: 370: 371: 372: 373: 374:
375: public function addSubmit($name, $caption = NULL)
376: {
377: return $this[$name] = new SubmitButton($caption);
378: }
379:
380:
381:
382: 383: 384: 385: 386: 387:
388: public function addButton($name, $caption)
389: {
390: return $this[$name] = new Button($caption);
391: }
392:
393:
394:
395: 396: 397: 398: 399: 400: 401:
402: public function addImage($name, $src = NULL, $alt = NULL)
403: {
404: return $this[$name] = new ImageButton($src, $alt);
405: }
406:
407:
408:
409: 410: 411: 412: 413:
414: public function addContainer($name)
415: {
416: $control = new FormContainer;
417: $control->currentGroup = $this->currentGroup;
418: return $this[$name] = $control;
419: }
420:
421:
422:
423:
424:
425:
426:
427: 428: 429: 430: 431: 432:
433: final public function offsetSet($name, $component)
434: {
435: $this->addComponent($component, $name);
436: }
437:
438:
439:
440: 441: 442: 443: 444: 445:
446: final public function offsetGet($name)
447: {
448: return $this->getComponent($name, TRUE);
449: }
450:
451:
452:
453: 454: 455: 456: 457:
458: final public function offsetExists($name)
459: {
460: return $this->getComponent($name, FALSE) !== NULL;
461: }
462:
463:
464:
465: 466: 467: 468: 469:
470: final public function offsetUnset($name)
471: {
472: $component = $this->getComponent($name, FALSE);
473: if ($component !== NULL) {
474: $this->removeComponent($component);
475: }
476: }
477:
478:
479:
480: 481: 482:
483: final public function __clone()
484: {
485: throw new NotImplementedException('Form cloning is not supported yet.');
486: }
487:
488: }
489: