WhoDidItBehavior.php 4.8 KB

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