Completed
Pull Request — master (#14)
by Lucas
07:16 queued 02:39
created

GeneratesUuid::resolveUuidVersion()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

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