Completed
Push — 6.0 ( 05a5a5...badc89 )
by liu
04:56
created

TimeStamp::autoWriteTimestamp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
ccs 0
cts 5
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think\model\concern;
14
15
use DateTime;
16
17
/**
18
 * 自动时间戳
19
 */
20
trait TimeStamp
21
{
22
    /**
23
     * 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型
24
     * @var bool|string
25
     */
26
    protected $autoWriteTimestamp;
27
28
    /**
29
     * 创建时间字段 false表示关闭
30
     * @var false|string
31
     */
32
    protected $createTime = 'create_time';
33
34
    /**
35
     * 更新时间字段 false表示关闭
36
     * @var false|string
37
     */
38
    protected $updateTime = 'update_time';
39
40
    /**
41
     * 时间字段显示格式
42
     * @var string
43
     */
44
    protected $dateFormat;
45
46
    /**
47
     * 是否需要自动写入时间字段
48
     * @access public
49
     * @param  bool|string $auto
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
50
     * @return $this
51
     */
52
    public function isAutoWriteTimestamp($auto)
53
    {
54
        $this->autoWriteTimestamp = $this->checkTimeFieldType($auto);
55
56
        return $this;
57
    }
58
59
    /**
60
     * 检测时间字段的实际类型
61
     * @access public
62
     * @param  bool|string $auto
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
63
     * @return mixed
64
     */
65
    protected function checkTimeFieldType($auto)
66
    {
67
        if (true === $auto && isset($this->schema[$this->createTime]) && in_array($this->schema[$this->createTime], ['datetime', 'date', 'timestamp', 'int'])) {
68
            return $this->schema[$this->createTime];
69
        }
70
71
        return $auto;
72
    }
73
74
    /**
75
     * 获取自动写入时间字段
76
     * @access public
77
     * @return bool|string
78
     */
79
    public function getAutoWriteTimestamp()
80
    {
81
        return $this->autoWriteTimestamp;
82
    }
83
84
    /**
85
     * 设置时间字段格式化
86
     * @access public
87
     * @param  string|false $format
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
88
     * @return $this
89
     */
90
    public function setDateFormat($format)
91
    {
92
        $this->dateFormat = $format;
0 ignored issues
show
Documentation Bug introduced by
It seems like $format can also be of type false. However, the property $dateFormat is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
93
94
        return $this;
95
    }
96
97
    /**
98
     * 获取自动写入时间字段
99
     * @access public
100
     * @return string|false
101
     */
102
    public function getDateFormat()
103
    {
104
        return $this->dateFormat;
105
    }
106
107
    /**
108
     * 自动写入时间戳
109
     * @access protected
110
     * @param  string $name 时间戳字段
111
     * @return mixed
112
     */
113
    protected function autoWriteTimestamp(string $name)
114
    {
115
        // 检测时间字段类型
116
        if (isset($this->type[$name])) {
117
            $type = $this->type[$name];
118
        } else {
119
            $type = $this->checkTimeFieldType($this->autoWriteTimestamp);
120
        }
121
122
        return $this->getTimeTypeValue($type);
123
    }
124
125
    /**
126
     * 获取指定类型的时间字段值
127
     * @access protected
128
     * @param  string $type 时间字段类型
129
     * @return mixed
130
     */
131
    protected function getTimeTypeValue(string $type)
132
    {
133
        $value = time();
134
135
        switch ($type) {
136
            case 'datetime':
137
            case 'date':
138
            case 'timestamp':
139
                $value = $this->formatDateTime('Y-m-d H:i:s.u');
140
                break;
141
            default:
142
                if (false !== strpos($type, '\\')) {
143
                    // 对象数据写入
144
                    $obj = new $type();
145
                    if (method_exists($obj, '__toString')) {
146
                        // 对象数据写入
147
                        $value = $obj->__toString();
148
                    }
149
                }
150
        }
151
152
        return $value;
153
    }
154
155
    /**
156
     * 时间日期字段格式化处理
157
     * @access protected
158
     * @param  mixed $format    日期格式
159
     * @param  mixed $time      时间日期表达式
160
     * @param  bool  $timestamp 时间表达式是否为时间戳
161
     * @return mixed
162
     */
163
    protected function formatDateTime($format, $time = 'now', bool $timestamp = false)
164
    {
165
        if (empty($time)) {
166
            return;
167
        }
168
169
        if (false === $format) {
170
            return $time;
171
        } elseif (false !== strpos($format, '\\')) {
172
            return new $format($time);
173
        }
174
175
        if ($time instanceof DateTime) {
176
            $dateTime = $time;
177
        } elseif ($timestamp) {
178
            $dateTime = new DateTime();
179
            $dateTime->setTimestamp((int) $time);
180
        } else {
181
            $dateTime = new DateTime($time);
182
        }
183
184
        return $dateTime->format($format);
185
    }
186
187
    /**
188
     * 获取时间字段值
189
     * @access protected
190
     * @param  mixed   $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
191
     * @return mixed
192
     */
193
    protected function getTimestampValue($value)
194
    {
195
        $type = $this->autoCheckTimestamp($this->autoWriteTimestamp);
0 ignored issues
show
Bug introduced by
It seems like autoCheckTimestamp() 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

195
        /** @scrutinizer ignore-call */ 
196
        $type = $this->autoCheckTimestamp($this->autoWriteTimestamp);
Loading history...
196
197
        if (in_array(strtolower($type), [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
198
            'datetime', 'date', 'timestamp',
199
        ])) {
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
200
            $value = $this->formatDateTime($this->dateFormat, $value);
201
        } else {
202
            $value = $this->formatDateTime($this->dateFormat, $value, true);
203
        }
204
205
        return $value;
206
    }
207
}
208