Completed
Push — master ( ca4764...3915c0 )
by vistart
06:24
created

BlameableTrait::countOfOwner()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 *  _   __ __ _____ _____ ___  ____  _____
5
 * | | / // // ___//_  _//   ||  __||_   _|
6
 * | |/ // /(__  )  / / / /| || |     | |
7
 * |___//_//____/  /_/ /_/ |_||_|     |_|
8
 * @link https://vistart.name/
9
 * @copyright Copyright (c) 2016 vistart
10
 * @license https://vistart.name/license/
11
 */
12
13
namespace vistart\Models\traits;
14
15
use yii\behaviors\BlameableBehavior;
16
use yii\caching\TagDependency;
17
18
/**
19
 * This trait is used for building blameable model. It contains following features:
20
 * 1.单列内容;多列内容待定;
21
 * 2.内容类型;具体类型应当自定义;
22
 * 3.内容规则;自动生成;
23
 * 4.归属用户 GUID;
24
 * 5.创建用户 GUID;
25
 * 6.上次更新用户 GUID;
26
 * 7.Confirmation features, provided by [[ConfirmationTrait]];
27
 * @property-read array $blameableAttributeRules Get all rules associated with
28
 * blameable.
29
 * @property array $blameableRules Get or set all the rules associated with
30
 * creator, updater, content and its ID, as well as all the inherited rules.
31
 * @property array $blameableBehaviors Get or set all the behaviors assoriated
32
 * with creator and updater, as well as all the inherited behaviors.
33
 * @property-read array $descriptionRules Get description property rules.
34
 * @property-read mixed $content Content.
35
 * @property-read boolean $contentCanBeEdited Whether this content could be edited.
36
 * @property-read array $contentRules Get content rules.
37
 * @property-read \vistart\Models\models\BaseUserModel $user
38
 * @property-read \vistart\Models\models\BaseUserModel $updater
39
 * @version 2.0
40
 * @author vistart <[email protected]>
41
 */
