Packages

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • NFormControl

Exceptions

  • ArgumentOutOfRangeException
  • DeprecatedException
  • DirectoryNotFoundException
  • FatalErrorException
  • FileNotFoundException
  • InvalidStateException
  • IOException
  • MemberAccessException
  • NotImplementedException
  • NotSupportedException

Functions

  • callback
  • dump
  • Overview
  • Package
  • Class
  • Tree
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Forms
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * Base class that implements the basic functionality common to form controls.
 17:  *
 18:  * @author     David Grudl
 19:  *
 20:  * @property-read NForm $form
 21:  * @property-read mixed $control
 22:  * @property-read mixed $label
 23:  * @property-read string $htmlName
 24:  * @property   string $htmlId
 25:  * @property-read array $options
 26:  * @property   ITranslator $translator
 27:  * @property   mixed $value
 28:  * @property-read NHtml $controlPrototype
 29:  * @property-read NHtml $labelPrototype
 30:  * @property-read NRules $rules
 31:  * @property-read array $errors
 32:  * @property   bool $disabled
 33:  * @property   bool $rendered
 34:  * @property   bool $required
 35: */
 36: abstract class NFormControl extends NComponent implements IFormControl
 37: {
 38:     /** @var string */
 39:     public static $idMask = 'frm%s-%s';
 40: 
 41:     /** @var string textual caption or label */
 42:     public $caption;
 43: 
 44:     /** @var mixed unfiltered control value */
 45:     protected $value;
 46: 
 47:     /** @var NHtml  control element template */
 48:     protected $control;
 49: 
 50:     /** @var NHtml  label element template */
 51:     protected $label;
 52: 
 53:     /** @var array */
 54:     private $errors = array();
 55: 
 56:     /** @var bool */
 57:     private $disabled = FALSE;
 58: 
 59:     /** @var string */
 60:     private $htmlId;
 61: 
 62:     /** @var string */
 63:     private $htmlName;
 64: 
 65:     /** @var NRules */
 66:     private $rules;
 67: 
 68:     /** @var ITranslator */
 69:     private $translator = TRUE; // means autodetect
 70: 
 71:     /** @var array user options */
 72:     private $options = array();
 73: 
 74: 
 75: 
 76:     /**
 77:      * @param  string  caption
 78:      */
 79:     public function __construct($caption = NULL)
 80:     {
 81:         $this->monitor('NForm');
 82:         parent::__construct();
 83:         $this->control = NHtml::el('input');
 84:         $this->label = NHtml::el('label');
 85:         $this->caption = $caption;
 86:         $this->rules = new NRules($this);
 87:     }
 88: 
 89: 
 90: 
 91:     /**
 92:      * This method will be called when the component becomes attached to Form.
 93:      * @param  IComponent
 94:      * @return void
 95:      */
 96:     protected function attached($form)
 97:     {
 98:         if (!$this->disabled && $form instanceof NForm && $form->isAnchored() && $form->isSubmitted()) {
 99:             $this->htmlName = NULL;
100:             $this->loadHttpData();
101:         }
102:     }
103: 
104: 
105: 
106:     /**
107:      * Returns form.
108:      * @param  bool   throw exception if form doesn't exist?
109:      * @return NForm
110:      */
111:     public function getForm($need = TRUE)
112:     {
113:         return $this->lookup('NForm', $need);
114:     }
115: 
116: 
117: 
118:     /**
119:      * Returns name of control within a Form & INamingContainer scope.
120:      * @return string
121:      */
122:     public function getHtmlName()
123:     {
124:         if ($this->htmlName === NULL) {
125:             $s = '';
126:             $name = $this->getName();
127:             $obj = $this->lookup('INamingContainer', TRUE);
128:             while (!($obj instanceof NForm)) {
129:                 $s = "[$name]$s";
130:                 $name = $obj->getName();
131:                 $obj = $obj->lookup('INamingContainer', TRUE);
132:             }
133:             $name .= $s;
134:             if ($name === 'submit') {
135:                 throw new InvalidArgumentException("Form control name 'submit' is not allowed due to JavaScript limitations.");
136:             }
137:             $this->htmlName = $name;
138:         }
139:         return $this->htmlName;
140:     }
141: 
142: 
143: 
144:     /**
145:      * Changes control's HTML id.
146:      * @param  string new ID, or FALSE or NULL
147:      * @return NFormControl  provides a fluent interface
148:      */
149:     public function setHtmlId($id)
150:     {
151:         $this->htmlId = $id;
152:         return $this;
153:     }
154: 
155: 
156: 
157:     /**
158:      * Returns control's HTML id.
159:      * @return string
160:      */
161:     public function getHtmlId()
162:     {
163:         if ($this->htmlId === FALSE) {
164:             return NULL;
165: 
166:         } elseif ($this->htmlId === NULL) {
167:             $this->htmlId = sprintf(self::$idMask, $this->getForm()->getName(), $this->getHtmlName());
168:             $this->htmlId = str_replace(array('[]', '[', ']'), array('', '-', ''), $this->htmlId);
169:         }
170:         return $this->htmlId;
171:     }
172: 
173: 
174: 
175:     /**
176:      * Sets user-specific option.
177:      * Common options:
178:      * - 'rendered' - indicate if method getControl() have been called
179:      * - 'required' - indicate if ':required' rule has been applied
180:      * - 'description' - textual or Html object description (recognized by ConventionalRenderer)
181:      * @param  string key
182:      * @param  mixed  value
183:      * @return NFormControl  provides a fluent interface
184:      */
185:     public function setOption($key, $value)
186:     {
187:         if ($value === NULL) {
188:             unset($this->options[$key]);
189: 
190:         } else {
191:             $this->options[$key] = $value;
192:         }
193:         return $this;
194:     }
195: 
196: 
197: 
198:     /**
199:      * Returns user-specific option.
200:      * @param  string key
201:      * @param  mixed  default value
202:      * @return mixed
203:      */
204:     final public function getOption($key, $default = NULL)
205:     {
206:         return isset($this->options[$key]) ? $this->options[$key] : $default;
207:     }
208: 
209: 
210: 
211:     /**
212:      * Returns user-specific options.
213:      * @return array
214:      */
215:     final public function getOptions()
216:     {
217:         return $this->options;
218:     }
219: 
220: 
221: 
222:     /********************* translator ****************d*g**/
223: 
224: 
225: 
226:     /**
227:      * Sets translate adapter.
228:      * @param  ITranslator
229:      * @return NFormControl  provides a fluent interface
230:      */
231:     public function setTranslator(ITranslator $translator = NULL)
232:     {
233:         $this->translator = $translator;
234:         return $this;
235:     }
236: 
237: 
238: 
239:     /**
240:      * Returns translate adapter.
241:      * @return ITranslator|NULL
242:      */
243:     final public function getTranslator()
244:     {
245:         if ($this->translator === TRUE) {
246:             return $this->getForm(FALSE) ? $this->getForm()->getTranslator() : NULL;
247:         }
248:         return $this->translator;
249:     }
250: 
251: 
252: 
253:     /**
254:      * Returns translated string.
255:      * @param  string
256:      * @param  int      plural count
257:      * @return string
258:      */
259:     public function translate($s, $count = NULL)
260:     {
261:         $translator = $this->getTranslator();
262:         return $translator === NULL || $s == NULL ? $s : $translator->translate($s, $count); // intentionally ==
263:     }
264: 
265: 
266: 
267:     /********************* interface IFormControl ****************d*g**/
268: 
269: 
270: 
271:     /**
272:      * Sets control's value.
273:      * @param  mixed
274:      * @return NFormControl  provides a fluent interface
275:      */
276:     public function setValue($value)
277:     {
278:         $this->value = $value;
279:         return $this;
280:     }
281: 
282: 
283: 
284:     /**
285:      * Returns control's value.
286:      * @return mixed
287:      */
288:     public function getValue()
289:     {
290:         return $this->value;
291:     }
292: 
293: 
294: 
295:     /**
296:      * Sets control's default value.
297:      * @param  mixed
298:      * @return NFormControl  provides a fluent interface
299:      */
300:     public function setDefaultValue($value)
301:     {
302:         $form = $this->getForm(FALSE);
303:         if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
304:             $this->setValue($value);
305:         }
306:         return $this;
307:     }
308: 
309: 
310: 
311:     /**
312:      * Loads HTTP data.
313:      * @return void
314:      */
315:     public function loadHttpData()
316:     {
317:         $path = explode('[', strtr(str_replace(array('[]', ']'), '', $this->getHtmlName()), '.', '_'));
318:         $this->setValue(NArrayTools::get($this->getForm()->getHttpData(), $path));
319:     }
320: 
321: 
322: 
323:     /**
324:      * Disables or enables control.
325:      * @param  bool
326:      * @return NFormControl  provides a fluent interface
327:      */
328:     public function setDisabled($value = TRUE)
329:     {
330:         $this->disabled = (bool) $value;
331:         return $this;
332:     }
333: 
334: 
335: 
336:     /**
337:      * Is control disabled?
338:      * @return bool
339:      */
340:     public function isDisabled()
341:     {
342:         return $this->disabled;
343:     }
344: 
345: 
346: 
347:     /********************* rendering ****************d*g**/
348: 
349: 
350: 
351:     /**
352:      * Generates control's HTML element.
353:      * @return NHtml
354:      */
355:     public function getControl()
356:     {
357:         $this->setOption('rendered', TRUE);
358:         $control = clone $this->control;
359:         $control->name = $this->getHtmlName();
360:         $control->disabled = $this->disabled;
361:         $control->id = $this->getHtmlId();
362:         return $control;
363:     }
364: 
365: 
366: 
367:     /**
368:      * Generates label's HTML element.
369:      * @param  string
370:      * @return NHtml
371:      */
372:     public function getLabel($caption = NULL)
373:     {
374:         $label = clone $this->label;
375:         $label->for = $this->getHtmlId();
376:         if ($caption !== NULL) {
377:             $label->setText($this->translate($caption));
378: 
379:         } elseif ($this->caption instanceof NHtml) {
380:             $label->add($this->caption);
381: 
382:         } else {
383:             $label->setText($this->translate($this->caption));
384:         }
385:         return $label;
386:     }
387: 
388: 
389: 
390:     /**
391:      * Returns control's HTML element template.
392:      * @return NHtml
393:      */
394:     final public function getControlPrototype()
395:     {
396:         return $this->control;
397:     }
398: 
399: 
400: 
401:     /**
402:      * Returns label's HTML element template.
403:      * @return NHtml
404:      */
405:     final public function getLabelPrototype()
406:     {
407:         return $this->label;
408:     }
409: 
410: 
411: 
412:     /**
413:      * Sets 'rendered' indicator.
414:      * @param  bool
415:      * @return NFormControl  provides a fluent interface
416:      * @deprecated
417:      */
418:     public function setRendered($value = TRUE)
419:     {
420:         $this->setOption('rendered', $value);
421:         return $this;
422:     }
423: 
424: 
425: 
426:     /**
427:      * Does method getControl() have been called?
428:      * @return bool
429:      * @deprecated
430:      */
431:     public function isRendered()
432:     {
433:         return !empty($this->options['rendered']);
434:     }
435: 
436: 
437: 
438:     /********************* rules ****************d*g**/
439: 
440: 
441: 
442:     /**
443:      * Adds a validation rule.
444:      * @param  mixed      rule type
445:      * @param  string     message to display for invalid data
446:      * @param  mixed      optional rule arguments
447:      * @return NFormControl  provides a fluent interface
448:      */
449:     public function addRule($operation, $message = NULL, $arg = NULL)
450:     {
451:         $this->rules->addRule($operation, $message, $arg);
452:         return $this;
453:     }
454: 
455: 
456: 
457:     /**
458:      * Adds a validation condition a returns new branch.
459:      * @param  mixed     condition type
460:      * @param  mixed      optional condition arguments
461:      * @return NRules      new branch
462:      */
463:     public function addCondition($operation, $value = NULL)
464:     {
465:         return $this->rules->addCondition($operation, $value);
466:     }
467: 
468: 
469: 
470:     /**
471:      * Adds a validation condition based on another control a returns new branch.
472:      * @param  IFormControl form control
473:      * @param  mixed      condition type
474:      * @param  mixed      optional condition arguments
475:      * @return NRules      new branch
476:      */
477:     public function addConditionOn(IFormControl $control, $operation, $value = NULL)
478:     {
479:         return $this->rules->addConditionOn($control, $operation, $value);
480:     }
481: 
482: 
483: 
484:     /**
485:      * @return NRules
486:      */
487:     final public function getRules()
488:     {
489:         return $this->rules;
490:     }
491: 
492: 
493: 
494:     /**
495:      * Makes control mandatory.
496:      * @param  string  error message
497:      * @return NFormControl  provides a fluent interface
498:      * @deprecated
499:      */
500:     final public function setRequired($message = NULL)
501:     {
502:         $this->rules->addRule(NForm::FILLED, $message);
503:         return $this;
504:     }
505: 
506: 
507: 
508:     /**
509:      * Is control mandatory?
510:      * @return bool
511:      * @deprecated
512:      */
513:     final public function isRequired()
514:     {
515:         return !empty($this->options['required']);
516:     }
517: 
518: 
519: 
520:     /**
521:      * New rule or condition notification callback.
522:      * @param  NRule
523:      * @return void
524:      */
525:     public function notifyRule(NRule $rule)
526:     {
527:         if (is_string($rule->operation) && strcasecmp($rule->operation, ':filled') === 0) {
528:             $this->setOption('required', TRUE);
529:         }
530:     }
531: 
532: 
533: 
534:     /********************* validation ****************d*g**/
535: 
536: 
537: 
538:     /**
539:      * Equal validator: are control's value and second parameter equal?
540:      * @param  IFormControl
541:      * @param  mixed
542:      * @return bool
543:      */
544:     public static function validateEqual(IFormControl $control, $arg)
545:     {
546:         $value = $control->getValue();
547:         foreach ((is_array($value) ? $value : array($value)) as $val) {
548:             foreach ((is_array($arg) ? $arg : array($arg)) as $item) {
549:                 if ((string) $val === (string) ($item instanceof IFormControl ? $item->value : $item)) {
550:                     return TRUE;
551:                 }
552:             }
553:         }
554:         return FALSE;
555:     }
556: 
557: 
558: 
559:     /**
560:      * Filled validator: is control filled?
561:      * @param  IFormControl
562:      * @return bool
563:      */
564:     public static function validateFilled(IFormControl $control)
565:     {
566:         return (string) $control->getValue() !== ''; // NULL, FALSE, '' ==> FALSE
567:     }
568: 
569: 
570: 
571:     /**
572:      * Valid validator: is control valid?
573:      * @param  IFormControl
574:      * @return bool
575:      */
576:     public static function validateValid(IFormControl $control)
577:     {
578:         return $control->rules->validate(TRUE);
579:     }
580: 
581: 
582: 
583:     /**
584:      * Adds error message to the list.
585:      * @param  string  error message
586:      * @return void
587:      */
588:     public function addError($message)
589:     {
590:         if (!in_array($message, $this->errors, TRUE)) {
591:             $this->errors[] = $message;
592:         }
593:         $this->getForm()->addError($message);
594:     }
595: 
596: 
597: 
598:     /**
599:      * Returns errors corresponding to control.
600:      * @return array
601:      */
602:     public function getErrors()
603:     {
604:         return $this->errors;
605:     }
606: 
607: 
608: 
609:     /**
610:      * @return bool
611:      */
612:     public function hasErrors()
613:     {
614:         return (bool) $this->errors;
615:     }
616: 
617: 
618: 
619:     /**
620:      * @return void
621:      */
622:     public function cleanErrors()
623:     {
624:         $this->errors = array();
625:     }
626: 
627: }
628: 
Nette Framework 0.9.7 (for PHP 5.2) API documentation generated by ApiGen 2.3.0