Completed
Push — 6.0 ( dc873c...6e7412 )
by liu
04:59
created

HasOneThrough::getRelation()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 2
dl 0
loc 15
ccs 0
cts 8
cp 0
crap 12
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
12
namespace think\model\relation;
13
14
use Closure;
15
use think\App;
16
use think\db\Query;
17
use think\Model;
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
class HasOneThrough extends HasManyThrough
24
{
25
26
    /**
27
     * 延迟获取关联数据
28
     * @access public
29
     * @param  array   $subRelation 子关联名
30
     * @param  Closure $closure     闭包查询条件
31
     * @return Model
32
     */
33
    public function getRelation(array $subRelation = [], \Closure $closure = null)
34
    {
35
        if ($closure) {
36
            $closure($this->query);
37
        }
38
39
        $this->baseQuery();
40
41
        $relationModel = $this->query->relation($subRelation)->find();
42
43
        if ($relationModel) {
0 ignored issues
show
introduced by
$relationModel is of type think\Model, thus it always evaluated to true.
Loading history...
44
            $relationModel->setParent(clone $this->parent);
45
        }
46
47
        return $relationModel;
48
    }
49
50
    /**
51
     * 预载入关联查询(数据集)
52
     * @access protected
53
     * @param  array   $resultSet   数据集
54
     * @param  string  $relation    当前关联名
55
     * @param  array   $subRelation 子关联名
56
     * @param  Closure $closure     闭包
57
     * @return void
58
     */
59
    public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation = [], Closure $closure = null): void
60
    {
61
        $localKey   = $this->localKey;
62
        $foreignKey = $this->foreignKey;
63
64
        $range = [];
65
        foreach ($resultSet as $result) {
66
            // 获取关联外键列表
67
            if (isset($result->$localKey)) {
68
                $range[] = $result->$localKey;
69
            }
70
        }
71
72
        if (!empty($range)) {
73
            $this->query->removeWhereField($foreignKey);
74
75
            $data = $this->eagerlyWhere([
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...
76
                [$this->foreignKey, 'in', $range],
77
            ], $foreignKey, $relation, $subRelation, $closure);
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...
78
79
            // 关联属性名
80
            $attr = App::parseName($relation);
81
82
            // 关联数据封装
83
            foreach ($resultSet as $result) {
84
                // 关联模型
85
                if (!isset($data[$result->$localKey])) {
86
                    $relationModel = null;
87
                } else {
88
                    $relationModel = $data[$result->$localKey];
89
                    $relationModel->setParent(clone $result);
90
                    $relationModel->exists(true);
91
                }
92
93
                // 设置关联属性
94
                $result->setRelation($attr, $relationModel);
95
            }
96
        }
97
    }
98
99
    /**
100
     * 预载入关联查询(数据)
101
     * @access protected
102
     * @param  Model   $result      数据对象
103
     * @param  string  $relation    当前关联名
104
     * @param  array   $subRelation 子关联名
105
     * @param  Closure $closure     闭包
106
     * @return void
107
     */
108
    public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null): void
109
    {
110
        $localKey   = $this->localKey;
111
        $foreignKey = $this->foreignKey;
112
113
        $this->query->removeWhereField($foreignKey);
114
115
        $data = $this->eagerlyWhere([
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...
116
            [$foreignKey, '=', $result->$localKey],
117
        ], $foreignKey, $relation, $subRelation, $closure);
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...
118
119
        // 关联模型
120
        if (!isset($data[$result->$localKey])) {
121
            $relationModel = null;
122
        } else {
123
            $relationModel = $data[$result->$localKey];
124
            $relationModel->setParent(clone $result);
125
            $relationModel->exists(true);
126
        }
127
128
        $result->setRelation(App::parseName($relation), $relationModel);
129
    }
130
131
    /**
132
     * 关联模型预查询
133
     * @access public
134
     * @param  array   $where       关联预查询条件
135
     * @param  string  $key         关联键名
136
     * @param  string  $relation    关联名
137
     * @param  array   $subRelation 子关联
138
     * @param  Closure $closure
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
139
     * @return array
140
     */
141
    protected function eagerlyWhere(array $where, string $key, string $relation, array $subRelation = [], Closure $closure = null)
142
    {
143
        // 预载入关联查询 支持嵌套预载入
144
        $keys = $this->through->where($where)->column($this->throughPk, $this->foreignKey);
145
146
        if ($closure) {
147
            $closure($this->query);
148
        }
149
150
        $list = $this->query->where($this->throughKey, 'in', $keys)->select();
151
152
        // 组装模型数据
153
        $data = [];
154
        $keys = array_flip($keys);
155
156
        foreach ($list as $set) {
157
            $data[$keys[$set->{$this->throughKey}]] = $set;
158
        }
159
160
        return $data;
161
    }
162
163
}
164