Completed
Push — develop ( 0d3736...607e7f )
by Nate
09:29
created

UserQueryParamHandler::applyParams()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 0
cts 26
cp 0
rs 8.8177
c 0
b 0
f 0
cc 6
nc 2
nop 1
crap 42
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/organization/license
6
 * @link       https://www.flipboxfactory.com/software/organization/
7
 */
8
9
namespace flipbox\organizations\queries;
10
11
use craft\elements\db\UserQuery;
12
use craft\helpers\Db;
13
use flipbox\organizations\records\UserAssociation as OrganizationUsersRecord;
14
use flipbox\organizations\records\UserTypeAssociation as UserCollectionUsersRecord;
15
use yii\base\BaseObject;
16
use yii\db\Query;
17
18
/**
19
 * @author Flipbox Factory <[email protected]>
20
 * @since 1.0.0
21
 */
22
class UserQueryParamHandler extends BaseObject
23
{
24
    use OrganizationAttributeTrait,
25
        OrganizationTypeAttributeTrait,
26
        UserTypeAttributeTrait {
27
        setUserType as parentSetUserType;
28
    }
29
30
    /**
31
     * @var OrganizationAttributesToUserQueryBehavior
32
     */
33
    private $owner;
34
35
    /**
36
     * @var string|string[]|null
37
     */
38
    public $userState;
39
40
    /**
41
     * @param string|string[]|null $value
42
     * @return UserQuery
43
     */
44
    public function setUserState($value): UserQuery
45
    {
46
        $this->userState = $value;
47
        return $this->owner->owner;
48
    }
49
50
    /**
51
     * @param string|string[]|null $value
52
     * @return UserQuery
53
     */
54
    public function userState($value): UserQuery
55
    {
56
        return $this->setUserState($value);
57
    }
58
59
    /**
60
     * @inheritdoc
61
     * @param OrganizationAttributesToUserQueryBehavior $owner
62
     */
63
    public function __construct(OrganizationAttributesToUserQueryBehavior $owner, array $config = [])
64
    {
65
        $this->owner = $owner;
66
        parent::__construct($config);
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function setUserType($value): UserQuery
73
    {
74
        $this->parentSetUserType($value);
75
        return $this->owner->owner;
76
    }
77
78
    /**
79
     * @param UserQuery $query
80
     */
81
    public function applyParams(UserQuery $query)
82
    {
83
        if ($query->subQuery === null ||
84
            (
85
                $this->organization === null &&
86
                $this->organizationType === null &&
87
                $this->userType === null &&
88
                $this->userState === null
89
            )
90
        ) {
91
            return;
92
        }
93
94
        $this->joinOrganizationUserTable($query);
95
96
        $this->applyOrganizationParam(
97
            $query,
98
            $this->organization
99
        );
100
101
        $this->applyUserTypeParam(
102
            $query,
103
            $this->userType
104
        );
105
106
        $this->applyUserStateParam(
107
            $query,
108
            $this->userState
109
        );
110
    }
111
112
    /************************************************************
113
     * JOIN TABLES
114
     ************************************************************/
115
116
    /**
117
     * @inheritdoc
118
     */
119
    protected function joinOrganizationUserTable(UserQuery $query)
120
    {
121
        $alias = OrganizationUsersRecord::tableAlias();
122
123
        $query->subQuery->leftJoin(
124
            OrganizationUsersRecord::tableName() . ' ' . $alias,
125
            '[[' . $alias . '.userId]] = [[elements.id]]'
126
        );
127
128
        // Check if we're ordering by one of the association table's order columns
129
        if (is_array($query->orderBy)) {
130
            $columns = ['userOrder' => 'userOrder', 'organizationOrder' => 'organizationOrder'];
131
            $matches = array_intersect_key($columns, $query->orderBy);
132
133
            foreach ($matches as $param => $select) {
134
                $query->subQuery->addSelect([$alias . '.' . $select]);
135
            }
136
        }
137
138
        return $alias;
139
    }
140
141
    /**
142
     * @inheritdoc
143
     */
144
    protected function joinOrganizationUserTypeTable(Query $query)
145
    {
146
        $alias = UserCollectionUsersRecord::tableAlias();
147
        $query->leftJoin(
148
            UserCollectionUsersRecord::tableName() . ' ' . $alias,
149
            '[[' . $alias . '.userId]] = [[' . OrganizationUsersRecord::tableAlias() . '.id]]'
150
        );
151
    }
152
153
154
    /************************************************************
155
     * ORGANIZATION
156
     ************************************************************/
157
158
    /**
159
     * @param UserQuery $query
160
     * @param $organization
161
     */
162
    protected function applyOrganizationParam(UserQuery $query, $organization)
163
    {
164
        if (empty($organization)) {
165
            return;
166
        }
167
168
        $query->subQuery->andWhere(
169
            Db::parseParam(
170
                OrganizationUsersRecord::tableAlias() . '.organizationId',
171
                $this->parseOrganizationValue($organization)
172
            )
173
        );
174
    }
175
176
177
    /************************************************************
178
     * USER TYPE
179
     ************************************************************/
180
181
    /**
182
     * @param UserQuery $query
183
     * @param $type
184
     */
185
    protected function applyUserTypeParam(UserQuery $query, $type)
186
    {
187
        if (empty($type)) {
188
            return;
189
        }
190
191
        $this->joinOrganizationUserTypeTable($query->subQuery);
0 ignored issues
show
Bug introduced by
It seems like $query->subQuery can be null; however, joinOrganizationUserTypeTable() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
192
        $query->subQuery
193
            ->distinct(true)
194
            ->andWhere(
195
                Db::parseParam(
196
                    UserCollectionUsersRecord::tableAlias() . '.typeId',
197
                    $this->parseUserTypeValue($type)
198
                )
199
            );
200
    }
201
202
203
    /************************************************************
204
     * USER STATE
205
     ************************************************************/
206
207
    /**
208
     * @param UserQuery $query
209
     * @param $state
210
     */
211
    protected function applyUserStateParam(UserQuery $query, $state)
212
    {
213
        if (empty($state)) {
214
            return;
215
        }
216
217
        $query->subQuery->andWhere(
218
            Db::parseParam(
219
                OrganizationUsersRecord::tableAlias() . '.state',
220
                $state
221
            )
222
        );
223
    }
224
}
225