/Nette/Forms/Controls/FormControl.php
PHP | 657 lines | 249 code | 158 blank | 250 comment | 23 complexity | c5af6dd753d914bdb32bbfde85263204 MD5 | raw file
Possible License(s): BSD-3-Clause
- <?php
- /**
- * Nette Framework
- *
- * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
- *
- * This source file is subject to the "Nette license" that is bundled
- * with this package in the file license.txt.
- *
- * For more information please see http://nettephp.com
- *
- * @copyright Copyright (c) 2004, 2009 David Grudl
- * @license http://nettephp.com/license Nette license
- * @link http://nettephp.com
- * @category Nette
- * @package Nette\Forms
- */
- /*namespace Nette\Forms;*/
- require_once dirname(__FILE__) . '/../../Component.php';
- require_once dirname(__FILE__) . '/../../Forms/IFormControl.php';
- /**
- * Base class that implements the basic functionality common to form controls.
- *
- * @author David Grudl
- * @copyright Copyright (c) 2004, 2009 David Grudl
- * @package Nette\Forms
- *
- * @property-read Form $form
- * @property-read mixed $control
- * @property-read mixed $label
- * @property-read string $htmlName
- * @property string $htmlId
- * @property-read array $options
- * @property Nette\ITranslator $translator
- * @property mixed $value
- * @property-read Nette\Web\Html $controlPrototype
- * @property-read Nette\Web\Html $labelPrototype
- * @property-read Rules $rules
- * @property-read array $errors
- * @property bool $disabled
- * @property bool $rendered
- * @property bool $required
- */
- abstract class FormControl extends /*Nette\*/Component implements IFormControl
- {
- /** @var string */
- public static $idMask = 'frm%s-%s';
- /** @var string textual caption or label */
- public $caption;
- /** @var mixed unfiltered control value */
- protected $value;
- /** @var Nette\Web\Html control element template */
- protected $control;
- /** @var Nette\Web\Html label element template */
- protected $label;
- /** @var array */
- private $errors = array();
- /** @var bool */
- private $disabled = FALSE;
- /** @var string */
- private $htmlId;
- /** @var string */
- private $htmlName;
- /** @var Rules */
- private $rules;
- /** @var Nette\ITranslator */
- private $translator = TRUE; // means autodetect
- /** @var array user options */
- private $options = array();
- /**
- * @param string caption
- */
- public function __construct($caption = NULL)
- {
- $this->monitor('Nette\Forms\Form');
- parent::__construct();
- $this->control = /*Nette\Web\*/Html::el('input');
- $this->label = /*Nette\Web\*/Html::el('label');
- $this->caption = $caption;
- $this->rules = new Rules($this);
- }
- /**
- * This method will be called when the component becomes attached to Form.
- * @param IComponent
- * @return void
- */
- protected function attached($form)
- {
- if (!$this->disabled && $form instanceof Form && $form->isAnchored() && $form->isSubmitted()) {
- $this->loadHttpData();
- }
- }
- /**
- * Overloaded parent setter. This method checks for invalid control name.
- * @param IComponentContainer
- * @param string
- * @return FormControl provides a fluent interface
- */
- public function setParent(/*Nette\*/IComponentContainer $parent = NULL, $name = NULL)
- {
- if ($name === 'submit') {
- throw new /*\*/InvalidArgumentException("Name 'submit' is not allowed due to JavaScript limitations.");
- }
- return parent::setParent($parent, $name);
- }
- /**
- * Returns form.
- * @param bool throw exception if form doesn't exist?
- * @return Form
- */
- public function getForm($need = TRUE)
- {
- return $this->lookup('Nette\Forms\Form', $need);
- }
- /**
- * Returns name of control within a Form & INamingContainer scope.
- * @return string
- */
- public function getHtmlName()
- {
- if ($this->htmlName === NULL) {
- $s = '';
- $name = $this->getName();
- $obj = $this->lookup('Nette\Forms\INamingContainer', TRUE);
- while (!($obj instanceof Form)) {
- $s = "[$name]$s";
- $name = $obj->getName();
- $obj = $obj->lookup('Nette\Forms\INamingContainer', TRUE);
- }
- $this->htmlName = "$name$s";
- }
- return $this->htmlName;
- }
- /**
- * Changes control's HTML id.
- * @param string new ID, or FALSE or NULL
- * @return FormControl provides a fluent interface
- */
- public function setHtmlId($id)
- {
- $this->htmlId = $id;
- return $this;
- }
- /**
- * Returns control's HTML id.
- * @return string
- */
- public function getHtmlId()
- {
- if ($this->htmlId === FALSE) {
- return NULL;
- } elseif ($this->htmlId === NULL) {
- $this->htmlId = sprintf(self::$idMask, $this->getForm()->getName(), $this->getHtmlName());
- $this->htmlId = str_replace(array('[', ']'), array('-', ''), $this->htmlId);
- }
- return $this->htmlId;
- }
- /**
- * Sets user-specific option.
- *
- * Common options:
- * - 'rendered' - indicate if method getControl() have been called
- * - 'required' - indicate if ':required' rule has been applied
- * - 'description' - textual or Html object description (recognized by ConventionalRenderer)
- *
- * @param string key
- * @param mixed value
- * @return FormControl provides a fluent interface
- */
- public function setOption($key, $value)
- {
- if ($value === NULL) {
- unset($this->options[$key]);
- } else {
- $this->options[$key] = $value;
- }
- return $this;
- }
- /**
- * Returns user-specific option.
- * @param string key
- * @param mixed default value
- * @return mixed
- */
- final public function getOption($key, $default = NULL)
- {
- return isset($this->options[$key]) ? $this->options[$key] : $default;
- }
- /**
- * Returns user-specific options.
- * @return array
- */
- final public function getOptions()
- {
- return $this->options;
- }
- /********************* translator ****************d*g**/
- /**
- * Sets translate adapter.
- * @param Nette\ITranslator
- * @return FormControl provides a fluent interface
- */
- public function setTranslator(/*Nette\*/ITranslator $translator = NULL)
- {
- $this->translator = $translator;
- return $this;
- }
- /**
- * Returns translate adapter.
- * @return Nette\ITranslator|NULL
- */
- final public function getTranslator()
- {
- if ($this->translator === TRUE) {
- return $this->getForm(FALSE) ? $this->getForm()->getTranslator() : NULL;
- }
- return $this->translator;
- }
- /**
- * Returns translated string.
- * @param string
- * @return string
- */
- public function translate($s)
- {
- $translator = $this->getTranslator();
- return $translator === NULL ? $s : $translator->translate($s);
- }
- /********************* interface IFormControl ****************d*g**/
- /**
- * Sets control's value.
- * @param mixed
- * @return FormControl provides a fluent interface
- */
- public function setValue($value)
- {
- $this->value = $value;
- return $this;
- }
- /**
- * Returns control's value.
- * @return mixed
- */
- public function getValue()
- {
- return $this->value;
- }
- /**
- * Sets control's default value.
- * @param mixed
- * @return FormControl provides a fluent interface
- */
- public function setDefaultValue($value)
- {
- $form = $this->getForm(FALSE);
- if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
- $this->setValue($value);
- }
- return $this;
- }
- /**
- * Loads HTTP data.
- * @return void
- */
- public function loadHttpData()
- {
- $path = strtr(str_replace(']', '', $this->getHtmlName()), '.', '_');
- $this->setValue(/*Nette\*/ArrayTools::get($this->getForm()->getHttpData(), explode('[', $path)));
- }
- /**
- * Disables or enables control.
- * @param bool
- * @return FormControl provides a fluent interface
- */
- public function setDisabled($value = TRUE)
- {
- $this->disabled = (bool) $value;
- return $this;
- }
- /**
- * Is control disabled?
- * @return bool
- */
- public function isDisabled()
- {
- return $this->disabled;
- }
- /********************* rendering ****************d*g**/
- /**
- * Generates control's HTML element.
- * @return Nette\Web\Html
- */
- public function getControl()
- {
- $this->setOption('rendered', TRUE);
- $control = clone $this->control;
- $control->name = $this->getHtmlName();
- $control->disabled = $this->disabled;
- $control->id = $this->getHtmlId();
- return $control;
- }
- /**
- * Generates label's HTML element.
- * @param string
- * @return Nette\Web\Html
- */
- public function getLabel($caption = NULL)
- {
- $label = clone $this->label;
- $label->for = $this->getHtmlId();
- if ($caption !== NULL) {
- $label->setText($this->translate($caption));
- } elseif ($this->caption instanceof /*Nette\Web\*/Html) {
- $label->add($this->caption);
- } else {
- $label->setText($this->translate($this->caption));
- }
- return $label;
- }
- /**
- * Returns control's HTML element template.
- * @return Nette\Web\Html
- */
- final public function getControlPrototype()
- {
- return $this->control;
- }
- /**
- * Returns label's HTML element template.
- * @return Nette\Web\Html
- */
- final public function getLabelPrototype()
- {
- return $this->label;
- }
- /**
- * Sets 'rendered' indicator.
- * @param bool
- * @return FormControl provides a fluent interface
- * @deprecated
- */
- public function setRendered($value = TRUE)
- {
- $this->setOption('rendered', $value);
- return $this;
- }
- /**
- * Does method getControl() have been called?
- * @return bool
- * @deprecated
- */
- public function isRendered()
- {
- return !empty($this->options['rendered']);
- }
- /********************* rules ****************d*g**/
- /**
- * Adds a validation rule.
- * @param mixed rule type
- * @param string message to display for invalid data
- * @param mixed optional rule arguments
- * @return FormControl provides a fluent interface
- */
- public function addRule($operation, $message = NULL, $arg = NULL)
- {
- $this->rules->addRule($operation, $message, $arg);
- return $this;
- }
- /**
- * Adds a validation condition a returns new branch.
- * @param mixed condition type
- * @param mixed optional condition arguments
- * @return Rules new branch
- */
- public function addCondition($operation, $value = NULL)
- {
- return $this->rules->addCondition($operation, $value);
- }
- /**
- * Adds a validation condition based on another control a returns new branch.
- * @param IFormControl form control
- * @param mixed condition type
- * @param mixed optional condition arguments
- * @return Rules new branch
- */
- public function addConditionOn(IFormControl $control, $operation, $value = NULL)
- {
- return $this->rules->addConditionOn($control, $operation, $value);
- }
- /**
- * @return Rules
- */
- final public function getRules()
- {
- return $this->rules;
- }
- /**
- * Makes control mandatory.
- * @param string error message
- * @return FormControl provides a fluent interface
- * @deprecated
- */
- final public function setRequired($message = NULL)
- {
- $this->rules->addRule(':Filled', $message);
- return $this;
- }
- /**
- * Is control mandatory?
- * @return bool
- * @deprecated
- */
- final public function isRequired()
- {
- return !empty($this->options['required']);
- }
- /**
- * New rule or condition notification callback.
- * @param Rule
- * @return void
- */
- public function notifyRule(Rule $rule)
- {
- if (is_string($rule->operation) && strcasecmp($rule->operation, ':filled') === 0) {
- $this->setOption('required', TRUE);
- }
- }
- /********************* validation ****************d*g**/
- /**
- * Equal validator: are control's value and second parameter equal?
- * @param IFormControl
- * @param mixed
- * @return bool
- */
- public static function validateEqual(IFormControl $control, $arg)
- {
- $value = (string) $control->getValue();
- foreach ((is_array($arg) ? $arg : array($arg)) as $item) {
- if ($item instanceof IFormControl) {
- if ($value === (string) $item->value) return TRUE;
- } else {
- if ($value === (string) $item) return TRUE;
- }
- }
- return FALSE;
- }
- /**
- * Filled validator: is control filled?
- * @param IFormControl
- * @return bool
- */
- public static function validateFilled(IFormControl $control)
- {
- return (string) $control->getValue() !== ''; // NULL, FALSE, '' ==> FALSE
- }
- /**
- * Valid validator: is control valid?
- * @param IFormControl
- * @return bool
- */
- public static function validateValid(IFormControl $control)
- {
- return $control->rules->validate(TRUE);
- }
- /**
- * Adds error message to the list.
- * @param string error message
- * @return void
- */
- public function addError($message)
- {
- if (!in_array($message, $this->errors, TRUE)) {
- $this->errors[] = $message;
- }
- $this->getForm()->addError($message);
- }
- /**
- * Returns errors corresponding to control.
- * @return array
- */
- public function getErrors()
- {
- return $this->errors;
- }
- /**
- * @return bool
- */
- public function hasErrors()
- {
- return (bool) $this->errors;
- }
- /**
- * @return void
- */
- public function cleanErrors()
- {
- $this->errors = array();
- }
- }