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

/lib/MiniMVC/MiniMVC/Form.php

https://github.com/tquensen/MiniMVC
PHP | 363 lines | 254 code | 53 blank | 56 comment | 25 complexity | 8f5f63d93d1b99ce6bbe2c0e3b46a079 MD5 | raw file
  1. <?php
  2. class MiniMVC_Form
  3. {
  4. protected $elements = array();
  5. protected $name = null;
  6. protected $isValid = true;
  7. protected $wasSubmitted = null;
  8. protected $errors = array();
  9. protected $options = array();
  10. protected $model = null;
  11. protected $postValidators = array();
  12. public function __construct($options = array())
  13. {
  14. $this->name = (isset($options['name'])) ? $options['name'] : $this->name;
  15. $this->model = (isset($options['model'])) ? $options['model'] : $this->model;
  16. $i18n = MiniMVC_Registry::getInstance()->helper->i18n->get('_form');
  17. $this->options['route'] = MiniMVC_Registry::getInstance()->settings->get('currentRoute');
  18. $this->options['parameter'] = isset($options['route']) ? array() : MiniMVC_Registry::getInstance()->settings->get('currentRouteParameter');
  19. $this->options['method'] = 'POST';
  20. $this->options['wrapper'] = 'div';
  21. $this->options['showGlobalErrors'] = true;
  22. $this->options['requiredMark'] = $i18n->requiredMark;
  23. $this->options['useFormToken'] = true;
  24. $this->options['ignoreTokenOnAuthenticatedRequest'] = false;
  25. $this->options['formTokenErrorMessage'] = $i18n->formTokenErrorMessage;
  26. $this->options = array_merge($this->options, (array)$options);
  27. $this->options['action'] = MiniMVC_Registry::getInstance()->helper->url->get($this->options['route'], !empty($this->options['parameter']) ? $this->options['parameter'] : array());
  28. //$this->setElement(new MiniMVC_Form_Element_Hidden('FormCheck', array('defaultValue' => 1, 'alwaysDisplayDefault' => true), array(new MiniMVC_Form_Validator_Required())));
  29. }
  30. public function getFormToken()
  31. {
  32. if (!$this->getOption('useFormToken')) {
  33. return false;
  34. }
  35. return MiniMVC_Registry::getInstance()->guard->generateFormToken();
  36. }
  37. public function checkFormToken()
  38. {
  39. if (!$this->getOption('useFormToken')) {
  40. return false;
  41. }
  42. return MiniMVC_Registry::getInstance()->guard->checkFormToken();
  43. }
  44. public function getName()
  45. {
  46. return $this->name;
  47. }
  48. public function setName($name)
  49. {
  50. $this->name = $name;
  51. }
  52. public function getModel()
  53. {
  54. return $this->model;
  55. }
  56. public function setModel($model)
  57. {
  58. $this->model = $model;
  59. }
  60. public function updateModel()
  61. {
  62. if (!is_object($this->model)) {
  63. return false;
  64. }
  65. foreach ($this->elements as $element) {
  66. $element->updateModel($this->model);
  67. }
  68. return $this->model;
  69. }
  70. public function __get($element)
  71. {
  72. return $this->getElement($element);
  73. }
  74. public function setOption($option, $value)
  75. {
  76. $this->options[$option] = $value;
  77. return true;
  78. }
  79. public function getOption($option)
  80. {
  81. return (isset($this->options[$option])) ? $this->options[$option] : null;
  82. }
  83. public function setElement($element)
  84. {
  85. if (!is_object($element)) {
  86. return false;
  87. }
  88. $this->elements[$element->getName()] = $element;
  89. $element->setForm($this);
  90. if ($this->getOption('forceGlobalErrors')) {
  91. $element->globalErrors = true;
  92. }
  93. return $this;
  94. }
  95. /**
  96. *
  97. * @param string $name the name of a form element
  98. * @return MiniMVC_Form_Element
  99. */
  100. public function getElement($name)
  101. {
  102. return (isset($this->elements[$name])) ? $this->elements[$name] : null;
  103. }
  104. public function getElements()
  105. {
  106. return $this->elements;
  107. }
  108. public function setPostValidator($validator)
  109. {
  110. if (!is_object($validator)) {
  111. return false;
  112. }
  113. $this->postValidators[] = $validator;
  114. $validator->setForm($this);
  115. return $this;
  116. }
  117. public function getPostValidators()
  118. {
  119. return $this->postValidators;
  120. }
  121. public function bindValues($values = null)
  122. {
  123. // if (isset($_SESSION['form_' . $this->name . '__errorData'])) {
  124. // $values = $_SESSION['form_' . $this->name . '__errorData'];
  125. //
  126. // if (!empty($values['_form'])) {
  127. // $this->errors = $values['_form'];
  128. // $this->isValid = false;
  129. // }
  130. //
  131. // unset($_SESSION['form_' . $this->name . '__errorData']);
  132. // foreach ($this->elements as $element) {
  133. // $_POST[$this->name][$element->getName()] = isset($values[$element->getName()]['value']) ? $values[$element->getName()]['value']
  134. // : null;
  135. // if (!empty($values[$element->getName()]['hasError'])) {
  136. // $this->isValid = false;
  137. // $element->setError($values[$element->getName()]['errorMessage']);
  138. // }
  139. // }
  140. // }
  141. if ($values === null) {
  142. $arr = strtoupper($this->getOption('method')) === 'GET' ? $_GET : $_POST;
  143. if (empty($arr[$this->name])) {
  144. $this->wasSubmitted = false;
  145. return false;
  146. }
  147. $values = $arr[$this->name];
  148. }
  149. $this->wasSubmitted = true;
  150. foreach ($this->elements as $element) {
  151. $element->setValue(isset($values[$element->getName()]) ? $values[$element->getName()]
  152. : false);
  153. }
  154. return true;
  155. }
  156. public function setError($errorMessage = null, $element = null)
  157. {
  158. $this->isValid = false;
  159. if ($errorMessage) {
  160. $this->errors[] = array('message' => $errorMessage, 'element' => $element);
  161. }
  162. }
  163. public function getErrors()
  164. {
  165. return $this->errors;
  166. }
  167. public function hasErrors()
  168. {
  169. return (bool) count($this->errors);
  170. }
  171. public function isValid()
  172. {
  173. return $this->isValid;
  174. }
  175. public function validate($values = null)
  176. {
  177. // $this->handleAjaxValidation();
  178. if ($values !== null) {
  179. $this->bindValues($values);
  180. }
  181. if (!$this->isValid || !$this->wasSubmitted()) {
  182. return false;
  183. }
  184. if ($this->getOption('useFormToken') && !MiniMVC_Registry::getInstance()->guard->checkFormToken()
  185. && (!$this->getOption('ignoreTokenOnAuthenticatedRequest') || !MiniMVC_Registry::getInstance()->guard->isAuthenticatedRequest())) {
  186. $this->setError($this->getOption('formTokenErrorMessage'));
  187. return false;
  188. }
  189. foreach ($this->elements as $element) {
  190. if (!$element->validate()) {
  191. $this->isValid = false;
  192. }
  193. }
  194. foreach ($this->postValidators as $validator)
  195. {
  196. if (!$validator->validate($this->isValid))
  197. {
  198. $errorMessage = $validator->errorMessage;
  199. if ($errorMessage)
  200. {
  201. $this->setError($errorMessage);
  202. }
  203. $this->isValid = false;
  204. }
  205. }
  206. // if (!$this->isValid && $this->getOption('redirectOnError')) {
  207. // $this->errorRedirect();
  208. // }
  209. return $this->isValid;
  210. }
  211. public function errorRedirect($route, $parameter = array())
  212. {
  213. $url = MiniMVC_Registry::getInstance()->helper->url->get($route, $parameter);
  214. $sessionData = array();
  215. foreach ($this->elements as $element) {
  216. $sessionData[$element->getName()] = array(
  217. 'hasError' => !$element->isValid(),
  218. 'value' => $element->value,
  219. 'errorMessage' => $element->errorMessage
  220. );
  221. }
  222. $sessionData['_form'] = $this->errors;
  223. $_SESSION['form_' . $this->name . '__errorData'] = $sessionData;
  224. $url = MiniMVC_Registry::getInstance()->helper->url->get($route, $parameter);
  225. header('Location: ' . $url);
  226. exit;
  227. }
  228. public function successRedirect($route, $parameter = array())
  229. {
  230. $url = MiniMVC_Registry::getInstance()->helper->url->get($route, $parameter);
  231. header('Location: ' . $url);
  232. exit;
  233. }
  234. public function wasSubmitted()
  235. {
  236. if ($this->wasSubmitted === null) {
  237. $this->bindValues();
  238. }
  239. return $this->wasSubmitted;
  240. //return strtoupper($this->getOption('method')) === 'GET' ? !empty($_GET[$this->name]) : !empty($_POST[$this->name]);
  241. }
  242. public function getValues()
  243. {
  244. $values = array();
  245. foreach ($this->elements as $element) {
  246. $values[$element->getName()] = $element->value;
  247. }
  248. return $values;
  249. }
  250. /**
  251. *
  252. * @param bool $public whether to export only "save" data (true, default) or any options of the form (false)
  253. * @return array the array representation of this form
  254. */
  255. public function toArray($public = true)
  256. {
  257. $form = array();
  258. $form['name'] = $this->name;
  259. if ($public) {
  260. $form['action'] = $this->getOption('action');
  261. $form['method'] = $this->getOption('method');
  262. $form['enctype'] = $this->getOption('enctype');
  263. }
  264. $form['globalErrors'] = $this->errors;
  265. $form['elements'] = array();
  266. foreach ($this->elements as $element) {
  267. $elementData = $element->toArray($public);
  268. if ($elementData) {
  269. $form['elements'][$element->getName()] = $elementData;
  270. }
  271. }
  272. if ($public) {
  273. $form['options'] = array();
  274. $form['options']['showGlobalErrors'] = $this->getOption('showGlobalErrors');
  275. $form['options']['requiredMark'] = $this->getOption('requiredMark');
  276. $form['options']['class'] = $this->getOption('class');
  277. $form['options']['attributes'] = $this->getOption('attributes');
  278. } else {
  279. $form['options'] = $this->options;
  280. }
  281. $form['isValid'] = $this->isValid;
  282. $form['wasSubmitted'] = $this->wasSubmitted();
  283. if ($this->getOption('useFormToken')) {
  284. $form['auth']['formToken'] = $this->getFormToken();
  285. }
  286. return $form;
  287. }
  288. // public function handleAjaxValidation()
  289. // {
  290. // if (empty($_POST['_validateForm']) || $_POST['_validateForm'] != $this->name) {
  291. // return;
  292. // }
  293. //
  294. // if (empty($_POST['_validateField']) || !isset($_POST['_validateValue'])) {
  295. // $t = MiniMVC_Registry::getInstance()->helper->i18n->get('_form');
  296. // $response = array('status' => false, 'message' => $t->errorAjaxMissingField);
  297. // exit;
  298. // } elseif (!$field = $this->getElement($_POST['_validateField'])) {
  299. // $t = MiniMVC_Registry::getInstance()->helper->i18n->get('_form');
  300. // $response = array('status' => false, 'message' => $t->errorAjaxInvalidField('field=' . htmlspecialchars($_POST['_validateField'])));
  301. // } else {
  302. // $field->setValue($_POST['_validateValue']);
  303. // $response = $field->validate() ? array('status' => true) : array('status' => false, 'message' => $field->errorMessage);
  304. // }
  305. //
  306. // header('Content-Type: application/json');
  307. // echo json_encode($response);
  308. // exit;
  309. // }
  310. }