Completed
Push — 6.0 ( 77cbae...03c51c )
by liu
03:09
created

Attribute::setAttrs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
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 InvalidArgumentException;
16
use think\App;
17
use think\db\Raw;
18
use think\model\Relation;
19
20
/**
21
 * 模型数据处理
22
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
23
trait Attribute
24
{
25
    /**
26
     * 数据表主键 复合主键使用数组定义
27
     * @var string|array
28
     */
29
    protected $pk = 'id';
30
31
    /**
32
     * 数据表字段信息 留空则自动获取
33
     * @var array
34
     */
35
    protected $schema = [];
36
37
    /**
38
     * 当前允许写入的字段
39
     * @var array
40
     */
41
    protected $field = [];
42
43
    /**
44
     * 字段自动类型转换
45
     * @var array
46
     */
47
    protected $type = [];
48
49
    /**
50
     * 数据表废弃字段
51
     * @var array
52
     */
53
    protected $disuse = [];
54
55
    /**
56
     * 数据表只读字段
57
     * @var array
58
     */
59
    protected $readonly = [];
60
61
    /**
62
     * 当前模型数据
63
     * @var array
64
     */
65
    private $data = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "data" must be prefixed with an underscore
Loading history...
66
67
    /**
68
     * 原始数据
69
     * @var array
70
     */
71
    private $origin = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "origin" must be prefixed with an underscore
Loading history...
72
73
    /**
74
     * JSON数据表字段
75
     * @var array
76
     */
77
    protected $json = [];
78
79
    /**
80
     * JSON数据表字段类型
81
     * @var array
82
     */
83
    protected $jsonType = [];
84
85
    /**
86
     * JSON数据取出是否需要转换为数组
87
     * @var bool
88
     */
89
    protected $jsonAssoc = false;
90
91
    /**
92
     * 是否严格字段大小写
93
     * @var bool
94
     */
95
    protected $strict = true;
96
97
    /**
98
     * 修改器执行记录
99
     * @var array
100
     */
101
    private $set = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "set" must be prefixed with an underscore
Loading history...
102
103
    /**
104
     * 动态获取器
105
     * @var array
106
     */
107
    private $withAttr = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "withAttr" must be prefixed with an underscore
Loading history...
108
109
    /**
110
     * 获取模型对象的主键
111
     * @access public
112
     * @return string|array
113
     */
114
    public function getPk()
115
    {
116
        return $this->pk;
117
    }
118
119
    /**
120
     * 判断一个字段名是否为主键字段
121
     * @access public
122
     * @param  string $key 名称
123
     * @return bool
124
     */
125
    protected function isPk(string $key): bool
126
    {
127
        $pk = $this->getPk();
128
129
        if (is_string($pk) && $pk == $key) {
130
            return true;
131
        } elseif (is_array($pk) && in_array($key, $pk)) {
132
            return true;
133
        }
134
135
        return false;
136
    }
137
138
    /**
139
     * 获取模型对象的主键值
140
     * @access public
141
     * @return mixed
142
     */
143
    public function getKey()
144
    {
145
        $pk = $this->getPk();
146
147
        if (is_string($pk) && array_key_exists($pk, $this->data)) {
148
            return $this->data[$pk];
149
        }
150
151
        return;
152
    }
153
154
    /**
155
     * 设置允许写入的字段
156
     * @access public
157
     * @param  array $field 允许写入的字段
158
     * @return $this
159
     */
160
    public function allowField(array $field)
161
    {
162
        $this->field = $field;
163
164
        return $this;
165
    }
166
167
    /**
168
     * 设置只读字段
169
     * @access public
170
     * @param  array $field 只读字段
171
     * @return $this
172
     */
173
    public function readOnly(array $field)
174
    {
175
        $this->readonly = $field;
176
177
        return $this;
178
    }
179
180
    /**
181
     * 获取实际的字段名
182
     * @access public
183
     * @param  string $name 字段名
184
     * @return string
185
     */
186
    protected function getRealFieldName(string $name): string
187
    {
188
        return $this->strict ? $name : App::parseName($name);
189
    }
190
191
    /**
192
     * 设置数据对象值
193
     * @access public
194
     * @param  array    $data  数据
195
     * @param  bool     $set   是否调用修改器
196
     * @param  array    $allow 允许的字段名
197
     * @return $this
198
     */
199
    public function data(array $data, bool $set = false, array $allow = [])
200
    {
201
        // 清空数据
202
        $this->data = [];
203
204
        // 废弃字段
205
        foreach ($this->disuse as $key) {
206
            if (array_key_exists($key, $data)) {
207
                unset($data[$key]);
208
            }
209
        }
210
211
        if (!empty($allow)) {
212
            $result = [];
213
            foreach ($allow as $name) {
214
                if (isset($data[$name])) {
215
                    $result[$name] = $data[$name];
216
                }
217
            }
218
            $data = $result;
219
        }
220
221
        if ($set) {
222
            // 数据对象赋值
223
            $this->setAttrs($data);
224
        } else {
225
            $this->data = $data;
226
        }
227
228
        return $this;
229
    }