42
trait BlameableTrait
43
{
44
    use ConfirmationTrait,
45
        SelfBlameableTrait;
46
47
    private $blameableLocalRules = [];
48
    private $blameableLocalBehaviors = [];
49
50
    /**
51
     * @var boolean|string|array Specify the attribute(s) name of content(s). If
52
     * there is only one content attribute, you can assign its name. Or there
53
     * is multiple attributes associated with contents, you can assign their
54
     * names in array. If you don't want to use this feature, please assign
55
     * false.
56
     * For example:
57
     * ```php
58
     * public $contentAttribute = 'comment'; // only one field named as 'comment'.
59
     * ```
60
     * or
61
     * ```php
62
     * public $contentAttribute = ['year', 'month', 'day']; // multiple fields.
63
     * ```
64
     * or
65
     * ```php
66
     * public $contentAttribute = false; // no need of this feature.
67
     * ```
68
     * If you don't need this feature, you should add rules corresponding with
69
     * `content` in `rules()` method of your user model by yourself.
70
     */
71
    public $contentAttribute = 'content';
72
73
    /**
74
     * @var array built-in validator name or validatation method name and
75
     * additional parameters.
76
     */
77
    public $contentAttributeRule = ['string', 'max' => 255];
78
79
    /**
80
     * @var boolean|string Specify the field which stores the type of content.
81
     */
82
    public $contentTypeAttribute = false;
83
84
    /**
85
     * @var boolean|array Specify the logic type of content, not data type. If
86
     * your content doesn't need this feature. please specify false. If the
87
     * $contentAttribute is specified to false, this attribute will be skipped.
88
     * ```php
89
     * public $contentTypes = [
90
     *     'public',
91
     *     'private',
92
     *     'friend',
93
     * ];
94
     * ```
95
     */
96
    public $contentTypes = false;
97
98
    /**
99
     * @var boolean|string This attribute speicfy the name of description
100
     * attribute. If this attribute is assigned to false, this feature will be
101
     * skipped.
102
     */
103
    public $descriptionAttribute = false;
104
105
    /**
106
     * @var string
107
     */
108
    public $initDescription = '';
109
110
    /**
111
     * @var string the attribute that will receive current user ID value. This
112
     * attribute must be assigned.
113
     */
114
    public $createdByAttribute = "user_guid";
115
116
    /**
117
     * @var string the attribute that will receive current user ID value.
118
     * Set this property to false if you do not want to record the updater ID.
119
     */
120
    public $updatedByAttribute = "user_guid";
121
122
    /**
123
     * @var boolean Add combinated unique rule if assigned to true.
124
     */
125
    public $idCreatorCombinatedUnique = true;
126
127
    /**
128
     * @var boolean|string The name of user class which own the current entity.
129
     * If this attribute is assigned to false, this feature will be skipped, and
130
     * when you use create() method of UserTrait, it will be assigned with
131
     * current user class.
132
     */
133
    public $userClass;
134
    public static $cacheKeyBlameableRules = 'blameable_rules';
135
    public static $cacheTagBlameableRules = 'tag_blameable_rules';
136
    public static $cacheKeyBlameableBehaviors = 'blameable_behaviors';
137
    public static $cacheTagBlameableBehaviors = 'tag_blameable_behaviors';
138
139
    /**
140
     * @inheritdoc
141
     */
142 37
    public function rules()
143
    {
144 37
        return $this->getBlameableRules();
145
    }
146
147
    /**
148
     * @inheritdoc
149
     */
150 37
    public function behaviors()
151
    {
152 37
        return $this->getBlameableBehaviors();
153
    }
154
155
    /**
156
     * Get total of contents which owned by their owner.
157
     * @return integer
158
     */
159 2
    public function countOfOwner()
160
    {
161 2
        $createdByAttribute = $this->createdByAttribute;
162 2
        return static::find()->where([$createdByAttribute => $this->$createdByAttribute])->count();
163
    }
164
165
    /**
166
     * Get content.
167
     * @return mixed
168
     */
169
    public function getContent()
170
    {
171
        $contentAttribute = $this->contentAttribute;
172
        if ($contentAttribute === false) {
173
            return null;
174
        }
175
        if (is_array($contentAttribute)) {
176
            $content = [];
177
            foreach ($contentAttribute as $key => $value) {
178
                $content[$key] = $this->$value;
179
            }
180
            return $content;
181
        }
182
        return $this->$contentAttribute;
183
    }
184
185
    /**
186
     * Set content.
187
     * @param mixed $content
188
     */
189
    public function setContent($content)
190
    {
191
        $contentAttribute = $this->contentAttribute;
192
        if ($contentAttribute === false) {
193
            return;
194
        }
195
        if (is_array($contentAttribute)) {
196
            foreach ($contentAttribute as $key => $value) {
197
                $this->$value = $content[$key];
198
            }
199
            return;
200
        }
201
        $this->$contentAttribute = $content;
202
    }
203
204
    /**
205
     * Determines whether content could be edited. Your should implement this
206
     * method by yourself.
207
     * @return boolean
208
     * @throws \yii\base\NotSupportedException
209
     */
210
    public function getContentCanBeEdited()
211
    {
212
        if ($this->contentAttribute === false) {
213
            return false;
214
        }
215
        throw new \yii\base\NotSupportedException("This method is not implemented.");
216
    }
217
218
    /**
219
     * Check it has been ever edited.
220
     * @return boolean Whether this content has ever been edited.
221
     */
222
    public function hasEverEdited()
223
    {
224
        $createdAtAttribute = $this->createdByAttribute;
225
        $updatedAtAttribute = $this->updatedByAttribute;
226
        if (!$createdAtAttribute || !$updatedAtAttribute) {
227
            return false;
228
        }
229
        return $this->$createdAtAttribute === $this->$updatedAtAttribute;
230
    }
231
232
    /**
233
     * Get blameable rules cache key.
234
     * @return string cache key.
235
     */
236 37
    public function getBlameableRulesCacheKey()
237
    {
238 37
        return static::className() . $this->cachePrefix . static::$cacheKeyBlameableRules;
0 ignored issues
show
Bug introduced by
The property cachePrefix does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
239
    }
240
241
    /**
242
     * Get blameable rules cache tag.
243
     * @return string cache tag
244
     */
245 13
    public function getBlameableRulesCacheTag()
246
    {
247 13
        return static::className() . $this->cachePrefix . static::$cacheTagBlameableRules;
248
    }
249
250
    /**
251
     * Get the rules associated with content to be blamed.
252
     * @return array rules.
253
     */
254 37
    public function getBlameableRules()
255
    {
256 37
        $cache = $this->getCache();
0 ignored issues
show
Bug introduced by
It seems like getCache() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
257 37
        if ($cache) {
258 37
            $this->blameableLocalRules = $cache->get($this->getBlameableRulesCacheKey());
259 37
        }
260
        // 若当前规则不为空,且是数组,则认为是规则数组,直接返回。
261 37
        if (!empty($this->blameableLocalRules) && is_array($this->blameableLocalRules)) {
262 30
            return $this->blameableLocalRules;
263
        }
264
265
        // 父类规则与确认规则合并。
266 13
        if ($cache) {
267 13
            TagDependency::invalidate($cache, [$this->getEntityRulesCacheTag()]);
0 ignored issues
show
Bug introduced by
It seems like getEntityRulesCacheTag() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
268 13
        }
269 13
        $rules = array_merge(
270 13
            parent::rules(),
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (rules() instead of getBlameableRules()). Are you sure this is correct? If so, you might want to change this to $this->rules().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
271 13
            $this->getConfirmationRules(),
272 13
            $this->getBlameableAttributeRules(),
273 13
            $this->getDescriptionRules(),
274 13
            $this->getContentRules(),
275 13
            $this->getSelfBlameableRules()
276 13
        );
277 13
        $this->setBlameableRules($rules);
278 13
        return $this->blameableLocalRules;
279
    }
280
281
    /**
282
     * Get the rules associated with `createdByAttribute`, `updatedByAttribute`
283
     * and `idAttribute`-`createdByAttribute` combination unique.
284
     * @return array rules.
285
     */
286 13
    public function getBlameableAttributeRules()
287
    {
288 13
        $rules = [];
289
        // 创建者和上次修改者由 BlameableBehavior 负责,因此标记为安全。
290 13
        if (!is_string($this->createdByAttribute) || empty($this->createdByAttribute)) {
291
            throw new \yii\base\NotSupportedException('You must assign the creator.');
292
        }
293 13
        $rules[] = [
294 13
            [$this->createdByAttribute],
295 13
            'safe',
296
        ];
297
298 13
        if (is_string($this->updatedByAttribute) && !empty($this->updatedByAttribute)) {
299 3
            $rules[] = [
300 3
                [$this->updatedByAttribute],
301 3
                'safe',
302
            ];
303 3
        }
304
305 13
        if ($this->idCreatorCombinatedUnique && is_string($this->idAttribute)) {
0 ignored issues
show
Bug introduced by
The property idAttribute does not seem to exist. Did you mean refIdAttribute?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
306 12
            $rules [] = [
307 12
                [$this->idAttribute,
0 ignored issues
show
Bug introduced by
The property idAttribute does not seem to exist. Did you mean refIdAttribute?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
308 12
                    $this->createdByAttribute],
309 12
                'unique',
310 12
                'targetAttribute' => [$this->idAttribute,
0 ignored issues
show
Bug introduced by
The property idAttribute does not seem to exist. Did you mean refIdAttribute?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
311 12
                    $this->createdByAttribute],
312
            ];
313 12
        }
314 13
        return $rules;
315
    }
316
317
    /**
318
     * Get the rules associated with `description` attribute.
319
     * @return array rules.
320
     */
321 13
    public function getDescriptionRules()
322
    {
323 13
        $rules = [];
324 13
        if (is_string($this->descriptionAttribute) && !empty($this->descriptionAttribute)) {
325 1
            $rules[] = [
326 1
                [$this->descriptionAttribute],
327
                'string'
328 1
            ];
329 1
            $rules[] = [
330 1
                [$this->descriptionAttribute],
331 1
                'default',
332 1
                'value' => $this->initDescription,
333
            ];
334 1
        }
335 13
        return $rules;
336
    }
337
338
    /**
339
     * Get the rules associated with `content` and `contentType` attributes.
340
     * @return array rules.
341
     */
342 13
    public function getContentRules()
343
    {
344 13
        if (!$this->contentAttribute) {
345 2
            return [];
346
        }
347 11
        $rules = [];
348 11
        $rules[] = [[
349 11
            $this->contentAttribute],
350 11
            'required'];
351 11
        if ($this->contentAttributeRule) {
352 11
            if (is_string($this->contentAttributeRule)) {
353
                $this->contentAttributeRule = [$this->contentAttributeRule];
354
            }
355 11
            if (is_array($this->contentAttributeRule)) {
356 11
                $rules[] = array_merge([$this->contentAttribute], $this->contentAttributeRule);
357 11
            }
358 11
        }
359
360 11
        if (!$this->contentTypeAttribute) {
361 9
            return $rules;
362
        }
363
364 2
        if (is_array($this->contentTypes) && !empty($this->contentTypes)) {
365 2
            $rules[] = [[
366 2
                $this->contentTypeAttribute],
367 2
                'required'];
368 2
            $rules[] = [[
369 2
                $this->contentTypeAttribute],
370 2
                'in',
371 2
                'range' => array_keys($this->contentTypes)];
372 2
        }
373 2
        return $rules;
374
    }
375
376
    /**
377
     * Set blameable rules.
378
     * @param array $rules
379
     */
380 13
    protected function setBlameableRules($rules = [])
381
    {
382 13
        $this->blameableLocalRules = $rules;
383 13
        $cache = $this->getCache();
0 ignored issues
show
Bug introduced by
It seems like getCache() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
384 13
        if ($cache) {
385 13
            $tagDependency = new \yii\caching\TagDependency(['tags' => [$this->getBlameableRulesCacheTag()]]);
386 13
            $cache->set($this->getBlameableRulesCacheKey(), $rules, 0, $tagDependency);
387 13
        }
388 13
    }
389
390
    /**
391
     * Get blameable behaviors cache key.
392
     * @return string cache key.
393
     */
394 37
    public function getBlameableBehaviorsCacheKey()
395
    {
396 37
        return static::className() . $this->cachePrefix . static::$cacheKeyBlameableBehaviors;
397
    }
398
399
    /**
400
     * Get blameable behaviors cache tag.
401
     * @return string cache tag.
402
     */
403 13
    public function getBlameableBehaviorsCacheTag()
404
    {
405 13
        return static::className() . $this->cachePrefix . static::$cacheTagBlameableBehaviors;
406
    }
407
408
    /**
409
     * Get blameable behaviors. If current behaviors array is empty, the init
410
     * array will be given.
411
     * @return array
412
     */
413 37
    public function getBlameableBehaviors()
414
    {
415 37
        $cache = $this->getCache();
0 ignored issues
show
Bug introduced by
It seems like getCache() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
416 37
        if ($cache) {
417 37
            $this->blameableLocalBehaviors = $cache->get($this->getBlameableBehaviorsCacheKey());
418 37
        }
419 37
        if (empty($this->blameableLocalBehaviors) || !is_array($this->blameableLocalBehaviors)) {
420 13
            if ($cache) {
421 13
                TagDependency::invalidate($cache, [$this->getEntityBehaviorsCacheTag()]);
0 ignored issues
show
Bug introduced by
The method getEntityBehaviorsCacheTag() does not exist on vistart\Models\traits\BlameableTrait. Did you maybe mean behaviors()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
422 13
            }
423 13
            $behaviors = parent::behaviors();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (behaviors() instead of getBlameableBehaviors()). Are you sure this is correct? If so, you might want to change this to $this->behaviors().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
424 13
            $behaviors['blameable'] = [
425 13
                'class' => BlameableBehavior::className(),
426 13
                'createdByAttribute' => $this->createdByAttribute,
427 13
                'updatedByAttribute' => $this->updatedByAttribute,
428 13
                'value' => [$this,
429 13
                    'onGetCurrentUserGuid'],
430
            ];
431 13
            $this->setBlameableBehaviors($behaviors);
432 13
        }
433 37
        return $this->blameableLocalBehaviors;
434
    }
435
436
    /**
437
     * Set blameable behaviors.
438
     * @param array $behaviors
439
     */
440 13
    protected function setBlameableBehaviors($behaviors = [])
441
    {
442 13
        $this->blameableLocalBehaviors = $behaviors;
443 13
        $cache = $this->getCache();
0 ignored issues
show
Bug introduced by
It seems like getCache() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
444 13
        if ($cache) {
445 13
            $tagDependencyConfig = ['tags' => [$this->getBlameableBehaviorsCacheTag()]];
446 13
            $tagDependency = new \yii\caching\TagDependency($tagDependencyConfig);
447 13
            $cache->set($this->getBlameableBehaviorsCacheKey(), $behaviors, 0, $tagDependency);
448 13
        }
449 13
    }
450
451
    /**
452
     * Set description.
453
     * @return string description.
454
     */
455
    public function getDescription()
456
    {
457
        $descAttribute = $this->descriptionAttribute;
458
        return is_string($descAttribute) ? $this->$descAttribute : null;
459
    }
460
461
    /**
462
     * Get description.
463
     * @param string $desc description.
464
     * @return string|null description if enabled, or null if disabled.
465
     */
466
    public function setDescription($desc)
467
    {
468
        $descAttribute = $this->descriptionAttribute;
469
        return is_string($descAttribute) ? $this->$descAttribute = $desc : null;
470
    }
471
472
    /**
473
     * Get blame who owned this blameable model.
474
     * NOTICE! This method will not check whether `$userClass` exists. You should
475
     * specify it in `init()` method.
476
     * @return \vistart\Models\queries\BaseUserQuery user.
477
     */
478 1
    public function getUser()
479
    {
480 1
        $userClass = $this->userClass;
481 1
        $model = $userClass::buildNoInitModel();
482 1
        return $this->hasOne($userClass::className(), [$model->guidAttribute => $this->createdByAttribute]);
0 ignored issues
show
Bug introduced by
It seems like hasOne() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
483
    }
484
485
    /**
486
     * Get updater who updated this blameable model recently.
487
     * NOTICE! This method will not check whether `$userClass` exists. You should
488
     * specify it in `init()` method.
489
     * @return \vistart\Models\queries\BaseUserQuery user.
490
     */
491 1
    public function getUpdater()
492
    {
493 1
        if (!is_string($this->updatedByAttribute)) {
494 1
            return null;
495
        }
496
        $userClass = $this->userClass;
497
        $model = $userClass::buildNoInitModel();
498
        return $this->hasOne($userClass::className(), [$model->guidAttribute => $this->updatedByAttribute]);
0 ignored issues
show
Bug introduced by
It seems like hasOne() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
499
    }
500
501
    /**
502
     * This event is triggered before the model update.
503
     * This method is ONLY used for being triggered by event. DO NOT call,
504
     * override or modify it directly, unless you know the consequences.
505
     * @param \yii\base\Event $event
506
     */
507 11
    public function onContentChanged($event)
508
    {
509 11
        $sender = $event->sender;
510 11
        $sender->resetConfirmation();
511 11
    }
512
513
    /**
514
     * Return the current user's GUID if current model doesn't specify the owner
515
     * yet, or return the owner's GUID if current model has been specified.
516
     * This method is ONLY used for being triggered by event. DO NOT call,
517
     * override or modify it directly, unless you know the consequences.
518
     * @param \yii\base\Event $event
519
     * @return string the GUID of current user or the owner.
520
     */
521 37
    public function onGetCurrentUserGuid($event)
522
    {
523 37
        $sender = $event->sender;
524 37
        if (isset($sender->attributes[$sender->createdByAttribute])) {
525 37
            return $sender->attributes[$sender->createdByAttribute];
526
        }
527
        $identity = \Yii::$app->user->identity;
528
        if ($identity) {
529
            $igAttribute = $identity->guidAttribute;
530
            return $identity->$igAttribute;
531
        }
532
    }
533
534
    /**
535
     * Initialize type of content. the first of element[index is 0] of
536
     * $contentTypes will be used.
537
     * @param \yii\base\Event $event
538
     */
539 36
    public function onInitContentType($event)
540
    {
541 36
        $sender = $event->sender;
542 36
        if (!isset($sender->contentTypeAttribute) || !is_string($sender->contentTypeAttribute)) {
543 29
            return;
544
        }
545 7
        $contentTypeAttribute = $sender->contentTypeAttribute;
546 7
        if (!isset($sender->$contentTypeAttribute) &&
547 7
            !empty($sender->contentTypes) &&
548 7
            is_array($sender->contentTypes)) {
549 7
            $sender->$contentTypeAttribute = $sender->contentTypes[0];
550 7
        }
551 7
    }
552
553
    /**
554
     * Initialize description property with $initDescription.
555
     * @param \yii\base\Event $event
556
     */
557 37
    public function onInitDescription($event)
558
    {
559 37
        $sender = $event->sender;
560 37
        if (!isset($sender->descriptionAttribute) || !is_string($sender->descriptionAttribute)) {
561 31
            return;
562
        }
563 6
        $descriptionAttribute = $sender->descriptionAttribute;
564 6
        if (empty($sender->$descriptionAttribute)) {
565 6
            $sender->$descriptionAttribute = $sender->initDescription;
566 6
        }
567 6
    }
568
569
    /**
570
     * Attach events associated with blameable model.
571
     */
572 37
    public function initBlameableEvents()
573
    {
574 37
        $this->on(static::$eventConfirmationChanged, [$this, "onConfirmationChanged"]);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
575 37
        $this->on(static::$eventNewRecordCreated, [$this, "onInitConfirmation"]);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
576 37
        $contentTypeAttribute = $this->contentTypeAttribute;
577 37
        if (!isset($this->$contentTypeAttribute)) {
578 36
            $this->on(static::$eventNewRecordCreated, [$this, "onInitContentType"]);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
579 36
        }
580 37
        $descriptionAttribute = $this->descriptionAttribute;
581 37
        if (!isset($this->$descriptionAttribute)) {
582 37
            $this->on(static::$eventNewRecordCreated, [$this, 'onInitDescription']);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
583 37
        }
584 37
        $this->on(static::EVENT_BEFORE_UPDATE, [$this, "onContentChanged"]);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
585 37
        $this->initSelfBlameableEvents();
586 37
    }
587
588
    /**
589
     * @inheritdoc
590
     */
591 11
    public function enabledFields()
592
    {
593 11
        $fields = parent::enabledFields();
594 11
        if (is_string($this->createdByAttribute)) {
595 11
            $fields[] = $this->createdByAttribute;
596 11
        }
597 11
        if (is_string($this->updatedByAttribute)) {
598 2
            $fields[] = $this->updatedByAttribute;
599 2
        }
600 11
        if (is_string($this->contentAttribute)) {
601 11
            $fields[] = $this->contentAttribute;
602 11
        }
603 11
        if (is_array($this->contentAttribute)) {
604
            $fields = array_merge($fields, $this->contentAttribute);
605
        }
606 11
        if (is_string($this->descriptionAttribute)) {
607
            $fields[] = $this->descriptionAttribute;
608
        }
609 11
        if (is_string($this->confirmationAttribute)) {
610
            $fields[] = $this->confirmationAttribute;
611
        }
612 11
        if (is_string($this->parentAttribute)) {
613
            $fields[] = $this->parentAttribute;
614
        }
615 11
        return $fields;
616
    }
617
}
618