bootBooleanTimestampFieldManipulator()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 4
b 0
f 0
nc 2
nop 0
dl 0
loc 15
rs 10
1
<?php
2
3
namespace Sarahman\Database\Support;
4
5
use Carbon\Carbon;
6
7
/**
8
 * This trait deals with the boolean-cum timestamp field.
9
 *
10
 * @property array $boolTimestampFields
11
 * @property array $attributes
12
 * @property array $casts
13
 *
14
 * @method self           append(array $attributes)
15
 * @method mixed|array    getOriginal(string $key = null, mixed $default = null)
16
 * @method \Carbon\Carbon asDateTime(mixed $value)
17
 * @method self           syncOriginal()
18
 *
19
 * @see \Illuminate\Database\Eloquent\Model
20
 */
21
trait BooleanTimestampFieldManipulator
22
{
23
    /**
24
     * Boot the trait.
25
     *
26
     * By booting this trait, it listens for the saving event of a model and
27
     * append the manipulated attribute values depending on the fields of defined $boolTimestampFields array.
28
     *
29
     * @throws \LogicException
30
     */
31
    protected static function bootBooleanTimestampFieldManipulator()
32
    {
33
        static::saving(function (self $model) {
34
            foreach ((array) $model::$boolTimestampFields as $field) {
35
                unset($model->attributes[$model->getAppendableAttributeName($field)]);
36
            }
37
        });
38
39
        static::saved(function (self $model) {
40
            $model->setBoolTimestampFieldsIntoAttributes($model);
41
        });
42
43
        if (method_exists(__CLASS__, 'retrieved')) {
44
            static::retrieved(function (self $model) {
45
                $model->setBoolTimestampFieldsIntoAttributes($model);
46
            });
47
        }
48
    }
49
50
    public function initializeBooleanTimestampFieldManipulator()
51
    {
52
        foreach ((array) self::$boolTimestampFields as $field) {
53
            $this->casts[$field] = 'boolean';
54
            $this->casts[$this->getAppendableAttributeName($field)] = 'datetime';
55
        }
56
    }
57
58
    public function setAttribute($key, $value)
59
    {
60
        if (count(self::$boolTimestampFields) && in_array($key, self::$boolTimestampFields)) {
61
            if ($value) {
62
                $this->attributes[$key] = ($original = $this->getOriginal($key)) ? $original : Carbon::now();
63
            } else {
64
                $this->attributes[$key] = null;
65
            }
66
67
            return;
68
        }
69
70
        parent::setAttribute($key, $value);
71
    }
72
73
    /**
74
     * Cast an attribute to a native PHP type.
75
     *
76
     * @param string $key
77
     * @param mixed  $value
78
     *
79
     * @return mixed
80
     */
81
    protected function castAttribute($key, $value)
82
    {
83
        if (count(self::$boolTimestampFields)) {
84
            if (in_array($key, self::$boolTimestampFields)) {
85
                return !empty($value);
86
            } elseif (in_array(preg_replace('/^time_being_/', 'is_', $key), self::$boolTimestampFields)) {
87
                return empty($value) ? null : $this->asDateTime($value);
88
            }
89
        }
90
91
        return parent::castAttribute($key, $value);
92
    }
93
94
    public function syncOriginal()
95
    {
96
        $result = parent::syncOriginal();
97
98
        $this->setBoolTimestampFieldsIntoAttributes($this, true);
99
100
        return $result;
101
    }
102
103
    private static function getAppendableAttributeName($field)
104
    {
105
        return 'time_being_'.preg_replace('/^is_/', '', $field);
106
    }
107
108
    private function setBoolTimestampFieldsIntoAttributes(self $model, $checkAttributeExists = false)
109
    {
110
        foreach ((array) self::$boolTimestampFields as $field) {
111
            if ($checkAttributeExists && !array_key_exists($field, $model->attributes)) {
112
                continue;
113
            }
114
115
            $original = $model->getOriginal($field);
116
            $model->attributes[$field] = !empty($original);
117
            $model->attributes[$model->getAppendableAttributeName($field)] = $original ? $model->asDateTime($original) : $original;
118
        }
119
    }
120
}
121