Completed
Push — master ( 2abe6c...da21df )
by Brett
02:01
created

CacheBehavior::clearCache()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 22
rs 6.9811
cc 7
eloc 12
nc 16
nop 1
1
<?php
2
/**
3
 * @author Brett O'Donnell <[email protected]>
4
 * @copyright 2016 Mr PHP
5
 * @link https://github.com/cornernote/yii2-cache-behavior
6
 * @license BSD-3-Clause https://raw.github.com/cornernote/yii2-cache-behavior/master/LICENSE.md
7
 */
8
9
namespace cornernote\cachebehavior;
10
11
use Yii;
12
use yii\base\Behavior;
13
use yii\base\Event;
14
use yii\db\BaseActiveRecord;
15
16
/**
17
 * CacheBehavior
18
 *
19
 * @usage:
20
 * ```
21
 * public function behaviors() {
22
 *     return [
23
 *         [
24
 *             'class' => 'cornernote\cachebehavior\CacheBehavior',
25
 *         ],
26
 *     ];
27
 * }
28
 * ```
29
 *
30
 * @property BaseActiveRecord $owner
31
 * @property string $cacheKeyPrefixName
32
 *
33
 */
34
class CacheBehavior extends Behavior
35
{
36
    /**
37
     * The cache component to use.
38
     *
39
     * @var string
40
     */
41
    public $cache = 'cache';
42
43
    /**
44
     * A backup cache component to use.
45
     * For example if your main cache is MemCache then you may want to use
46
     * FileCache or DbCache as a backup cache storage.
47
     *
48
     * @var bool
49
     */
50
    public $backupCache = false;
51
52
    /**
53
     * The relations to clear cache when this models cache is cleared.
54
     *
55
     * @var array
56
     */
57
    public $cacheRelations = [];
58
59
    /**
60
     * Unique md5 for this model.
61
     *
62
     * @var string
63
     */
64
    private $_cacheKeyPrefixName;
65
66
    /**
67
     * Models that have already been cleared.
68
     *
69
     * @var array
70
     */
71
    private $_cleared = [];
72
73
    /**
74
     * @inheritdoc
75
     */
76
    public function events()
77
    {
78
        return [
79
            BaseActiveRecord::EVENT_AFTER_INSERT => 'clearCacheEvent',
80
            BaseActiveRecord::EVENT_AFTER_UPDATE => 'clearCacheEvent',
81
            BaseActiveRecord::EVENT_AFTER_DELETE => 'clearCacheEvent',
82
        ];
83
    }
84
85
    /**
86
     * Event to clear cache.
87
     *
88
     * @param Event $event
89
     */
90
    public function clearCacheEvent($event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
    {
92
        $this->clearCache();
93
    }
94
95
    /**
96
     * Get a cached value.
97
     *
98
     * @param string $key
99
     * @param bool $useBackupCache
100
     * @return mixed
101
     */
102
    public function getCache($key, $useBackupCache = false)
103
    {
104
        $fullKey = $this->getCacheKeyPrefix() . '.' . $key;
105
        $value = Yii::$app->{$this->cache}->get($fullKey);
106
        if (!$value && $useBackupCache && $this->backupCache) {
107
            $value = Yii::$app->{$this->backupCache}->get($fullKey);
108
        }
109
        return $value;
110
    }
111
112
    /**
113
     * Set a cached value.
114
     *
115
     * @param string $key
116
     * @param mixed $value
117
     * @param bool $useBackupCache
118
     * @return mixed
119
     */
120
    public function setCache($key, $value, $useBackupCache = false)
121
    {
122
        $fullKey = $this->getCacheKeyPrefix() . '.' . $key;
123
        Yii::$app->{$this->cache}->set($fullKey, $value);
124
        if ($useBackupCache && $this->backupCache) {
125
            Yii::$app->{$this->backupCache}->set($fullKey, $value);
126
        }
127
        return $value;
128
    }
129
130
    /**
131
     * Clear cache for model and relations.
132
     *
133
     * @param bool $resetCleared
134
     */
135
    public function clearCache($resetCleared = true)
0 ignored issues
show
Unused Code introduced by
The parameter $resetCleared is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
136
    {
137
        // check for recursion
138
        if ($reset) {
0 ignored issues
show
Bug introduced by
The variable $reset does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
139
            $this->_cleared = [];
140
        }
141
        if (isset($this->_cleared[$this->cacheKeyPrefixName])) {
142
            return;
143
        }
144
        $this->_cleared[$this->cacheKeyPrefixName] = true;
145
        // clear related cache
146
        foreach ($this->cacheRelations as $cacheRelation) {
147
            $models = is_array($this->owner->$cacheRelation) ? $this->owner->$cacheRelation : [$this->owner->$cacheRelation];
148
            foreach ($models as $cacheRelationModel) {
149
                if ($cacheRelationModel instanceof BaseActiveRecord) {
150
                    $cacheRelationModel->clearCache(false);
151
                }
152
            }
153
        }
154
        // clear own cache
155
        $this->clearCacheKeyPrefix();
156
    }
157
158
    /**
159
     * Clear the cache prefix.
160
     *
161
     * @param null|string $cacheKeyPrefix
0 ignored issues
show
Bug introduced by
There is no parameter named $cacheKeyPrefix. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
162
     */
163
    private function clearCacheKeyPrefix()
164
    {
165
        Yii::$app->{$this->cache}->delete($this->cacheKeyPrefixName);
166
        if ($this->backupCache) {
167
            Yii::$app->{$this->backupCache}->delete($this->cacheKeyPrefixName);
168
        }
169
    }
170
171
    /**
172
     * Get the cache prefix.
173
     *
174
     * @return bool|string
175
     */
176
    private function getCacheKeyPrefix()
177
    {
178
        $cacheKeyPrefix = Yii::$app->{$this->cache}->get($this->cacheKeyPrefixName);
179
        if (!$cacheKeyPrefix && $this->backupCache) {
180
            $cacheKeyPrefix = Yii::$app->{$this->backupCache}->get($this->cacheKeyPrefixName);
181
        }
182
        if (!$cacheKeyPrefix) {
183
            $cacheKeyPrefix = uniqid();
184
            Yii::$app->{$this->cache}->set($this->cacheKeyPrefixName, $cacheKeyPrefix);
185
            if ($this->backupCache) {
186
                Yii::$app->{$this->backupCache}->set($this->cacheKeyPrefixName, $cacheKeyPrefix);
187
            }
188
        }
189
        return $cacheKeyPrefix;
190
    }
191
192
    /**
193
     * Get the cache prefix name.
194
     *
195
     * @return string
196
     */
197
    private function getCacheKeyPrefixName()
198
    {
199
        if (!$this->_cacheKeyPrefixName) {
200
            $owner = $this->owner;
201
            $pk = is_array($owner->getPrimaryKey()) ? implode('-', $owner->getPrimaryKey()) : $owner->getPrimaryKey();
202
            $this->_cacheKeyPrefixName = md5($owner->className() . '.getCacheKeyPrefix.' . $pk);
203
        }
204
        return $this->_cacheKeyPrefixName;
205
    }
206
207
}
208