230
231
    /**
232
     * 批量追加数据对象值
233
     * @access public
234
     * @param  array $data  数据
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
235
     * @param  bool  $set   是否需要进行数据处理
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 3 found
Loading history...
236
     * @return $this
237
     */
238
    public function appendData(array $data, bool $set = false)
239
    {
240
        if ($set) {
241
            $this->setAttrs($data);
242
        } else {
243
            $this->data = array_merge($this->data, $data);
244
        }
245
246
        return $this;
247
    }
248
249
    /**
250
     * 获取对象原始数据 如果不存在指定字段返回null
251
     * @access public
252
     * @param  string $name 字段名 留空获取全部
253
     * @return mixed
254
     */
255
    public function getOrigin(string $name = null)
256
    {
257
        if (is_null($name)) {
258
            return $this->origin;
259
        }
260
261
        return array_key_exists($name, $this->origin) ? $this->origin[$name] : null;
262
    }
263
264
    /**
265
     * 获取对象原始数据 如果不存在指定字段返回false
266
     * @access public
267
     * @param  string $name 字段名 留空获取全部
268
     * @return mixed
269
     * @throws InvalidArgumentException
270
     */
271
    public function getData(string $name = null)
272
    {
273
        if (is_null($name)) {
274
            return $this->data;
275
        }
276
277
        $fieldName = $this->getRealFieldName($name);
278
279
        if (array_key_exists($fieldName, $this->data)) {
280
            return $this->data[$fieldName];
281
        } elseif (array_key_exists($name, $this->relation)) {
282
            return $this->relation[$name];
283
        }
284
285
        throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name);
286
    }
287
288
    /**
289
     * 获取变化的数据 并排除只读数据
290
     * @access public
291
     * @return array
292
     */
293
    public function getChangedData(): array
294
    {
295
        $data = $this->force ? $this->data : array_udiff_assoc($this->data, $this->origin, function ($a, $b) {
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...
296
            if ((empty($a) || empty($b)) && $a !== $b) {
297
                return 1;
298
            }
299
300
            return is_object($a) || $a != $b ? 1 : 0;
301
        });
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...
302
303
        // 只读字段不允许更新
304
        foreach ($this->readonly as $key => $field) {
305
            if (isset($data[$field])) {
306
                unset($data[$field]);
307
            }
308
        }
309
310
        return $data;
311
    }
312
313
    /**
314
     * 直接设置数据对象值
315
     * @access public
316
     * @param  string $name  属性名
317
     * @param  mixed  $value 值
318
     * @return void
319
     */
320
    public function set(string $name, $value): void
321
    {
322
        $name = $this->getRealFieldName($name);
323
324
        $this->data[$name] = $value;
325
    }
326
327
    /**
328
     * 通过修改器 批量设置数据对象值
329
     * @access public
330
     * @param  array $data  数据
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
331
     * @return void
332
     */
333
    public function setAttrs(array $data): void
334
    {
335
        // 进行数据处理
336
        foreach ($data as $key => $value) {
337
            $this->setAttr($key, $value, $data);
338
        }
339
    }
340
341
    /**
342
     * 通过修改器 设置数据对象值
343
     * @access public
344
     * @param  string $name  属性名
345
     * @param  mixed  $value 属性值
346
     * @param  array  $data  数据
347
     * @return void
348
     */
349
    public function setAttr(string $name, $value, array $data = []): void
350
    {
351
        $name = $this->getRealFieldName($name);
352
353
        if (isset($this->set[$name])) {
354
            return;
355
        }
356
357
        if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
358
            // 自动写入的时间戳字段
359
            $value = $this->autoWriteTimestamp($name);
0 ignored issues
show
Bug introduced by
It seems like autoWriteTimestamp() 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

359
            /** @scrutinizer ignore-call */ 
360
            $value = $this->autoWriteTimestamp($name);
Loading history...
360
        } else {
361
            // 检测修改器
362
            $method = 'set' . App::parseName($name, 1) . 'Attr';
363
364
            if (method_exists($this, $method)) {
365
                $value = $this->$method($value, array_merge($this->data, $data));
366
367
                $this->set[$name] = true;
368
            } elseif (isset($this->type[$name])) {
369
                // 类型转换
370
                $value = $this->writeTransform($value, $this->type[$name]);
371
            }
372
        }
373
374
        // 设置数据对象属性
375
        $this->data[$name] = $value;
376
    }
