Passed
Pull Request — master (#274)
by
unknown
02:36
created

ModelCaching::__set()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 2
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php namespace GeneaLabs\LaravelModelCaching\Traits;
2
3
use GeneaLabs\LaravelModelCaching\CachedBelongsToMany;
4
use GeneaLabs\LaravelModelCaching\CachedBuilder;
5
use Illuminate\Container\Container;
6
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9
use Illuminate\Support\Carbon;
10
11
trait ModelCaching
12
{
13
    public function __get($key)
14
    {
15
        if ($key === "cachePrefix") {
16
            return $this->cachePrefix
17
                ?? "";
18
        }
19
20
        if ($key === "cacheCooldownSeconds") {
21
            return $this->cacheCooldownSeconds
22
                ?? 0;
23
        }
24
25
        return parent::__get($key);
26
    }
27
28
    public function __set($key, $value)
29
    {
30
        if ($key === "cachePrefix") {
31
            $this->cachePrefix = $value;
32
        }
33
34
        if ($key === "cacheCooldownSeconds") {
35
            $this->cacheCooldownSeconds = $value;
36
        }
37
38
        parent::__set($key, $value);
39
    }
40
41
    public static function maxCacheTimeout()
42
    {
43
        return static::$maxCacheTimeout ?? 0;
0 ignored issues
show
Bug Best Practice introduced by
The property maxCacheTimeout does not exist on GeneaLabs\LaravelModelCaching\Traits\ModelCaching. Since you implemented __get, consider adding a @property annotation.
Loading history...
44
    }
45
46
    public static function all($columns = ['*'])
47
    {
48
        $isCacheDisabled = Container::getInstance()
49
            ->make("config")
50
            ->get("laravel-model-caching.disabled");
51
52
        if ($isCacheDisabled) {
53
            return parent::all($columns);
54
        }
55
56
        $class = get_called_class();
57
        $instance = new $class;
58
        $tags = $instance->makeCacheTags();
59
        $key = $instance->makeCacheKey();
60
61
        $cache_callback = function () use ($columns) {
62
            return parent::all($columns);
63
        };
64
65
        if (static::maxCacheTimeout() > 0) {
66
            return $instance->cache($tags)
67
                ->remember(
68
                    $key,
69
                    static::maxCacheTimeout(),
70
                    $cache_callback
71
                );
72
        }
73
74
        return $instance->cache($tags)
75
            ->rememberForever($key, $cache_callback);
76
    }
77
78
    public static function bootCachable()
79
    {
80
        static::created(function ($instance) {
81
            $instance->checkCooldownAndFlushAfterPersisting($instance);
82
        });
83
84
        static::deleted(function ($instance) {
85
            $instance->checkCooldownAndFlushAfterPersisting($instance);
86
        });
87
88
        static::saved(function ($instance) {
89
            $instance->checkCooldownAndFlushAfterPersisting($instance);
90
        });
91
92
        // TODO: figure out how to add this listener
93
        // static::restored(function ($instance) {
94
        //     $instance->checkCooldownAndFlushAfterPersisting($instance);
95
        // });
96
97
        static::pivotAttached(function ($instance, $secondInstance, $relationship) {
98
            $instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
99
        });
100
101
        static::pivotDetached(function ($instance, $secondInstance, $relationship) {
102
            $instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
103
        });
104
105
        static::pivotUpdated(function ($instance, $secondInstance, $relationship) {
106
            $instance->checkCooldownAndFlushAfterPersisting($instance, $relationship);
107
        });
108
    }
109
110
    public static function destroy($ids)
111
    {
112
        $class = get_called_class();
113
        $instance = new $class;
114
        $instance->flushCache();
115
116
        return parent::destroy($ids);
117
    }
118
119
    public function newEloquentBuilder($query)
120
    {
121
        if (! $this->isCachable()) {
122
            $this->isCachable = false;
123
124
            return new EloquentBuilder($query);
125
        }
126
127
        return new CachedBuilder($query);
128
    }
129
130
    protected function newBelongsToMany(
131
        EloquentBuilder $query,
132
        Model $parent,
133
        $table,
134
        $foreignPivotKey,
135
        $relatedPivotKey,
136
        $parentKey,
137
        $relatedKey,
138
        $relationName = null
139
    ) {
140
        if (method_exists($query->getModel(), "isCachable")
141
            && $query->getModel()->isCachable()
142
        ) {
143
            return new CachedBelongsToMany(
144
                $query,
145
                $parent,
146
                $table,
147
                $foreignPivotKey,
148
                $relatedPivotKey,
149
                $parentKey,
150
                $relatedKey,
151
                $relationName
152
            );
153
        }
154
155
        return new BelongsToMany(
156
            $query,
157
            $parent,
158
            $table,
159
            $foreignPivotKey,
160
            $relatedPivotKey,
161
            $parentKey,
162
            $relatedKey,
163
            $relationName
164
        );
165
    }
166
167
    public function scopeDisableCache(EloquentBuilder $query) : EloquentBuilder
168
    {
169
        if ($this->isCachable()) {
170
            $query = $query->disableModelCaching();
171
        }
172
173
        return $query;
174
    }
175
176
    public function scopeWithCacheCooldownSeconds(
177
        EloquentBuilder $query,
178
        int $seconds = null
179
    ) : EloquentBuilder {
180
        if (! $seconds) {
181
            $seconds = $this->cacheCooldownSeconds;
182
        }
183
184
        $cachePrefix = $this->getCachePrefix();
185
        $modelClassName = get_class($this);
186
        $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:seconds";
187
188
        $this->cache()
189
            ->rememberForever($cacheKey, function () use ($seconds) {
190
                return $seconds;
191
            });
192
193
        $cacheKey = "{$cachePrefix}:{$modelClassName}-cooldown:invalidated-at";
194
        $this->cache()
195
            ->rememberForever($cacheKey, function () {
196
                return (new Carbon)->now();
197
            });
198
199
        return $query;
200
    }
201
}
202