Completed
Pull Request — master (#5)
by Lucas
35:54 queued 27:56
created

GeneratesUuid::bootGeneratesUuid()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 6
nc 1
nop 0
crap 4
1
<?php
2
3
namespace Dyrynda\Database\Support;
4
5
/**
6
 * UUID generation trait.
7
 *
8
 * Include this trait in any Eloquent model where you wish to automatically set
9
 * a UUID field. When saving, if the UUID field has not been set, generate a
10
 * new UUID value, which will be set on the model and saved by Eloquent.
11
 *
12
 * @copyright 2017 Michael Dyrynda
13
 * @author    Michael Dyrynda <[email protected]>
14
 * @license   MIT
15
 */
16
trait GeneratesUuid
17
{
18
    protected $uuidVersions = [
19
        'uuid1',
20
        'uuid3',
21
        'uuid4',
22
        'uuid5',
23
    ];
24
25
    /**
26
     * Determine whether an attribute should be cast to a native type.
27
     *
28
     * @param  string  $key
29
     * @param  array|string|null  $types
30
     * @return bool
31
     */
32
    abstract public function hasCast($key, $types = null);
33
34
    /**
35
     * Boot the trait, adding a creating observer.
36
     *
37
     * When persisting a new model instance, we resolve the UUID field, then set
38
     * a fresh UUID, taking into account if we need to cast to binary or not.
39
     */
40
    public static function bootGeneratesUuid()
41
    {
42 6
        static::creating(function ($model) {
43 6
            $uuid = $model->resolveUuid();
44
45 6
            if (isset($model->attributes['uuid']) && ! is_null($model->attributes['uuid'])) {
46 4
                $uuid = $uuid->fromString(strtolower($model->attributes['uuid']));
47 4
            }
48
49 6
            $model->attributes['uuid'] = $model->hasCast('uuid') ? $uuid->getBytes() : $uuid->toString();
50 6
        });
51 2
    }
52
    
53
    /**
54
     * Resolve a UUID instance for the configured version.
55
     *
56
     * @return \Ramsey\Uuid\Uuid
57
     */
58 6
    public function resolveUuid()
59
    {
60 6
        return call_user_func("\Ramsey\Uuid\Uuid::{$this->resolveUuidVersion()}");
61
    }
62
63
    /**
64
     * Resolve the UUID version to use when setting the UUID value. Default to uuid4.
65
     *
66
     * @return string
67
     */
68 11
    public function resolveUuidVersion()
69
    {
70 11
        if (property_exists($this, 'uuidVersion') && in_array($this->uuidVersion, $this->uuidVersions)) {
71 4
            return $this->uuidVersion;
72
        }
73
74 7
        return 'uuid4';
75
    }
76
77
    /**
78
     * Scope queries to find by UUID.
79
     *
80
     * @param  \Illuminate\Database\Eloquent\Builder  $query
81
     * @param  string  $uuid
82
     *
83
     * @return \Illuminate\Database\Eloquent\Builder
84
     */
85 2
    public function scopeWhereUuid($query, $uuid)
86
    {
87 2
        return $this->hasCast('uuid')
88 2
            ? $query->where('uuid', $this->resolveUuid()->fromString($uuid)->getBytes())
89 2
            : $query->where('uuid', $uuid);
90
    }
91
92
    /**
93
     * Cast an attribute to a native PHP type.
94
     *
95
     * @param  string  $key
96
     * @param  mixed  $value
97
     * @return mixed
98
     */
99 2
    protected function castAttribute($key, $value)
100
    {
101 2
        if ($key == 'uuid' && ! is_null($value)) {
102 2
            return $this->resolveUuid()->fromBytes($value)->toString();
103
        }
104
105
        return parent::castAttribute($key, $value);
106
    }
107
}
108