OrganizationQuery::applyUserGroupParam()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 0
cts 17
cp 0
rs 9.568
c 0
b 0
f 0
cc 4
nc 3
nop 1
crap 20
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\db\Query;
12
use craft\db\QueryAbortedException;
13
use craft\elements\db\ElementQuery;
14
use craft\helpers\Db;
15
use craft\records\UserGroup_User as UserGroupUsersRecord;
16
use flipbox\craft\ember\queries\UserAttributeTrait;
17
use flipbox\craft\ember\queries\UserGroupAttributeTrait;
18
use flipbox\organizations\elements\Organization as OrganizationElement;
19
use flipbox\organizations\records\Organization as OrganizationRecord;
20
use flipbox\organizations\records\OrganizationTypeAssociation as TypeAssociationRecord;
21
use flipbox\organizations\records\UserAssociation as OrganizationUsersRecord;
22
use flipbox\organizations\records\UserTypeAssociation as UserTypeAssociationRecord;
23
24
/**
25
 * @author Flipbox Factory <[email protected]>
26
 * @since 1.0.0
27
 *
28
 * @property Query $query
29
 * @property Query $subQuery
30
 *
31
 * @method OrganizationElement one($db = null)
32
 * @method OrganizationElement[] all($db = null)
33
 * @method OrganizationElement[] getCachedResult()
34
 */
