PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/en/models/callback-methods.rst

https://gitlab.com/albertkeba/docs
ReStructuredText | 230 lines | 171 code | 59 blank | 0 comment | 0 complexity | 29f2dfda5d897e4a731dd24a60bd39bf MD5 | raw file
  1. Callback Methods
  2. ################
  3. If you want to sneak in some logic just before or after a CakePHP
  4. model operation, use model callbacks. These functions can be
  5. defined in model classes (including your AppModel) class. Be sure
  6. to note the expected return values for each of these special
  7. functions.
  8. When using callback methods you should remember that behavior callbacks are
  9. fired **before** model callbacks are.
  10. beforeFind
  11. ==========
  12. ``beforeFind(array $query)``
  13. Called before any find-related operation. The ``$query`` passed
  14. to this callback contains information about the current query:
  15. conditions, fields, etc.
  16. If you do not wish the find operation to begin (possibly based on a
  17. decision relating to the ``$query`` options), return *false*.
  18. Otherwise, return the possibly modified ``$query``, or anything
  19. you want to get passed to find and its counterparts.
  20. You might use this callback to restrict find operations based on a
  21. user's role, or make caching decisions based on the current load.
  22. afterFind
  23. =========
  24. ``afterFind(array $results, boolean $primary = false)``
  25. Use this callback to modify results that have been returned from a
  26. find operation, or to perform any other post-find logic. The
  27. $results parameter passed to this callback contains the returned
  28. results from the model's find operation, i.e. something like::
  29. $results = array(
  30. 0 => array(
  31. 'ModelName' => array(
  32. 'field1' => 'value1',
  33. 'field2' => 'value2',
  34. ),
  35. ),
  36. );
  37. The return value for this callback should be the (possibly
  38. modified) results for the find operation that triggered this
  39. callback.
  40. The ``$primary`` parameter indicates whether or not the current
  41. model was the model that the query originated on or whether or not
  42. this model was queried as an association. If a model is queried as
  43. an association the format of ``$results`` can differ; instead of the
  44. result you would normally get from a find operation, you may get
  45. this::
  46. $results = array(
  47. 'field_1' => 'value1',
  48. 'field_2' => 'value2'
  49. );
  50. .. warning::
  51. Code expecting ``$primary`` to be true will probably get a "Cannot
  52. use string offset as an array" fatal error from PHP if a recursive
  53. find is used.
  54. Below is an example of how afterfind can be used for date
  55. formatting::
  56. public function afterFind($results, $primary = false) {
  57. foreach ($results as $key => $val) {
  58. if (isset($val['Event']['begindate'])) {
  59. $results[$key]['Event']['begindate'] = $this->dateFormatAfterFind(
  60. $val['Event']['begindate']
  61. );
  62. }
  63. }
  64. return $results;
  65. }
  66. public function dateFormatAfterFind($dateString) {
  67. return date('d-m-Y', strtotime($dateString));
  68. }
  69. beforeValidate
  70. ==============
  71. ``beforeValidate(array $options = array())``
  72. Use this callback to modify model data before it is validated, or
  73. to modify validation rules if required. This function must also
  74. return *true*, otherwise the current save() execution will abort.
  75. afterValidate
  76. =============
  77. ``afterValidate()``
  78. Called after data has been checked for errors. Use this callback to perform
  79. any data cleanup or preparation if needed.
  80. beforeSave
  81. ==========
  82. ``beforeSave(array $options = array())``
  83. Place any pre-save logic in this function. This function executes
  84. immediately after model data has been successfully validated, but
  85. just before the data is saved. This function should also return
  86. true if you want the save operation to continue.
  87. This callback is especially handy for any data-massaging logic that
  88. needs to happen before your data is stored. If your storage engine
  89. needs dates in a specific format, access it at $this->data and
  90. modify it.
  91. Below is an example of how beforeSave can be used for date
  92. conversion. The code in the example is used for an application with
  93. a begindate formatted like YYYY-MM-DD in the database and is
  94. displayed like DD-MM-YYYY in the application. Of course this can be
  95. changed very easily. Use the code below in the appropriate model.
  96. ::
  97. public function beforeSave($options = array()) {
  98. if (!empty($this->data['Event']['begindate']) &&
  99. !empty($this->data['Event']['enddate'])
  100. ) {
  101. $this->data['Event']['begindate'] = $this->dateFormatBeforeSave(
  102. $this->data['Event']['begindate']
  103. );
  104. $this->data['Event']['enddate'] = $this->dateFormatBeforeSave(
  105. $this->data['Event']['enddate']
  106. );
  107. }
  108. return true;
  109. }
  110. public function dateFormatBeforeSave($dateString) {
  111. return date('Y-m-d', strtotime($dateString));
  112. }
  113. .. tip::
  114. Be sure that beforeSave() returns true, or your save is going to
  115. fail.
  116. afterSave
  117. =========
  118. ``afterSave(boolean $created, array $options = array())``
  119. If you have logic you need to be executed just after every save
  120. operation, place it in this callback method. The saved data will
  121. be available in ``$this->data``.
  122. The value of ``$created`` will be true if a new record was created
  123. (rather than an update).
  124. The ``$options`` array is the same one passed to ``Model::save()``.
  125. beforeDelete
  126. ============
  127. ``beforeDelete(boolean $cascade = true)``
  128. Place any pre-deletion logic in this function. This function should
  129. return true if you want the deletion to continue, and false if you
  130. want to abort.
  131. The value of ``$cascade`` will be ``true`` if records that depend
  132. on this record will also be deleted.
  133. .. tip::
  134. Be sure that beforeDelete() returns true, or your delete is going
  135. to fail.
  136. ::
  137. // using app/Model/ProductCategory.php
  138. // In the following example, do not let a product category be deleted if it
  139. // still contains products.
  140. // A call of $this->Product->delete($id) from ProductsController.php has set
  141. // $this->id .
  142. // Assuming 'ProductCategory hasMany Product', we can access $this->Product
  143. // in the model.
  144. public function beforeDelete($cascade = true) {
  145. $count = $this->Product->find("count", array(
  146. "conditions" => array("product_category_id" => $this->id)
  147. ));
  148. if ($count == 0) {
  149. return true;
  150. }
  151. return false;
  152. }
  153. afterDelete
  154. ===========
  155. ``afterDelete()``
  156. Place any logic that you want to be executed after every deletion
  157. in this callback method.
  158. ::
  159. // perhaps after deleting a record from the database, you also want to delete
  160. // an associated file
  161. public function afterDelete() {
  162. $file = new File($this->data['SomeModel']['file_path']);
  163. $file->delete();
  164. }
  165. onError
  166. =======
  167. ``onError()``
  168. Called if any problems occur.
  169. .. meta::
  170. :title lang=en: Callback Methods
  171. :keywords lang=en: querydata,query conditions,model classes,callback methods,special functions,return values,counterparts,array,logic,decisions