Passed
Push — master ( ef2d88...898186 )
by Arthur
06:43
created

ModelCacheOOP::getCacheTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: arthur
5
 * Date: 11.10.18
6
 * Time: 14:11.
7
 */
8
9
namespace Foundation\Cache;
10
11
use Cache;
12
use Foundation\Exceptions\Exception;
13
use Illuminate\Support\Facades\Redis;
14
15
class ModelCacheOOP
16
{
17
    protected $model;
18
19
    protected $cacheTime;
20
21
    /* Unique secondary indexes */
22
    protected $secondaryIndexes;
23
24
    /**
25
     * ModelCacheOOP constructor.
26
     */
27
    public function __construct(string $model, array $indexes = array(), $cacheTime = null)
28
    {
29
        $this->model = $model;
30
        $this->secondaryIndexes = $indexes;
31
        $this->cacheTime = $cacheTime;
32
    }
33
34
    /**
35
     * @param $id
36
     * @param string $modelClass
37
     *
38
     * @return \Eloquent
39
     */
40
    public function find($id, $eagerLoad = true)
41
    {
42
        $model = Cache::get(self::getCacheName($id));
0 ignored issues
show
Bug Best Practice introduced by
The method Foundation\Cache\ModelCacheOOP::getCacheName() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

42
        $model = Cache::get(self::/** @scrutinizer ignore-call */ getCacheName($id));
Loading history...
43
44
        if ($eagerLoad)
45
            return $this->eagerLoadRelations($model);
46
47
        return $model;
48
    }
49
50
    public function findBy(string $index, $key, $eagerLoad = true)
51
    {
52
        if (!in_array($index, $this->secondaryIndexes)) {
53
            throw new Exception('provided index does not exist as secondary index on the cache model');
54
        }
55
        $modelId = $this->findSecondaryIndex($index, $key);
56
57
        if ($modelId === null)
58
            return ($this->model)::where($index, $key)->first();
59
        return $this->find($modelId, $eagerLoad);
60
    }
61
62
    protected function eagerLoadRelations($model)
63
    {
64
        if ($model !== null)
65
            return $model::eagerLoadRelations(array($model))[0];
66
        return null;
67
    }
68
69
    protected function findSecondaryIndex(string $index, $key)
70
    {
71
        return Cache::get($this->getCacheName($key, $index));
72
    }
73
74
    /**
75
     * @param string
76
     */
77
    public function getCacheName($id, string $index = 'id')
78
    {
79
        return config('model.cache_prefix') . ':' . strtolower(get_short_class_name($this->model)) . ':' . $index . ':' . $id;
80
    }
81
82
    /**
83
     * @return \Illuminate\Config\Repository|mixed
84
     */
85
    public function getCacheTime()
86
    {
87
        return $this->cacheTime ?? config('model.cache_time');
88
    }
89
90
    /**
91
     * @param \Eloquent $model
92
     */
93
    public function store($model)
94
    {
95
        Cache::put($this->getCacheName($model->getKey()), $model->newFromBuilder($model->getAttributes()), $this->getCacheTime());
96
        $this->storeSecondaryIndexReferences($model);
97
    }
98
99
    /**
100
     * @param string $index
101
     * @param \Eloquent $model
102
     */
103
    protected function storeSecondaryIndexReferences($model)
104
    {
105
        foreach ($this->secondaryIndexes as $index) {
106
            $indexValue = $model->$index;
107
            if ($indexValue !== null)
108
                Cache::put($this->getCacheName($indexValue, $index), $model->getKey(), $this->getCacheTime());
109
        }
110
    }
111
112
    /**
113
     * @param $id
114
     * @param string $modelClass
115
     *
116
     * @return bool
117
     */
118
    public function remove($id)
119
    {
120
        return Cache::forget($this->getCacheName($id));
121
    }
122
123
    public static function clearAll()
124
    {
125
        $pattern = config('model.cache_prefix');
126
        self::deleteWithPrefix($pattern);
127
    }
128
129
    /**
130
     * @param $prefix
131
     *
132
     * @throws Exception
133
     */
134
    private static function deleteWithPrefix($prefix)
135
    {
136
        $redis = self::getCacheConnection();
137
        $keyPattern = Cache::getPrefix() . $prefix . '*';
0 ignored issues
show
Bug introduced by
The call to Illuminate\Cache\CacheManager::getPrefix() has too few arguments starting with config. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

137
        $keyPattern = Cache::/** @scrutinizer ignore-call */ getPrefix() . $prefix . '*';

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
138
        $keys = $redis->keys($keyPattern);
139
        $redis->delete($keys);
140
    }
141
142
    /**
143
     * @throws Exception
144
     *
145
     * @return \Illuminate\Redis\Connections\Connection
146
     */
147
    private static function getCacheConnection()
148
    {
149
        if (config('cache.default') === 'redis') {
150
            return Redis::connection('cache');
151
        }
152
153
        throw new Exception('This action is only possible with redis as cache driver');
154
    }
155
156
    /**
157
     * @param $modelClass
158
     *
159
     * @throws Exception
160
     */
161
    public function clearModelCache()
162
    {
163
        $pattern = config('model.cache_prefix') . ':' . strtolower(get_short_class_name($this->model));
164
        self::deleteWithPrefix($pattern);
165
    }
166
167
    public function enabled(): bool
168
    {
169
        return (bool)config('model.caching');
170
    }
171
}
172