35
class OrganizationQuery extends ElementQuery
36
{
37
    use UserAttributeTrait,
38
        UserGroupAttributeTrait,
39
        UserTypeAttributeTrait,
40
        UserStateAttributeTrait,
41
        OrganizationTypeAttributeTrait;
42
43
    /**
44
     * @var mixed When the resulting organizations must have joined.
45
     */
46
    public $dateJoined;
47
48
    /**
49
     * @inheritdoc
50
     */
51
    protected $defaultOrderBy = ['dateJoined' => SORT_DESC];
52
53
    /**
54
     * @inheritdoc
55
     * @throws QueryAbortedException
56
     */
57
    protected function beforePrepare(): bool
58
    {
59
        if (false === ($result = parent::beforePrepare())) {
60
            return false;
61
        }
62
63
        $alias = OrganizationRecord::tableAlias();
64
        $this->joinElementTable($alias);
65
66
        $this->query->select([
67
            $alias . '.dateJoined'
68
        ]);
69
70
        $this->prepareRelationsParams();
71
        $this->prepareAttributes($alias);
72
73
        return true;
74
    }
75
76
    /**
77
     * Prepares simple attributes
78
     *
79
     * @var string $alias
80
     */
81
    protected function prepareAttributes(string $alias)
82
    {
83
        if ($this->dateJoined) {
84
            $this->subQuery->andWhere(Db::parseDateParam($alias . '.dateJoined', $this->dateJoined));
85
        }
86
    }
87
88
    /**
89
     * @throws QueryAbortedException
90
     */
91
    protected function prepareRelationsParams()
92
    {
93
        // Type
94
        $this->applyTypeParam();
95
96
        if (empty($this->user) && empty($this->userGroup) && empty($this->userType)) {
97
            return;
98
        }
99
100
        $alias = $this->joinOrganizationUserTable();
101
102
        $this->applyUserParam($alias);
103
        $this->applyUserGroupParam($alias);
104
        $this->applyUserTypeParam($alias);
105
        $this->applyUserStateParam($alias);
106
    }
107
108
109
    /************************************************************
110
     * JOIN TABLES
111
     ************************************************************/
112
113
    /**
114
     * @return string
115
     */
116
    protected function joinOrganizationUserTable(): string
117
    {
118
        $alias = OrganizationUsersRecord::tableAlias();
119
120
        $this->subQuery->innerJoin(
121
            OrganizationUsersRecord::tableName() . ' ' . $alias,
122
            '[[' . $alias . '.organizationId]] = [[elements.id]]'
123
        );
124
125
        // Check if we're ordering by one of the association tables order columns
126
        if (is_array($this->orderBy)) {
127
            $columns = ['userOrder' => 'userOrder', 'organizationOrder' => 'organizationOrder'];
128
            $matches = array_intersect_key($columns, $this->orderBy);
129
130
            foreach ($matches as $param => $select) {
131
                $this->subQuery->addSelect([$alias . '.' . $select]);
132
            }
133
        }
134
135
        return $alias;
136
    }
137
138
    /**
139
     * @return string
140
     */
141
    protected function joinOrganizationTypeTable(): string
142
    {
143
        $alias = TypeAssociationRecord::tableAlias();
144
145
        $this->subQuery->leftJoin(
146
            TypeAssociationRecord::tableName() . ' ' . $alias,
147
            '[[' . $alias . '.organizationId]] = [[elements.id]]'
148
        );
149
150
        return $alias;
151
    }
152
153
154
    /************************************************************
155
     * USER
156
     ************************************************************/
157
158
    /**
159
     * @param string $alias
160
     *
161
     * @return void
162
     * @throws QueryAbortedException
163
     */
164
    protected function applyUserParam(string $alias)
165
    {
166
        // Is the query already doomed?
167
        if ($this->user !== null && empty($this->user)) {
168
            throw new QueryAbortedException();
169
        }
170
171
        if (empty($this->user)) {
172
            return;
173
        }
174
175
        $this->subQuery->andWhere(
176
            Db::parseParam($alias . '.userId', $this->parseUserValue($this->user))
177
        );
178
    }
179
180
181
    /************************************************************
182
     * USER GROUP
183
     ************************************************************/
184
185
    /**
186
     * @param string $alias
187
     *
188
     * @return void
189
     * @throws QueryAbortedException
190
     */
191
    protected function applyUserGroupParam(string $alias)
192
    {
193
        // Is the query already doomed?
194
        if ($this->userGroup !== null && empty($this->userGroup)) {
195
            throw new QueryAbortedException();
196
        }
197
198
        if (empty($this->userGroup)) {
199
            return;
200
        }
201
202
        $groupAlias = 'ug_user';
203
204
        $this->subQuery->innerJoin(
205
            UserGroupUsersRecord::tableName() . ' ' . $groupAlias,
206
            '[[' . $groupAlias . '.userId]] = [[' . $alias . '.userId]]'
207
        );
208
209
        $this->subQuery->andWhere(
210
            Db::parseParam($groupAlias . '.groupId', $this->parseUserGroupValue($this->userGroup))
211
        );
212
    }
213
214
215
    /************************************************************
216
     * USER TYPE
217
     ************************************************************/
218
219
    /**
220
     * @param string $alias
221
     *
222
     * @return void
223
     * @throws QueryAbortedException
224
     */
225
    protected function applyUserTypeParam(string $alias)
226
    {
227
        // Is the query already doomed?
228
        if ($this->userType !== null && empty($this->userType)) {
229
            throw new QueryAbortedException();
230
        }
231
232
        if (empty($this->userType)) {
233
            return;
234
        }
235
236
        $typeAlias = 'ut_user';
237
238
        $this->subQuery->innerJoin(
239
            UserTypeAssociationRecord::tableName() . ' ' . $typeAlias,
240
            '[[' . $typeAlias . '.userId]] = [[' . $alias . '.userId]]'
241
        );
242
243
        $this->subQuery->andWhere(
244
            Db::parseParam($typeAlias . '.typeId', $this->parseUserTypeValue($this->userType))
245
        );
246
    }
247
248
249
    /************************************************************
250
     * USER STATE
251
     ************************************************************/
252
253
    /**
254
     * @param string $alias
255
     *
256
     * @return void
257
     * @throws QueryAbortedException
258
     */
259
    protected function applyUserStateParam(string $alias)
260
    {
261
        // Is the query already doomed?
262
        if ($this->userState !== null && empty($this->userState)) {
263
            throw new QueryAbortedException();
264
        }
265
266
        if (empty($this->userState)) {
267
            return;
268
        }
269
270
        $this->subQuery->andWhere(
271
            Db::parseParam($alias . '.state', $this->userState)
272
        );
273
    }
274
275
276
    /************************************************************
277
     * TYPE
278
     ************************************************************/
279
280
    /**
281
     * @return void
282
     * @throws QueryAbortedException
283
     */
284
    protected function applyTypeParam()
285
    {
286
        // Is the query already doomed?
287
        if ($this->organizationType !== null && empty($this->organizationType)) {
288
            throw new QueryAbortedException();
289
        }
290
291
        if (empty($this->organizationType)) {
292
            return;
293
        }
294
295
        $alias = $this->joinOrganizationTypeTable();
296
297
        $this->subQuery
298
            ->andWhere(
299
                Db::parseParam($alias . '.typeId', $this->parseOrganizationTypeValue($this->organizationType))
300
            );
301
    }
302
}
303