Passed
Push — main ( c84275...1d7014 )
by Gabriel
03:41
created

TimestampableTrait::getUpdateTimestamps()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 5
c 1
b 0
f 1
nc 3
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace ByTIC\DataObjects\Behaviors\Timestampable;
4
5
use DateTime;
6
use Nip\Utility\Date;
7
8
/**
9
 * Trait TimestampableTrait
10
 * @package ByTIC\DataObjects\Behaviors\Timestampable
11
 */
12
trait TimestampableTrait
13
{
14
    protected $timestampableTypes = ['create', 'update'];
15
16
    /**
17
     * @param $attributes
18
     * @throws \Exception
19
     */
20
    public function updatedTimestamps($attributes)
21
    {
22
        if (is_string($attributes)) {
23
            if (in_array($attributes, $this->timestampableTypes)) {
24
                $attributes = $this->getTimestampAttributes($attributes);
25
            } else {
26
                $attributes = [$attributes];
27
            }
28
        }
29
        foreach ($attributes as $attribute) {
30
            /** @noinspection PhpUnhandledExceptionInspection */
31
            $this->setModelTimeAttribute($attribute, $this->{$attribute});
32
        }
33
    }
34
35
    protected function clearTimestamps()
36
    {
37
    }
38
39
    public function bootTimestampableTrait()
40
    {
41
        $this->hookCastableTrait();
42
    }
43
44
    /**
45
     * @param $attribute
46
     * @param $value
47
     * @return false|int|mixed|Date
48
     * @throws \Exception
49
     */
50
    public function setModelTimeAttribute($attribute, $value = null)
51
    {
52
        if (\is_string($value) && !empty($value)) {
53
            $unix = \strtotime($value);
54
            if ($unix === false) {
55
                throw new \Exception(
56
                    sprintf(
57
                        "Error parsing time value [%s] for field [%s] in object [%s]",
58
                        $value,
59
                        $attribute,
60
                        get_class($this)
61
                    )
62
                );
63
            }
64
            $value = $unix;
65
        }
66
67
        if (\is_numeric($value)) {
68
            $value = Date::createFromTimestamp($value);
69
        }
70
71
        if (!\is_object($value)) {
72
            $value = Date::now();
73
        }
74
        return $this->{$attribute} = $value;
75
    }
76
77
    /**
78
     * Get a fresh timestamp for the model.
79
     *
80
     * @return \Nip\Utility\Date
81
     */
82
    public function freshTimestamp(): DateTime
83
    {
84
        return Date::now();
85
    }
86
87
    /**
88
     * @param string $type
89
     * @return array
90
     */
91
    public function getTimestampAttributes(string $type = 'create'): array
92
    {
93
        if (!in_array($type, ['create', 'update'])) {
94
            return [];
95
        }
96
        $updateTimestamps = $this->getUpdateTimestamps();
97
        if ($type == 'update') {
98
            return $updateTimestamps;
99
        }
100
        $createTimestamps = $this->getCreateTimestamps();
101
102
        return array_merge($createTimestamps, $updateTimestamps);
103
    }
104
105
    /**
106
     * Get the name of the "created at" column.
107
     *
108
     * @return array
109
     */
110
    public function getCreateTimestamps(): array
111
    {
112
        if (!isset(static::$createTimestamps)) {
113
            return ['created_at'];
114
        }
115
        if (is_string(static::$createTimestamps)) {
116
            static::$createTimestamps = [static::$createTimestamps];
0 ignored issues
show
Bug Best Practice introduced by
The property createTimestamps does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
117
        }
118
        return static::$createTimestamps;
119
    }
120
121
    /**
122
     * Get the name of the "updated at" column.
123
     *
124
     * @return array
125
     */
126
    public function getUpdateTimestamps(): array
127
    {
128
        if (!isset(static::$createTimestamps)) {
129
            return ['updated_at'];
130
        }
131
        if (is_string(static::$updateTimestamps)) {
132
            static::$updateTimestamps = [static::$updateTimestamps];
0 ignored issues
show
Bug Best Practice introduced by
The property updateTimestamps does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
133
        }
134
        return static::$updateTimestamps;
135
    }
136
137
    /**
138
     * Get carbon object from timestamp attribute.
139
     *
140
     * @param string $attribute Attribute name
141
     *
142
     * @return Date|null|string
143
     */
144
    public function getTimeFromAttribute(string $attribute)
145
    {
146
        $value = $this->{$attribute};
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
147
148
        if (!$this->{$attribute}) {
149
            return $this->attributes[$attribute] = Date::now()->timestamp;
0 ignored issues
show
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
150
        }
151
152
        if (\is_string($this->attributes[$attribute]) && $timestamp = \strtotime($this->attributes[$attribute])) {
153
            return $this->attributes[$attribute] = (new Date())->setTimestamp($timestamp);
154
        }
155
156
        return $this->attributes[$attribute];
157
    }
158
159
    protected function hookCastableTrait()
160
    {
161
        if (method_exists($this, 'addCast') === false) {
162
            return;
163
        }
164
        $fields = $this->getTimestampAttributes();
165
        foreach ($fields as $field) {
166
            if ($this->hasCast($field)) {
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? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
            if ($this->/** @scrutinizer ignore-call */ hasCast($field)) {
Loading history...
167
                continue;
168
            }
169
            $this->addCast($field,'datetime');
170
        }
171
    }
172
}
173