Passed
Push — 5.1 ( 7fddc3...214229 )
by liu
09:13
created

Conversion::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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~2018 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
12
namespace think\model\concern;
13
14
use think\Collection;
15
use think\Exception;
16
use think\Loader;
17
use think\Model;
18
use think\model\Collection as ModelCollection;
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 Conversion
24
{
25
    /**
26
     * 数据输出显示的属性
27
     * @var array
28
     */
29
    protected $visible = [];
30
31
    /**
32
     * 数据输出隐藏的属性
33
     * @var array
34
     */
35
    protected $hidden = [];
36
37
    /**
38
     * 数据输出需要追加的属性
39
     * @var array
40
     */
41
    protected $append = [];
42
43
    /**
44
     * 数据集对象名
45
     * @var string
46
     */
47
    protected $resultSetType;
48
49
    /**
50
     * 设置需要附加的输出属性
51
     * @access public
52
     * @param  array $append   属性列表
53
     * @param  bool  $override 是否覆盖
54
     * @return $this
55
     */
56
    public function append(array $append = [], $override = false)
57
    {
58
        $this->append = $override ? $append : array_merge($this->append, $append);
59
60
        return $this;
61
    }
62
63
    /**
64
     * 设置附加关联对象的属性
65
     * @access public
66
     * @param  string       $attr    关联属性
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 4 found
Loading history...
67
     * @param  string|array $append  追加属性名
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
68
     * @return $this
69
     * @throws Exception
70
     */
71
    public function appendRelationAttr($attr, $append)
72
    {
73
        if (is_string($append)) {
74
            $append = explode(',', $append);
75
        }
76
77
        $relation = Loader::parseName($attr, 1, false);
78
        if (isset($this->relation[$relation])) {
79
            $model = $this->relation[$relation];
80
        } else {
81
            $model = $this->getRelationData($this->$relation());
0 ignored issues
show
Bug introduced by
It seems like getRelationData() 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

81
            /** @scrutinizer ignore-call */ 
82
            $model = $this->getRelationData($this->$relation());
Loading history...
82
        }
83
84
        if ($model instanceof Model) {
85
            foreach ($append as $key => $attr) {
0 ignored issues
show
introduced by
$attr is overwriting one of the parameters of this function.
Loading history...
86
                $key = is_numeric($key) ? $attr : $key;
87
                if (isset($this->data[$key])) {
88
                    throw new Exception('bind attr has exists:' . $key);
89
                } else {
90
                    $this->data[$key] = $model->$attr;
0 ignored issues
show
Bug Best Practice introduced by
The property data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
91
                }
92
            }
93
        }
94
95
        return $this;
96
    }
97
98
    /**
99
     * 设置需要隐藏的输出属性
100
     * @access public
101
     * @param  array $hidden   属性列表
102
     * @param  bool  $override 是否覆盖
103
     * @return $this
104
     */
105
    public function hidden(array $hidden = [], $override = false)
106
    {
107
        $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden);
108
109
        return $this;
110
    }
111
112
    /**
113
     * 设置需要输出的属性
114
     * @access public
115
     * @param  array $visible
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
116
     * @param  bool  $override 是否覆盖
117
     * @return $this
118
     */
119
    public function visible(array $visible = [], $override = false)
120
    {
121
        $this->visible = $override ? $visible : array_merge($this->visible, $visible);
122
123
        return $this;
124
    }
125
126
    /**
127
     * 转换当前模型对象为数组
128
     * @access public
129
     * @return array
130
     */
131
    public function toArray()
