Test Setup Failed
Push — master ( e50fd7...c57aa3 )
by Syed Abidur
01:59
created

BooleanTimestampFieldManipulator::syncOriginal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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