WhoDidItBehavior.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * PHP 5
  4. *
  5. * @copyright http://www.4webby.com
  6. * @author Daniel Vecchiato
  7. * @author Mark Scherer
  8. * @author Marc Würth
  9. * @version 1.3
  10. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  11. * @link https://github.com/dereuromark/tools
  12. */
  13. App::uses('CakeSession', 'Model/Datasource');
  14. App::uses('ModelBehavior', 'Model');
  15. /**
  16. * WhoDidIt Behavior
  17. *
  18. * Handles created_by, modified_by fields for a given Model, if they exist in the Model DB table.
  19. * It's similar to the created, modified automagic, but it stores the id of the logged in user
  20. * in the models that have $actsAs = array('WhoDidIt').
  21. *
  22. * This is useful to track who created records, and the last user that has changed them.
  23. *
  24. * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#using-created-and-modified
  25. */
  26. class WhoDidItBehavior extends ModelBehavior {
  27. /**
  28. * Default settings for a model that has this behavior attached.
  29. *
  30. * Setting force_modified to true will have the same effect as overriding the save method as
  31. * described in the code example for "Using created and modified" in the Cookbook.
  32. *
  33. * @var array
  34. * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#using-created-and-modified
  35. */
  36. protected $_defaults = array(
  37. 'auth_session' => 'Auth', // Name of Auth session key
  38. 'user_model' => 'User', // Name of the User model
  39. 'created_by_field' => 'created_by', // Name of the "created_by" field in the model
  40. 'modified_by_field' => 'modified_by', // Name of the "modified_by" field in the model
  41. 'confirmed_by_field' => 'confirmed_by', // Name of the "confirmed by" field in the model
  42. 'auto_bind' => true, // Automatically bind the model to the User model (default true)
  43. 'force_modified' => false // Force update of the "modified" field even if not empty
  44. );
  45. /**
  46. * Initiate WhoDidIt Behavior.
  47. *
  48. * Checks if the configured fields are available in the model.
  49. * Also binds the User model as association for each available field.
  50. *
  51. * @param Model $Model The model.
  52. * @param array $config Behavior settings you would like to override.
  53. * @return void
  54. */
  55. public function setup(Model $Model, $config = array()) {
  56. $this->settings[$Model->alias] = array_merge($this->_defaults, (array)$config);
  57. $hasFieldCreatedBy = $Model->hasField($this->settings[$Model->alias]['created_by_field']);
  58. $hasFieldModifiedBy = $Model->hasField($this->settings[$Model->alias]['modified_by_field']);
  59. $hasFieldConfirmedBy = $Model->hasField($this->settings[$Model->alias]['confirmed_by_field']);
  60. $this->settings[$Model->alias]['has_created_by'] = $hasFieldCreatedBy;
  61. $this->settings[$Model->alias]['has_modified_by'] = $hasFieldModifiedBy;
  62. $this->settings[$Model->alias]['has_confirmed_by'] = $hasFieldConfirmedBy;
  63. // Handles model binding to the User model according to the auto_bind settings (default true).
  64. if ($this->settings[$Model->alias]['auto_bind']) {
  65. if ($hasFieldCreatedBy) {
  66. $commonBelongsTo = array(
  67. 'CreatedBy' => array(
  68. 'className' => $this->settings[$Model->alias]['user_model'],
  69. 'foreignKey' => $this->settings[$Model->alias]['created_by_field']));
  70. $Model->bindModel(array('belongsTo' => $commonBelongsTo), false);
  71. }
  72. if ($hasFieldModifiedBy) {
  73. $commonBelongsTo = array(
  74. 'ModifiedBy' => array(
  75. 'className' => $this->settings[$Model->alias]['user_model'],
  76. 'foreignKey' => $this->settings[$Model->alias]['modified_by_field']));
  77. $Model->bindModel(array('belongsTo' => $commonBelongsTo), false);
  78. }
  79. if ($hasFieldConfirmedBy) {
  80. $commonBelongsTo = array(
  81. 'ConfirmedBy' => array(
  82. 'className' => $this->settings[$Model->alias]['user_model'],
  83. 'foreignKey' => $this->settings[$Model->alias]['confirmed_by_field']));
  84. $Model->bindModel(array('belongsTo' => $commonBelongsTo), false);
  85. }
  86. }
  87. }
  88. /**
  89. * Before save callback.
  90. *
  91. * Checks if at least one field is available.
  92. * Reads the current user id from the session.
  93. * If a user id is set it will fill...
  94. * ... the created_by field only when creating a record
  95. * ... the modified by field only if it is not in the data array
  96. * or the "force_modified" setting is set to true.
  97. *
  98. * @param Model $Model The model using this behavior.
  99. * @return boolean True if the operation should continue, false if it should abort.
  100. */
  101. public function beforeSave(Model $Model, $options = array()) {
  102. if ($this->settings[$Model->alias]['has_created_by'] || $this->settings[$Model->alias]['has_modified_by']) {
  103. $AuthSession = $this->settings[$Model->alias]['auth_session'];
  104. $UserSession = $this->settings[$Model->alias]['user_model'];
  105. $userId = CakeSession::read($AuthSession . '.' . $UserSession . '.id');
  106. if ($userId) {
  107. $data = array();
  108. $modifiedByField = $this->settings[$Model->alias]['modified_by_field'];
  109. if (!isset($Model->data[$Model->alias][$modifiedByField]) || $this->settings[$Model->alias]['force_modified']) {
  110. $data[$this->settings[$Model->alias]['modified_by_field']] = $userId;
  111. } else {
  112. $pos = strpos($this->settings[$Model->alias]['modified_by_field'], '_');
  113. $field = substr($this->settings[$Model->alias]['modified_by_field'], 0, $pos);
  114. $data[$field] = false;
  115. }
  116. if (!$Model->exists()) {
  117. $data[$this->settings[$Model->alias]['created_by_field']] = $userId;
  118. }
  119. if ($data) {
  120. $Model->set($data);
  121. }
  122. }
  123. }
  124. return true;
  125. }
  126. }