UserBehaviorBehavior.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * Author: ljt
  5. * DateTime: 2016/11/21 13:24
  6. * Description:
  7. */
  8. namespace common\behaviors;
  9. use common\modules\user\models\Profile;
  10. use yii\base\Behavior;
  11. use yii\helpers\ArrayHelper;
  12. use yii\helpers\StringHelper;
  13. use Yii;
  14. use common\models\UserBehaviorLog as Log;
  15. /**
  16. * 记录用户行为
  17. */
  18. class UserBehaviorBehavior extends Behavior
  19. {
  20. const RULE = '/\{(.+?)(?:\{(.+)\})?\}/';
  21. public $name;
  22. public $eventName = [];
  23. /**
  24. * @var array 触发规则
  25. ```
  26. [
  27. 'cycle' => 24,
  28. 'max' => 1,
  29. 'counter' => 10,
  30. ]
  31. ```
  32. */
  33. public $rule;
  34. /**
  35. * @var array 附加数据
  36. */
  37. public $data = [];
  38. /**
  39. * @var string 日志内容格式
  40. */
  41. public $content;
  42. public function events()
  43. {
  44. $events = [];
  45. $this->eventName = (array) $this->eventName;
  46. foreach ($this->eventName as $eventName) {
  47. $events[$eventName] = 'execute';
  48. }
  49. return $events;
  50. }
  51. public function execute()
  52. {
  53. //执行行为规则
  54. $execCount = Log::find()->where(['behavior_name' => $this->name, 'user_id' => Yii::$app->user->identity->id])->andWhere(['>', 'created_at', time() - intval($this->rule['cycle']) * 3600])->count();
  55. if($execCount >= $this->rule['max']){
  56. return;
  57. }
  58. // TODO 暂时只支持更新money字段
  59. Profile::updateAllCounters(['money' => $this->rule['counter']], ['user_id' => Yii::$app->user->identity->id]);
  60. //记录日志
  61. $this->log();
  62. }
  63. private function log()
  64. {
  65. $this->parseContent($this->data);
  66. $log = new Log();
  67. $log->behavior_name = $this->name;
  68. $log->user_id = Yii::$app->user->identity->id;
  69. $log->content = $this->content;
  70. $log->save(false);
  71. }
  72. protected function parseContent($data)
  73. {
  74. $data = array_merge(['user' => Yii::$app->user->identity], $data);
  75. $specialValues = $this->getValues($this->content);
  76. if (count($specialValues) > 0) {
  77. $specialValues = array_filter($specialValues, function ($value) {
  78. return StringHelper::startsWith($value, 'extra.') || StringHelper::startsWith($value, 'user.');
  79. });
  80. foreach ($specialValues as $replacer) {
  81. $replace = ArrayHelper::getValue($data, $replacer);
  82. $this->content = $this->replaceContent($this->content, $replace, $replacer);
  83. }
  84. }
  85. }
  86. protected function getValues($body)
  87. {
  88. $values = [];
  89. preg_match_all(self::RULE, $body, $values);
  90. return $values[1];
  91. }
  92. protected function replaceContent($body, $valueMatch, $replacer)
  93. {
  94. $body = str_replace('{'.$replacer.'}', $valueMatch, $body);
  95. return $body;
  96. }
  97. }