Form.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Form;
  16. use Cake\Form\Schema;
  17. use Cake\Validation\Validator;
  18. /**
  19. * Form abstraction used to create forms not tied to ORM backed models,
  20. * or to other permanent datastores. Ideal for implementing forms on top of
  21. * API services, or contact forms.
  22. *
  23. * ### Building a form
  24. *
  25. * This class is most useful when subclassed. In a subclass you
  26. * should define the `_buildSchema`, `_buildValidator` and optionally,
  27. * the `_execute` methods. These allow you to declare your form's
  28. * fields, validation and primary action respectively.
  29. *
  30. * You can also define the validation and schema by chaining method
  31. * calls off of `$form->schema()` and `$form->validator()`.
  32. *
  33. * Forms are conventionally placed in the `App\Form` namespace.
  34. */
  35. class Form
  36. {
  37. /**
  38. * The schema used by this form.
  39. *
  40. * @var \Cake\Form\Schema;
  41. */
  42. protected $_schema;
  43. /**
  44. * The errors if any
  45. *
  46. * @var array
  47. */
  48. protected $_errors = [];
  49. /**
  50. * The validator used by this form.
  51. *
  52. * @var \Cake\Validation\Validator;
  53. */
  54. protected $_validator;
  55. /**
  56. * Get/Set the schema for this form.
  57. *
  58. * This method will call `_buildSchema()` when the schema
  59. * is first built. This hook method lets you configure the
  60. * schema or load a pre-defined one.
  61. *
  62. * @param \Cake\Form\Schema $schema The schema to set, or null.
  63. * @return \Cake\Form\Schema the schema instance.
  64. */
  65. public function schema(Schema $schema = null)
  66. {
  67. if ($schema === null && empty($this->_schema)) {
  68. $schema = $this->_buildSchema(new Schema());
  69. }
  70. if ($schema) {
  71. $this->_schema = $schema;
  72. }
  73. return $this->_schema;
  74. }
  75. /**
  76. * A hook method intended to be implemented by subclasses.
  77. *
  78. * You can use this method to define the schema using
  79. * the methods on Cake\Form\Schema, or loads a pre-defined
  80. * schema from a concrete class.
  81. *
  82. * @param \Cake\Form\Schema $schema The schema to customize.
  83. * @return \Cake\Form\Schema The schema to use.
  84. */
  85. protected function _buildSchema(Schema $schema)
  86. {
  87. return $schema;
  88. }
  89. /**
  90. * Get/Set the validator for this form.
  91. *
  92. * This method will call `_buildValidator()` when the validator
  93. * is first built. This hook method lets you configure the
  94. * validator or load a pre-defined one.
  95. *
  96. * @param \Cake\Validation\Validator $validator The validator to set, or null.
  97. * @return \Cake\Validation\Validator the validator instance.
  98. */
  99. public function validator(Validator $validator = null)
  100. {
  101. if ($validator === null && empty($this->_validator)) {
  102. $validator = $this->_buildValidator(new Validator());
  103. }
  104. if ($validator) {
  105. $this->_validator = $validator;
  106. }
  107. return $this->_validator;
  108. }
  109. /**
  110. * A hook method intended to be implemented by subclasses.
  111. *
  112. * You can use this method to define the validator using
  113. * the methods on Cake\Validation\Validator or loads a pre-defined
  114. * validator from a concrete class.
  115. *
  116. * @param \Cake\Validation\Validator $validator The validator to customize.
  117. * @return \Cake\Validation\Validator The validator to use.
  118. */
  119. protected function _buildValidator(Validator $validator)
  120. {
  121. return $validator;
  122. }
  123. /**
  124. * Used to check if $data passes this form's validation.
  125. *
  126. * @param array $data The data to check.
  127. * @return bool Whether or not the data is valid.
  128. */
  129. public function validate(array $data)
  130. {
  131. $validator = $this->validator();
  132. $this->_errors = $validator->errors($data);
  133. return count($this->_errors) === 0;
  134. }
  135. /**
  136. * Get the errors in the form
  137. *
  138. * Will return the errors from the last call
  139. * to `validate()` or `execute()`.
  140. *
  141. * @return array Last set validation errors.
  142. */
  143. public function errors()
  144. {
  145. return $this->_errors;
  146. }
  147. /**
  148. * Execute the form if it is valid.
  149. *
  150. * First validates the form, then calls the `_execute()` hook method.
  151. * This hook method can be implemented in subclasses to perform
  152. * the action of the form. This may be sending email, interacting
  153. * with a remote API, or anything else you may need.
  154. *
  155. * @param array $data Form data.
  156. * @return bool False on validation failure, otherwise returns the
  157. * result of the `_execute()` method.
  158. */
  159. public function execute(array $data)
  160. {
  161. if (!$this->validate($data)) {
  162. return false;
  163. }
  164. return $this->_execute($data);
  165. }
  166. /**
  167. * Hook method to be implemented in subclasses.
  168. *
  169. * Used by `execute()` to execute the form's action.
  170. *
  171. * @param array $data Form data.
  172. * @return bool
  173. */
  174. protected function _execute(array $data)
  175. {
  176. return true;
  177. }
  178. /**
  179. * Get the printable version of a Form instance.
  180. *
  181. * @return array
  182. */
  183. public function __debugInfo()
  184. {
  185. $special = [
  186. '_schema' => $this->schema()->__debugInfo(),
  187. '_errors' => $this->errors(),
  188. '_validator' => $this->validator()->__debugInfo()
  189. ];
  190. return $special + get_object_vars($this);
  191. }
  192. }