Test Setup Failed
Pull Request — master (#12)
by Carlos
02:21
created

Versionable::getVersionModel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the overtrue/laravel-versionable.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled.
9
 */
10
11
namespace Overtrue\LaravelVersionable;
12
13
use Illuminate\Database\Eloquent\Model;
14
use Illuminate\Database\Eloquent\Relations\MorphMany;
15
use Illuminate\Database\Eloquent\Relations\MorphOne;
16
17
trait Versionable
18
{
19
    static protected $versioning = true;
20
    protected bool $forceDeleteVersion = false;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
21
22
    // You can add these properties to you versionable model
23
    //protected $versionable = [];
24
    //protected $dontVersionable = ['*'];
25 6
26
    public static function bootVersionable()
27
    {
28 6
        static::saved(function (Model $model) {
29 6
            self::createVersionForModel($model);
30
        });
31
32
        static::deleted(function (Model $model) {
33
            if ($model->forceDeleting) {
34
                $model->forceRemoveAllVersions();
35
            } else {
36
                self::createVersionForModel($model);
37 6
            }
38 6
        });
39
    }
40 6
41
    private static function createVersionForModel(Model $model): void
42 6
    {
43 6
        if (self::$versioning && $model->shouldVersioning()) {
44 6
            Version::createForModel($model);
45
            $model->removeOldVersions($model->getKeepVersionsCount());
46 6
        }
47
    }
48
49
    /**
50
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
51 6
     */
52
    public function versions(): MorphMany
53 6
    {
54
        return $this->morphMany(\config('versionable.version_model'), 'versionable')->latest('id');
55
    }
56
57
    /**
58
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
59 4
     */
60
    public function lastVersion(): MorphOne
61 4
    {
62
        return $this->morphOne(\config('versionable.version_model'), 'versionable')->latest('id');
63
    }
64
65
    public function forceDeleteEnable(): self
66
    {
67
        $this->forceDeleteVersion = true;
68
69 1
        return $this;
70
    }
71 1
72
    public function forceDeleteDisable(): self
73
    {
74
        $this->forceDeleteVersion = false;
75
76
        return $this;
77
    }
78
    /**
79 1
     * @param int $id
80
     *
81 1
     * @return \Illuminate\Database\Eloquent\Model|null
82
     */
83
    public function getVersion(int $id)
84
    {
85
        return $this->versions()->find($id);
86
    }
87 6
88
    public function getThrashedVersions()
89 6
    {
90 5
        return $this->versions()->onlyTrashed()->get();
91
    }
92
93 1
    public function restoreThrashedVersion(int $id)
94 1
    {
95
        return $this->versions()->onlyTrashed()->whereId($id)->restore();
96 1
    }
97
98 1
    /**
99 1
     * @param int $id
100
     *
101
     * @return mixed
102
     */
103
    public function revertToVersion(int $id)
104 6
    {
105
        return $this->versions()->findOrFail($id)->revert();
106 6
    }
107
108
    /**
109
     * @param int $keep
110
     */
111
    public function removeOldVersions(int $keep): void
112 6
    {
113
        if ($keep <= 0) {
114 6
            return;
115
        }
116 6
117
        $this->versions()->skip($keep)->take(PHP_INT_MAX)->get()->each->delete();
118
    }
119
120 6
    public function removeVersions(array $ids)
121 6
    {
122 6
        if ($this->forceDeleteVersion) {
123 6
            return $this->forceRemoveVersions($ids);
124 1
        }
125 1
126 1
        return $this->versions()->find($ids)->each->delete();
127
    }
128
129
    public function removeVersion(int $id)
130
    {
131 6
        if ($this->forceDeleteVersion) {
132
            return $this->forceRemoveVersion($id);
133
        }
134
135
        return $this->versions()->findOrFail($id)->delete();
136
    }
137
138
    public function removeAllVersions()
139
    {
140
        if ($this->forceDeleteVersion) {
141
            $this->forceRemoveAllVersions();
142
        }
143
144
        $this->versions->each->delete();
145
    }
146
147
    public function forceRemoveVersion(int $id)
148
    {
149
        return $this->versions()->findOrFail($id)->forceDelete();
150
    }
151
152
    public function forceRemoveVersions(array $ids)
153
    {
154
        return $this->versions()->find($ids)->each->forceDelete();
155
    }
156
157
    public function forceRemoveAllVersions()
158
    {
159
        $this->versions->each->forceDelete();
160
    }
161
162
    /**
163
     * @return bool
164
     */
165
    public function shouldVersioning(): bool
166
    {
167
        return !empty($this->getVersionableAttributes());
168
    }
169
170
    /**
171
     * @return array
172
     */
173 6
    public function getVersionableAttributes(): array
174
    {
175 6
        $changes = $this->getDirty();
176
177
        if (empty($changes)) {
178
            return [];
179
        }
180
181
        switch ($this->getVersionStrategy()) {
182
            case VersionStrategy::DIFF:
183
                $contents = $changes;
184
                break;
185
            case VersionStrategy::SNAPSHOT:
186
                $contents = $this->attributesToArray();
187
                break;
188
            default:
189 6
                $contents = $changes;
190
        }
191 6
192
        return $this->versionableFromArray($contents);
193
    }
194
195
    /**
196
     * @param array $attributes
197
     *
198
     * @return $this
199
     *
200
     * @throws \Exception
201 1
     */
202
    public function setVersionable(array $attributes)
203 1
    {
204
        if (!\property_exists($this, 'versionable')) {
205
            throw new \Exception('Property $versionable not exist.');
206
        }
207 1
208
        $this->versionable = $attributes;
209 1
210
        return $this;
211
    }
212
213
    /**
214
     * @param array $attributes
215 6
     *
216
     * @return $this
217 6
     *
218
     * @throws \Exception
219
     */
220
    public function setDontVersionable(array $attributes)
221
    {
222
        if (!\property_exists($this, 'dontVersionable')) {
223 6
            throw new \Exception('Property $dontVersionable not exist.');
224
        }
225 6
226
        $this->dontVersionable = $attributes;
227
228
        return $this;
229
    }
230
231
    /**
232
     * @return array
233
     */
234
    public function getVersionable(): array
235 6
    {
236
        return \property_exists($this, 'versionable') ? $this->versionable : [];
237 6
    }
238 6
239
    /**
240
     * @return array
241
     */
242
    public function getDontVersionable(): array
243
    {
244
        return \property_exists($this, 'dontVersionable') ? $this->dontVersionable : [];
245
    }
246
247
    /**
248
     * @return string
249
     */
250
    public function getVersionStrategy()
251 1
    {
252
        return \property_exists($this, 'versionStrategy') ? $this->versionStrategy : VersionStrategy::DIFF;
253 1
    }
254
255 1
    /**
256
     * @param string $strategy
257 1
     *
258 1
     * @return $this
259
     *
260
     * @throws \Exception
261
     */
262
    public function setVersionStrategy(string $strategy)
263
    {
264
        if (!\property_exists($this, 'versionStrategy')) {
265
            throw new \Exception('Property $versionStrategy not exist.');
266
        }
267
268
        $this->versionStrategy = $strategy;
269
270
        return $this;
271
    }
272
273
    /**
274
     * @return string
275
     */
276
    public function getVersionModel(): string
277
    {
278
        return config('versionable.version_model');
279
    }
280
281
    /**
282
     * @return string
283
     */
284
    public function getKeepVersionsCount(): string
285
    {
286
        return config('versionable.keep_versions', 0);
287
    }
288
289
    /**
290
     * Get the versionable attributes of a given array.
291
     *
292
     * @param array $attributes
293
     *
294
     * @return array
295
     */
296
    public function versionableFromArray(array $attributes): array
297
    {
298
        if (count($this->getVersionable()) > 0) {
299
            return \array_intersect_key($attributes, array_flip($this->getVersionable()));
300
        }
301
302
        if (count($this->getDontVersionable()) > 0) {
303
            return \array_diff_key($attributes, array_flip($this->getDontVersionable()));
304
        }
305
306
        return $attributes;
307
    }
308
309
    /**
310
     * @param callable $callback
311
     */
312
    public static function withoutVersion(callable $callback)
313
    {
314
        self::$versioning = false;
315
316
        \call_user_func($callback);
317
318
        self::$versioning = true;
319
    }
320
}
321