132
    {
133
        $item       = [];
134
        $hasVisible = false;
135
136
        foreach ($this->visible as $key => $val) {
137
            if (is_string($val)) {
138
                if (strpos($val, '.')) {
139
                    list($relation, $name)      = explode('.', $val);
140
                    $this->visible[$relation][] = $name;
141
                } else {
142
                    $this->visible[$val] = true;
143
                    $hasVisible          = true;
144
                }
145
                unset($this->visible[$key]);
146
            }
147
        }
148
149
        foreach ($this->hidden as $key => $val) {
150
            if (is_string($val)) {
151
                if (strpos($val, '.')) {
152
                    list($relation, $name)     = explode('.', $val);
153
                    $this->hidden[$relation][] = $name;
154
                } else {
155
                    $this->hidden[$val] = true;
156
                }
157
                unset($this->hidden[$key]);
158
            }
159
        }
160
161
        // 合并关联数据
162
        $data = array_merge($this->data, $this->relation);
163
164
        foreach ($data as $key => $val) {
165
            if ($val instanceof Model || $val instanceof ModelCollection) {
166
                // 关联模型对象
167
                if (isset($this->visible[$key])) {
168
                    $val->visible($this->visible[$key]);
169
                } elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {
170
                    $val->hidden($this->hidden[$key]);
171
                }
172
                // 关联模型对象
173
                if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {
174
                    $item[$key] = $val->toArray();
175
                }
176
            } elseif (isset($this->visible[$key])) {
177
                $item[$key] = $this->getAttr($key);
0 ignored issues
show
Bug introduced by
It seems like getAttr() 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

177
                /** @scrutinizer ignore-call */ 
178
                $item[$key] = $this->getAttr($key);
Loading history...
178
            } elseif (!isset($this->hidden[$key]) && !$hasVisible) {
179
                $item[$key] = $this->getAttr($key);
180
            }
181
        }
182
183
        // 追加属性(必须定义获取器)
184
        if (!empty($this->append)) {
185
            foreach ($this->append as $key => $name) {
186
                if (is_array($name)) {
187
                    // 追加关联对象属性
188
                    $relation = $this->getRelation($key);
0 ignored issues
show
Bug introduced by
It seems like getRelation() 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

188
                    /** @scrutinizer ignore-call */ 
189
                    $relation = $this->getRelation($key);
Loading history...
189
190
                    if (!$relation) {
191
                        $relation = $this->getAttr($key);
192
                        $relation->visible($name);
193
                    }
194
195
                    $item[$key] = $relation->append($name)->toArray();
196
                } elseif (strpos($name, '.')) {
197
                    list($key, $attr) = explode('.', $name);
198
                    // 追加关联对象属性
199
                    $relation = $this->getRelation($key);
200
201
                    if (!$relation) {
202
                        $relation = $this->getAttr($key);
203
                        $relation->visible([$attr]);
204
                    }
205
206
                    $item[$key] = $relation->append([$attr])->toArray();
207
                } else {
208
                    $item[$name] = $this->getAttr($name, $item);
209
                }
210
            }
211
        }
212
213
        return $item;
214
    }
215
216
    /**
217
     * 转换当前模型对象为JSON字符串
218
     * @access public
219
     * @param  integer $options json参数
220
     * @return string
221
     */
222
    public function toJson($options = JSON_UNESCAPED_UNICODE)
223
    {
224
        return json_encode($this->toArray(), $options);
225
    }
226
227
    /**
228
     * 移除当前模型的关联属性
229
     * @access public
230
     * @return $this
231
     */
232
    public function removeRelation()
233
    {
234
        $this->relation = [];
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...
235
        return $this;
236
    }
237
238
    public function __toString()
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
239
    {
240
        return $this->toJson();
241
    }
242
243
    // JsonSerializable
244
    public function jsonSerialize()
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a function comment
Loading history...
245
    {
246
        return $this->toArray();
247
    }
248
249
    /**
250
     * 转换数据集为数据集对象
251
     * @access public
252
     * @param  array|Collection $collection 数据集
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
253
     * @param  string           $resultSetType 数据集类
254
     * @return Collection
255
     */
256
    public function toCollection($collection, $resultSetType = null)
257
    {
258
        $resultSetType = $resultSetType ?: $this->resultSetType;
259
260
        if ($resultSetType && false !== strpos($resultSetType, '\\')) {
261
            $collection = new $resultSetType($collection);
262
        } else {
263
            $collection = new ModelCollection($collection);
264
        }
265
266
        return $collection;
267
    }
268
269
}
270