Completed
Push — 6.0 ( be0b6e...c47dd5 )
by liu
06:54 queued 10s
created

ResultOperation::selectOrFail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
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\db\concern;
14
15
use think\App;
16
use think\Collection;
17
use think\db\exception\DataNotFoundException;
18
use think\db\exception\ModelNotFoundException;
19
20
/**
21
 * 查询数据处理
22
 */
23
trait ResultOperation
24
{
25
    /**
26
     * 是否允许返回空数据(或空模型)
27
     * @access public
28
     * @param bool $allowEmpty 是否允许为空
29
     * @return $this
30
     */
31
    public function allowEmpty(bool $allowEmpty = true)
32
    {
33
        $this->options['allow_empty'] = $allowEmpty;
0 ignored issues
show
Bug Best Practice introduced by
The property options does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
34
        return $this;
35
    }
36
37
    /**
38
     * 设置查询数据不存在是否抛出异常
39
     * @access public
40
     * @param bool $fail 数据不存在是否抛出异常
41
     * @return $this
42
     */
43
    public function failException(bool $fail = true)
44
    {
45
        $this->options['fail'] = $fail;
0 ignored issues
show
Bug Best Practice introduced by
The property options does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
46
        return $this;
47
    }
48
49
    /**
50
     * 处理数据
51
     * @access protected
52
     * @param array $result 查询数据
53
     * @return void
54
     */
55
    protected function result(array &$result): void
56
    {
57
        if (!empty($this->options['json'])) {
58
            $this->jsonResult($result, $this->options['json'], true);
59
        }
60
61
        if (!empty($this->options['with_attr'])) {
62
            $this->getResultAttr($result, $this->options['with_attr']);
63
        }
64
65
        $this->filterResult($result);
66
    }
67
68
    /**
69
     * 处理数据集
70
     * @access public
71
     * @param array $resultSet 数据集
72
     * @return void
73
     */
74
    protected function resultSet(array &$resultSet): void
75
    {
76
        if (!empty($this->options['json'])) {
77
            foreach ($resultSet as &$result) {
78
                $this->jsonResult($result, $this->options['json'], true);
79
            }
80
        }
81
82
        if (!empty($this->options['with_attr'])) {
83
            foreach ($resultSet as &$result) {
84
                $this->getResultAttr($result, $this->options['with_attr']);
85
            }
86
        }
87
88
        if (!empty($this->options['visible']) || !empty($this->options['hidden'])) {
89
            foreach ($resultSet as &$result) {
90
                $this->filterResult($result);
91
            }
92
        }
93
94
        // 返回Collection对象
95
        $resultSet = new Collection($resultSet);
96
    }
97
98
    /**
99
     * 处理数据的可见和隐藏
100
     * @access protected
101
     * @param array $result 查询数据
102
     * @return void
103
     */
104
    protected function filterResult(&$result): void
105
    {
106
        if (!empty($this->options['visible'])) {
107
            foreach ($this->options['visible'] as $key) {
108
                $array[] = $key;
109
            }
110
            $result = array_intersect_key($result, array_flip($array));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $array seems to be defined by a foreach iteration on line 107. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
111
        } elseif (!empty($this->options['hidden'])) {
112
            foreach ($this->options['hidden'] as $key) {
113
                $array[] = $key;
114
            }
115
            $result = array_diff_key($result, array_flip($array));
116
        }
117
    }
118
119
    /**
120
     * 使用获取器处理数据
121
     * @access protected
122
     * @param array $result   查询数据
123
     * @param array $withAttr 字段获取器
124
     * @return void
125
     */
126
    protected function getResultAttr(array &$result, array $withAttr = []): void
127
    {
128
        foreach ($withAttr as $name => $closure) {
129
            $name = App::parseName($name);
130
131
            if (strpos($name, '.')) {
132
                // 支持JSON字段 获取器定义
133
                list($key, $field) = explode('.', $name);
134
135
                if (isset($result[$key])) {
136
                    $result[$key][$field] = $closure($result[$key][$field] ?? null, $result[$key]);
137
                }
138
            } else {
139
                $result[$name] = $closure($result[$name] ?? null, $result);
140
            }
141
        }
142
    }
143
144
    /**
145
     * 处理空数据
146
     * @access protected
147
     * @return array|Model|null
148
     * @throws DbException
149
     * @throws ModelNotFoundException
150
     * @throws DataNotFoundException
151
     */
152
    protected function resultToEmpty()
153
    {
154
        if (!empty($this->options['fail'])) {
155
            $this->throwNotFound();
156
        } elseif (!empty($this->options['allow_empty'])) {
157
            return !empty($this->model) ? $this->model->newInstance()->setQuery($this) : [];
158
        }
159
    }
160
161
    /**
162
     * 查找单条记录 不存在返回空数据(或者空模型)
163
     * @access public
164
     * @param mixed $data 数据
165
     * @return array|Model
166
     */
167
    public function findOrEmpty($data = null)
168
    {
169
        return $this->allowEmpty(true)->find($data);
0 ignored issues
show
Bug introduced by
It seems like find() 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

169
        return $this->allowEmpty(true)->/** @scrutinizer ignore-call */ find($data);
Loading history...
170
    }
171
172
    /**
173
     * JSON字段数据转换
174
     * @access protected
175
     * @param array $result           查询数据
176
     * @param array $json             JSON字段
177
     * @param bool  $assoc            是否转换为数组
178
     * @param array $withRelationAttr 关联获取器
179
     * @return void
180
     */
181
    protected function jsonResult(array &$result, array $json = [], bool $assoc = false, array $withRelationAttr = []): void
182
    {
183
        foreach ($json as $name) {
184
            if (!isset($result[$name])) {
185
                continue;
186
            }
187
188
            $result[$name] = json_decode($result[$name], true);
189
190
            if (isset($withRelationAttr[$name])) {
191
                foreach ($withRelationAttr[$name] as $key => $closure) {
192
                    $result[$name][$key] = $closure($result[$name][$key] ?? null, $result[$name]);
193
                }
194
            }
195
196
            if (!$assoc) {
197
                $result[$name] = (object) $result[$name];
198
            }
199
        }
200
    }
201
202
    /**
203
     * 查询失败 抛出异常
204
     * @access protected
205
     * @return void
206
     * @throws ModelNotFoundException
207
     * @throws DataNotFoundException
208
     */
209
    protected function throwNotFound(): void
210
    {
211
        if (!empty($this->model)) {
212
            $class = get_class($this->model);
213
            throw new ModelNotFoundException('model data Not Found:' . $class, $class, $this->options);
214
        }
215
216
        $table = $this->getTable();
0 ignored issues
show
Bug introduced by
It seems like getTable() 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

216
        /** @scrutinizer ignore-call */ 
217
        $table = $this->getTable();
Loading history...
217
        throw new DataNotFoundException('table data not Found:' . $table, $table, $this->options);
218
    }
219
220
    /**
221
     * 查找多条记录 如果不存在则抛出异常
222
     * @access public
223
     * @param array|string|Query|Closure $data 数据
0 ignored issues
show
Bug introduced by
The type think\db\concern\Closure was not found. Did you mean Closure? If so, make sure to prefix the type with \.
Loading history...
Bug introduced by
The type think\db\concern\Query was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
224
     * @return array|Model
225
     * @throws DbException
226
     * @throws ModelNotFoundException
227
     * @throws DataNotFoundException
228
     */
229
    public function selectOrFail($data = null)
230
    {
231
        return $this->failException(true)->select($data);
0 ignored issues
show
Bug introduced by
The method select() does not exist on think\db\concern\ResultOperation. Did you maybe mean selectOrFail()? ( Ignorable by Annotation )

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

231
        return $this->failException(true)->/** @scrutinizer ignore-call */ select($data);

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...
232
    }
233
234
    /**
235
     * 查找单条记录 如果不存在则抛出异常
236
     * @access public
237
     * @param array|string|Query|Closure $data 数据
238
     * @return array|Model
239
     * @throws DbException
240
     * @throws ModelNotFoundException
241
     * @throws DataNotFoundException
242
     */
243
    public function findOrFail($data = null)
244
    {
245
        return $this->failException(true)->find($data);
246
    }
247
248
}
249