Completed
Pull Request — master (#2)
by Michael
01:40
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
use Ramsey\Uuid\Uuid;
6
7
/**
8
 * UUID generation trait.
9
 *
10
 * Include this trait in any Eloquent model where you wish to automatically set
11
 * a UUID field. When saving, if the UUID field has not been set, generate a
12
 * new UUID value, which will be set on the model and saved by Eloquent.
13
 *
14
 * @copyright 2017 Michael Dyrynda
15
 * @author    Michael Dyrynda <[email protected]>
16
 * @license   MIT
17
 */
18
trait GeneratesUuid
19
{
20
    protected $uuidVersions = [
21
        'uuid1',
22
        'uuid3',
23
        'uuid4',
24
        'uuid5',
25
    ];
26
27
    public static function bootGeneratesUuid()
28
    {
29
        /**
30
         * Boot the traid, adding a creating observer.
31
         *
32
         * When persisting a new model instance, we resolve the UUID field, then set
33
         * a fresh UUID
34
         */
35 10
        static::creating(function ($model) {
36 10
            $uuidField = $model->resolveUuidField();
37 10
            $uuidVersion = $model->resolveUuidVersion();
38
39 10
            if (! isset($model->attributes[$uuidField]) || is_null($model->attributes[$uuidField])) {
40 3
                $uuid = call_user_func("\Ramsey\Uuid\Uuid::{$uuidVersion}");
41 3
            } else {
42 7
                $uuid = call_user_func("\Ramsey\Uuid\Uuid::{$uuidVersion}")->fromString(strtolower($model->attributes[$uuidField]));
43
            }
44
45 10
            $model->attributes[$uuidField] = $model->hasCast($uuidField) ? $uuid->getBytes() : $uuid->toString();
46 10
        });
47 4
    }
48
49
    /**
50
     * Resolve the UUID version to use when setting the UUID value. Default to uuid4.
51
     *
52
     * @return string
53
     */
54 15
    public function resolveUuidVersion()
55
    {
56 15
        if (property_exists($this, 'uuidVersion') && in_array($this->uuidVersion, $this->uuidVersions)) {
57 4
            return $this->uuidVersion;
58
        }
59
60 11
        return 'uuid4';
61
    }
62
63
    /**
64
     * Resolve the name of the field we should use for UUIDs.
65
     *
66
     * @return string
67
     */
68 11
    public function resolveUuidField()
69
    {
70 11
        return property_exists($this, 'uuidField') ? $this->uuidField : 'uuid';
71
    }
72
73
    /**
74
     * Scope queries to find by UUID.
75
     *
76
     * @param  \Illuminate\Database\Eloquent\Builder  $query
77
     * @param  string  $uuid
78
     *
79
     * @return \Illuminate\Database\Eloquent\Builder
80
     */
81 4
    public function scopeWhereUuid($query, $uuid)
82
    {
83 4
        $uuidField = $this->resolveUuidField();
84
85 4
        if ($this->hasCast($uuidField)) {
0 ignored issues
show
Bug introduced by
It seems like hasCast() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
86 2
            return $query->where(
87 2
                $uuidField,
88 2
                call_user_func("\Ramsey\Uuid\Uuid::{$this->resolveUuidVersion()}")->fromString($uuid)->getBytes()
89 2
            );
90
        }
91
92 2
        return $query->where($uuidField, $uuid);
93
    }
94
95 4
    protected function castAttribute($key, $value)
96
    {
97 4
        if ($key == $this->resolveUuidField() && ! is_null($value)) {
98 4
            return Uuid::{$this->resolveUuidVersion()}()->fromBytes($value)->toString();
99
        }
100
101
        return parent::castAttribute($key, $value);
102
    }
103
}
104