377
378
    /**
379
     * 数据写入 类型转换
380
     * @access protected
381
     * @param  mixed        $value 值
382
     * @param  string|array $type  要转换的类型
383
     * @return mixed
384
     */
385
    protected function writeTransform($value, $type)
386
    {
387
        if (is_null($value)) {
388
            return;
389
        }
390
391
        if ($value instanceof Raw) {
392
            return $value;
393
        }
394
395
        if (is_array($type)) {
396
            list($type, $param) = $type;
397
        } elseif (strpos($type, ':')) {
398
            list($type, $param) = explode(':', $type, 2);
399
        }
400
401
        switch ($type) {
402
            case 'integer':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
403
                $value = (int) $value;
404
                break;
405
            case 'float':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
406
                if (empty($param)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
407
                    $value = (float) $value;
408
                } else {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
409
                    $value = (float) number_format($value, $param, '.', '');
410
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
411
                break;
412
            case 'boolean':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
413
                $value = (bool) $value;
414
                break;
415
            case 'timestamp':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
416
                if (!is_numeric($value)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
417
                    $value = strtotime($value);
418
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
419
                break;
420
            case 'datetime':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
421
422
                $value = is_numeric($value) ? $value : strtotime($value);
423
                $value = $this->formatDateTime('Y-m-d H:i:s.u', $value);
0 ignored issues
show
Bug introduced by
It seems like formatDateTime() 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

423
                /** @scrutinizer ignore-call */ 
424
                $value = $this->formatDateTime('Y-m-d H:i:s.u', $value);
Loading history...
424
                break;
425
            case 'object':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
426
                if (is_object($value)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
427
                    $value = json_encode($value, JSON_FORCE_OBJECT);
428
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
429
                break;
430
            case 'array':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
431
                $value = (array) $value;
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
432
            case 'json':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
433
                $option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE;
434
                $value  = json_encode($value, $option);
435
                break;
436
            case 'serialize':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
437
                $value = serialize($value);
438
                break;
439
            default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
440
                if (is_object($value) && false !== strpos($type, '\\') && method_exists($value, '__toString')) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
441
                    // 对象类型
442
                    $value = $value->__toString();
443
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
444
        }
445
446
        return $value;
447
    }
448
449
    /**
450
     * 获取器 获取数据对象的值
451
     * @access public
452
     * @param  string $name 名称
453
     * @return mixed
454
     * @throws InvalidArgumentException
455
     */
456
    public function getAttr(string $name)
457
    {
458
        try {
459
            $relation = false;
460
            $value    = $this->getData($name);
461
        } catch (InvalidArgumentException $e) {
462
            $relation = true;
463
            $value    = null;
464
        }
465
466
        return $this->getValue($name, $value, $relation);
467
    }
468
469
    /**
470
     * 获取经过获取器处理后的数据对象的值
471
     * @access protected
472
     * @param  string $name 字段名称
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 1 found
Loading history...
473
     * @param  mixed  $value 字段值
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
474
     * @param  bool   $relation 是否为关联属性
475
     * @return mixed
476
     * @throws InvalidArgumentException
477
     */
478
    protected function getValue(string $name, $value, bool $relation = false)
479
    {
480
        // 检测属性获取器
481
        $fieldName = $this->getRealFieldName($name);
482
        $method    = 'get' . App::parseName($name, 1) . 'Attr';
483
484
        if (isset($this->withAttr[$fieldName])) {
485
            if ($relation) {
486
                $value = $this->getRelationValue($name);
487
            }
488
489
            if (in_array($fieldName, $this->json) && is_array($this->withAttr[$fieldName])) {
490
                $value = $this->getJsonValue($fieldName, $value);
491
            } else {
492
                $closure = $this->withAttr[$fieldName];
493
                $value   = $closure($value, $this->data);
494
            }
495
        } elseif (method_exists($this, $method)) {
496
            if ($relation) {
497
                $value = $this->getRelationValue($name);
498
            }
499
500
            $value = $this->$method($value, $this->data);
501
        } elseif (isset($this->type[$fieldName])) {
502
            // 类型转换
503
            $value = $this->readTransform($value, $this->type[$fieldName]);
504
        } elseif ($this->autoWriteTimestamp && in_array($fieldName, [$this->createTime, $this->updateTime])) {
505
            $value = $this->getTimestampValue($value);
0 ignored issues
show
Bug introduced by
It seems like getTimestampValue() 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

505
            /** @scrutinizer ignore-call */ 
506
            $value = $this->getTimestampValue($value);
Loading history...
506
        } elseif ($relation) {
507
            $value = $this->getRelationAttribute($name);
508
        }
509
510
        return $value;
511
    }
512
513
    protected function getJsonValue($name, $value)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getJsonValue()
Loading history...
514
    {
515
        foreach ($this->withAttr[$name] as $key => $closure) {
516
            if ($this->jsonAssoc) {
517
                $value[$key] = $closure($value[$key], $value);
518
            } else {
519
                $value->$key = $closure($value->$key, $value);
520
            }
521
        }
522
        return $value;
523
    }
524
    /**
525
     * 获取关联属性值
526
     * @access protected
527
     * @param  string   $name  属性名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
528
     * @return mixed
529
     */
530
    protected function getRelationValue(string $name)
531
    {
532
        $relation = $this->isRelationAttr($name);
0 ignored issues
show
Bug introduced by
It seems like isRelationAttr() 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

532
        /** @scrutinizer ignore-call */ 
533
        $relation = $this->isRelationAttr($name);
Loading history...
533
534
        if (false === $relation) {
535
            return;
536
        }
537
538
        $modelRelation = $this->$relation();
539
540
        return $modelRelation instanceof Relation ? $this->getRelationData($modelRelation) : null;
0 ignored issues
show
Bug introduced by
The method getRelationData() does not exist on think\model\concern\Attribute. Did you maybe mean getRelationValue()? ( Ignorable by Annotation )

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

540
        return $modelRelation instanceof Relation ? $this->/** @scrutinizer ignore-call */ getRelationData($modelRelation) : null;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
541
    }
542
543
    /**
544
     * 获取并保存关联属性值
545
     * @access protected
546
     * @param  string   $name  属性名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
547
     * @return mixed
548
     */
549
    protected function getRelationAttribute(string $name)
550
    {
551
        $value = $this->getRelationValue($name);
552
553
        if (!$value) {
554
            throw new InvalidArgumentException('property not exists:' . static::class . '->' . $name);
555
        }
556
557
        // 保存关联对象值
558
        $this->relation[$name] = $value;
0 ignored issues
show
Bug Best Practice introduced by
The property relation does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
559
560
        return $value;
561
    }
562
563
    /**
564
     * 数据读取 类型转换
565
     * @access protected
566
     * @param  mixed        $value 值
567
     * @param  string|array $type  要转换的类型
568
     * @return mixed
569
     */
570
    protected function readTransform($value, $type)
571
    {
572
        if (is_null($value)) {
573
            return;
574
        }
575
576
        if (is_array($type)) {
577
            list($type, $param) = $type;
578
        } elseif (strpos($type, ':')) {
579
            list($type, $param) = explode(':', $type, 2);
580
        }
581
582
        switch ($type) {
583
            case 'integer':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
584
                $value = (int) $value;
585
                break;
586
            case 'float':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
587
                if (empty($param)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
588
                    $value = (float) $value;
589
                } else {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
590
                    $value = (float) number_format($value, $param, '.', '');
591
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
592
                break;
593
            case 'boolean':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
594
                $value = (bool) $value;
595
                break;
596
            case 'timestamp':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
597
                if (!is_null($value)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
598
                    $format = !empty($param) ? $param : $this->dateFormat;
599
                    $value  = $this->formatDateTime($format, $value, true);
600
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
601
                break;
602
            case 'datetime':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
603
                if (!is_null($value)) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
604
                    $format = !empty($param) ? $param : $this->dateFormat;
605
                    $value  = $this->formatDateTime($format, $value);
606
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
607
                break;
608
            case 'json':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
609
                $value = json_decode($value, true);
610
                break;
611
            case 'array':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
612
                $value = empty($value) ? [] : json_decode($value, true);
613
                break;
614
            case 'object':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
615
                $value = empty($value) ? new \stdClass() : json_decode($value);
616
                break;
617
            case 'serialize':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
618
                try {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
619
                    $value = unserialize($value);
620
                } catch (\Exception $e) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
621
                    $value = null;
622
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
623
                break;
624
            default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
625
                if (false !== strpos($type, '\\')) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
626
                    // 对象类型
627
                    $value = new $type($value);
628
                }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
629
        }
630
631
        return $value;
632
    }
633
634
    /**
635
     * 设置数据字段获取器
636
     * @access public
637
     * @param  string|array $name       字段名
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 7 found
Loading history...
638
     * @param  callable     $callback   闭包获取器
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
639
     * @return $this
640
     */
641
    public function withAttribute($name, callable $callback = null)
642
    {
643
        if (is_array($name)) {
644
            foreach ($name as $key => $val) {
645
                $this->withAttribute($key, $val);
646
            }
647
        } else {
648
            $name = $this->getRealFieldName($name);
649
650
            if (strpos($name, '.')) {
651
                list($name, $key) = explode('.', $name);
652
653
                $this->withAttr[$name][$key] = $callback;
654
            } else {
655
                $this->withAttr[$name] = $callback;
656
            }
657
        }
658
659
        return $this;
660
    }
661
662
}
663