PageRenderTime 55ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/Nette/Forms/FormContainer.php

https://github.com/DocX/nette
PHP | 490 lines | 184 code | 110 blank | 196 comment | 24 complexity | 7cfa5d6c337a38317b2a02749e90c683 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Nette Framework
  4. *
  5. * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
  6. *
  7. * This source file is subject to the "Nette license" that is bundled
  8. * with this package in the file license.txt.
  9. *
  10. * For more information please see http://nettephp.com
  11. *
  12. * @copyright Copyright (c) 2004, 2009 David Grudl
  13. * @license http://nettephp.com/license Nette license
  14. * @link http://nettephp.com
  15. * @category Nette
  16. * @package Nette\Forms
  17. */
  18. /*namespace Nette\Forms;*/
  19. require_once dirname(__FILE__) . '/../ComponentContainer.php';
  20. require_once dirname(__FILE__) . '/../Forms/INamingContainer.php';
  21. /**
  22. * Container for form controls.
  23. *
  24. * @author David Grudl
  25. * @copyright Copyright (c) 2004, 2009 David Grudl
  26. * @package Nette\Forms
  27. *
  28. * @property-read \ArrayIterator $controls
  29. * @property-read Form $form
  30. * @property-read bool $valid
  31. * @property array $values
  32. */
  33. class FormContainer extends /*Nette\*/ComponentContainer implements /*\*/ArrayAccess, INamingContainer
  34. {
  35. /** @var FormGroup */
  36. protected $currentGroup;
  37. /** @var bool */
  38. protected $valid;
  39. /********************* data exchange ****************d*g**/
  40. /**
  41. * Fill-in with default values.
  42. * @param array|Traversable values used to fill the form
  43. * @param bool erase other default values?
  44. * @return FormContainer provides a fluent interface
  45. */
  46. public function setDefaults($values, $erase = FALSE)
  47. {
  48. $form = $this->getForm(FALSE);
  49. if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
  50. $this->setValues($values, $erase);
  51. }
  52. return $this;
  53. }
  54. /**
  55. * Fill-in with values.
  56. * @param array|Traversable values used to fill the form
  57. * @param bool erase other controls?
  58. * @return FormContainer provides a fluent interface
  59. */
  60. public function setValues($values, $erase = FALSE)
  61. {
  62. if ($values instanceof /*\*/Traversable) {
  63. $values = iterator_to_array($values);
  64. } elseif (!is_array($values)) {
  65. throw new /*\*/InvalidArgumentException("Values must be an array, " . gettype($values) ." given.");
  66. }
  67. $cursor = & $values;
  68. $iterator = $this->getComponents(TRUE);
  69. foreach ($iterator as $name => $control) {
  70. $sub = $iterator->getSubIterator();
  71. if (!isset($sub->cursor)) {
  72. $sub->cursor = & $cursor;
  73. }
  74. if ($control instanceof IFormControl) {
  75. if ((is_array($sub->cursor) || $sub->cursor instanceof /*\*/ArrayAccess) && array_key_exists($name, $sub->cursor)) {
  76. $control->setValue($sub->cursor[$name]);
  77. } elseif ($erase) {
  78. $control->setValue(NULL);
  79. }
  80. }
  81. if ($control instanceof INamingContainer) {
  82. if ((is_array($sub->cursor) || $sub->cursor instanceof /*\*/ArrayAccess) && isset($sub->cursor[$name])) {
  83. $cursor = & $sub->cursor[$name];
  84. } else {
  85. unset($cursor);
  86. $cursor = NULL;
  87. }
  88. }
  89. }
  90. return $this;
  91. }
  92. /**
  93. * Returns the values submitted by the form.
  94. * @return array
  95. */
  96. public function getValues()
  97. {
  98. $values = array();
  99. $cursor = & $values;
  100. $iterator = $this->getComponents(TRUE);
  101. foreach ($iterator as $name => $control) {
  102. $sub = $iterator->getSubIterator();
  103. if (!isset($sub->cursor)) {
  104. $sub->cursor = & $cursor;
  105. }
  106. if ($control instanceof IFormControl && !$control->isDisabled() && !($control instanceof ISubmitterControl)) {
  107. $sub->cursor[$name] = $control->getValue();
  108. }
  109. if ($control instanceof INamingContainer) {
  110. $cursor = & $sub->cursor[$name];
  111. $cursor = array();
  112. }
  113. }
  114. return $values;
  115. }
  116. /********************* validation ****************d*g**/
  117. /**
  118. * Is form valid?
  119. * @return bool
  120. */
  121. public function isValid()
  122. {
  123. if ($this->valid === NULL) {
  124. $this->validate();
  125. }
  126. return $this->valid;
  127. }
  128. /**
  129. * Performs the server side validation.
  130. * @return void
  131. */
  132. public function validate()
  133. {
  134. $this->valid = TRUE;
  135. foreach ($this->getControls() as $control) {
  136. if (!$control->getRules()->validate()) {
  137. $this->valid = FALSE;
  138. }
  139. }
  140. }
  141. /********************* form building ****************d*g**/
  142. /**
  143. * @param FormGroup
  144. * @return FormContainer provides a fluent interface
  145. */
  146. public function setCurrentGroup(FormGroup $group = NULL)
  147. {
  148. $this->currentGroup = $group;
  149. return $this;
  150. }
  151. /**
  152. * Adds the specified component to the IComponentContainer.
  153. * @param IComponent
  154. * @param string
  155. * @param string
  156. * @return void
  157. * @throws \InvalidStateException
  158. */
  159. public function addComponent(/*Nette\*/IComponent $component, $name, $insertBefore = NULL)
  160. {
  161. parent::addComponent($component, $name, $insertBefore);
  162. if ($this->currentGroup !== NULL && $component instanceof IFormControl) {
  163. $this->currentGroup->add($component);
  164. }
  165. }
  166. /**
  167. * Iterates over all form controls.
  168. * @return \ArrayIterator
  169. */
  170. public function getControls()
  171. {
  172. return $this->getComponents(TRUE, 'Nette\Forms\IFormControl');
  173. }
  174. /**
  175. * Returns form.
  176. * @param bool throw exception if form doesn't exist?
  177. * @return Form
  178. */
  179. public function getForm($need = TRUE)
  180. {
  181. return $this->lookup('Nette\Forms\Form', $need);
  182. }
  183. /********************* control factories ****************d*g**/
  184. /**
  185. * Adds single-line text input control to the form.
  186. * @param string control name
  187. * @param string label
  188. * @param int width of the control
  189. * @param int maximum number of characters the user may enter
  190. * @return TextInput
  191. */
  192. public function addText($name, $label = NULL, $cols = NULL, $maxLength = NULL)
  193. {
  194. return $this[$name] = new TextInput($label, $cols, $maxLength);
  195. }
  196. /**
  197. * Adds single-line text input control used for sensitive input such as passwords.
  198. * @param string control name
  199. * @param string label
  200. * @param int width of the control
  201. * @param int maximum number of characters the user may enter
  202. * @return TextInput
  203. */
  204. public function addPassword($name, $label = NULL, $cols = NULL, $maxLength = NULL)
  205. {
  206. $control = new TextInput($label, $cols, $maxLength);
  207. $control->setPasswordMode(TRUE);
  208. $this->addComponent($control, $name);
  209. return $control;
  210. }
  211. /**
  212. * Adds multi-line text input control to the form.
  213. * @param string control name
  214. * @param string label
  215. * @param int width of the control
  216. * @param int height of the control in text lines
  217. * @return TextArea
  218. */
  219. public function addTextArea($name, $label = NULL, $cols = 40, $rows = 10)
  220. {
  221. return $this[$name] = new TextArea($label, $cols, $rows);
  222. }
  223. /**
  224. * Adds control that allows the user to upload files.
  225. * @param string control name
  226. * @param string label
  227. * @return FileUpload
  228. */
  229. public function addFile($name, $label = NULL)
  230. {
  231. return $this[$name] = new FileUpload($label);
  232. }
  233. /**
  234. * Adds hidden form control used to store a non-displayed value.
  235. * @param string control name
  236. * @return HiddenField
  237. */
  238. public function addHidden($name)
  239. {
  240. return $this[$name] = new HiddenField;
  241. }
  242. /**
  243. * Adds check box control to the form.
  244. * @param string control name
  245. * @param string caption
  246. * @return Checkbox
  247. */
  248. public function addCheckbox($name, $caption)
  249. {
  250. return $this[$name] = new Checkbox($caption);
  251. }
  252. /**
  253. * Adds set of radio button controls to the form.
  254. * @param string control name
  255. * @param string label
  256. * @param array options from which to choose
  257. * @return RadioList
  258. */
  259. public function addRadioList($name, $label = NULL, array $items = NULL)
  260. {
  261. return $this[$name] = new RadioList($label, $items);
  262. }
  263. /**
  264. * Adds select box control that allows single item selection.
  265. * @param string control name
  266. * @param string label
  267. * @param array items from which to choose
  268. * @param int number of rows that should be visible
  269. * @return SelectBox
  270. */
  271. public function addSelect($name, $label = NULL, array $items = NULL, $size = NULL)
  272. {
  273. return $this[$name] = new SelectBox($label, $items, $size);
  274. }
  275. /**
  276. * Adds select box control that allows multiple item selection.
  277. * @param string control name
  278. * @param string label
  279. * @param array options from which to choose
  280. * @param int number of rows that should be visible
  281. * @return MultiSelectBox
  282. */
  283. public function addMultiSelect($name, $label = NULL, array $items = NULL, $size = NULL)
  284. {
  285. return $this[$name] = new MultiSelectBox($label, $items, $size);
  286. }
  287. /**
  288. * Adds button used to submit form.
  289. * @param string control name
  290. * @param string caption
  291. * @return SubmitButton
  292. */
  293. public function addSubmit($name, $caption)
  294. {
  295. return $this[$name] = new SubmitButton($caption);
  296. }
  297. /**
  298. * Adds push buttons with no default behavior.
  299. * @param string control name
  300. * @param string caption
  301. * @return Button
  302. */
  303. public function addButton($name, $caption)
  304. {
  305. return $this[$name] = new Button($caption);
  306. }
  307. /**
  308. * Adds graphical button used to submit form.
  309. * @param string control name
  310. * @param string URI of the image
  311. * @param string alternate text for the image
  312. * @return ImageButton
  313. */
  314. public function addImage($name, $src = NULL, $alt = NULL)
  315. {
  316. return $this[$name] = new ImageButton($src, $alt);
  317. }
  318. /**
  319. * Adds naming container to the form.
  320. * @param string name
  321. * @return FormContainer
  322. */
  323. public function addContainer($name)
  324. {
  325. $control = new FormContainer;
  326. $control->currentGroup = $this->currentGroup;
  327. return $this[$name] = $control;
  328. }
  329. /**
  330. * Adds control that repeats a specified prototype for each item in the list.
  331. * @param string control name
  332. * @return RepeaterControl
  333. */
  334. public function addRepeater($name)
  335. {
  336. return $this[$name] = new RepeaterControl;
  337. }
  338. /********************* interface \ArrayAccess ****************d*g**/
  339. /**
  340. * Adds the component to the container.
  341. * @param string component name
  342. * @param Nette\IComponent
  343. * @return void.
  344. */
  345. final public function offsetSet($name, $component)
  346. {
  347. $this->addComponent($component, $name);
  348. }
  349. /**
  350. * Returns component specified by name. Throws exception if component doesn't exist.
  351. * @param string component name
  352. * @return Nette\IComponent
  353. * @throws \InvalidArgumentException
  354. */
  355. final public function offsetGet($name)
  356. {
  357. return $this->getComponent($name, TRUE);
  358. }
  359. /**
  360. * Does component specified by name exists?
  361. * @param string component name
  362. * @return bool
  363. */
  364. final public function offsetExists($name)
  365. {
  366. return $this->getComponent($name, FALSE) !== NULL;
  367. }
  368. /**
  369. * Removes component from the container. Throws exception if component doesn't exist.
  370. * @param string component name
  371. * @return void
  372. */
  373. final public function offsetUnset($name)
  374. {
  375. $component = $this->getComponent($name, FALSE);
  376. if ($component !== NULL) {
  377. $this->removeComponent($component);
  378. }
  379. }
  380. }