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