OrganizationQuery   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 14
dl 0
loc 267
ccs 0
cts 129
cp 0
rs 9.84
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A beforePrepare() 0 18 2
A prepareAttributes() 0 6 2
A prepareRelationsParams() 0 16 4
A joinOrganizationUserTable() 0 21 3
A joinOrganizationTypeTable() 0 11 1
A applyUserParam() 0 15 4
A applyUserGroupParam() 0 22 4
A applyUserTypeParam() 0 22 4
A applyUserStateParam() 0 15 4
A applyTypeParam() 0 18 4
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
     */
56
    protected function beforePrepare(): bool
57
    {
58
        if (false === ($result = parent::beforePrepare())) {
59
            return false;
60
        }
61
62
        $alias = OrganizationRecord::tableAlias();
63
        $this->joinElementTable($alias);
64
65
        $this->query->select([
66
            $alias . '.dateJoined'
67
        ]);
68
69
        $this->prepareRelationsParams();
70
        $this->prepareAttributes($alias);
71
72
        return true;
73
    }
74
75
    /**
76
     * Prepares simple attributes
77
     *
78
     * @var string $alias
79
     */
80
    protected function prepareAttributes(string $alias)
81
    {
82
        if ($this->dateJoined) {
83
            $this->subQuery->andWhere(Db::parseDateParam($alias . '.dateJoined', $this->dateJoined));
84
        }
85
    }
86
87
    /**
88
     * Prepares relation params
89
     */
90
    protected function prepareRelationsParams()
91
    {
92
        // Type
93
        $this->applyTypeParam();
94
95
        if (empty($this->user) && empty($this->userGroup) && empty($this->userType)) {
96
            return;
97
        }
98
99
        $alias = $this->joinOrganizationUserTable();
100
101
        $this->applyUserParam($alias);
102
        $this->applyUserGroupParam($alias);
103
        $this->applyUserTypeParam($alias);
104
        $this->applyUserStateParam($alias);
105
    }
106
107
108
    /************************************************************
109
     * JOIN TABLES
110
     ************************************************************/
111
112
    /**
113
     * @return string
114
     */
115
    protected function joinOrganizationUserTable(): string
116
    {
117
        $alias = OrganizationUsersRecord::tableAlias();
118
119
        $this->subQuery->innerJoin(
120
            OrganizationUsersRecord::tableName() . ' ' . $alias,
121
            '[[' . $alias . '.organizationId]] = [[elements.id]]'
122
        );
123
124
        // Check if we're ordering by one of the association tables order columns
125
        if (is_array($this->orderBy)) {
126
            $columns = ['userOrder' => 'userOrder', 'organizationOrder' => 'organizationOrder'];
127
            $matches = array_intersect_key($columns, $this->orderBy);
128
129
            foreach ($matches as $param => $select) {
130
                $this->subQuery->addSelect([$alias . '.' . $select]);
131
            }
132
        }
133
134
        return $alias;
135
    }
136
137
    /**
138
     * @return string
139
     */
140
    protected function joinOrganizationTypeTable(): string
141
    {
142
        $alias = TypeAssociationRecord::tableAlias();
143
144
        $this->subQuery->leftJoin(
145
            TypeAssociationRecord::tableName() . ' ' . $alias,
146
            '[[' . $alias . '.organizationId]] = [[elements.id]]'
147
        );
148
149
        return $alias;
150
    }
151
152
153
    /************************************************************
154
     * USER
155
     ************************************************************/
156
157
    /**
158
     * @param string $alias
159
     *
160
     * @return void
161
     * @throws QueryAbortedException
162
     */
163
    protected function applyUserParam(string $alias)
164
    {
165
        // Is the query already doomed?
166
        if ($this->user !== null && empty($this->user)) {
167
            throw new QueryAbortedException();
168
        }
169
170
        if (empty($this->user)) {
171
            return;
172
        }
173
174
        $this->subQuery->andWhere(
175
            Db::parseParam($alias . '.userId', $this->parseUserValue($this->user))
176
        );
177
    }
178
179
180
    /************************************************************
181
     * USER GROUP
182
     ************************************************************/
183
184
    /**
185
     * @param string $alias
186
     *
187
     * @return void
188
     * @throws QueryAbortedException
189
     */
190
    protected function applyUserGroupParam(string $alias)
191
    {
192
        // Is the query already doomed?
193
        if ($this->userGroup !== null && empty($this->userGroup)) {
194
            throw new QueryAbortedException();
195
        }
196
197
        if (empty($this->userGroup)) {
198
            return;
199
        }
200
201
        $groupAlias = 'ug_user';
202
203
        $this->subQuery->innerJoin(
204
            UserGroupUsersRecord::tableName() . ' ' . $groupAlias,
205
            '[[' . $groupAlias . '.userId]] = [[' . $alias . '.userId]]'
206
        );
207
208
        $this->subQuery->andWhere(
209
            Db::parseParam($groupAlias . '.groupId', $this->parseUserGroupValue($this->userGroup))
210
        );
211
    }
212
213
214
    /************************************************************
215
     * USER TYPE
216
     ************************************************************/
217
218
    /**
219
     * @param string $alias
220
     *
221
     * @return void
222
     * @throws QueryAbortedException
223
     */
224
    protected function applyUserTypeParam(string $alias)
225
    {
226
        // Is the query already doomed?
227
        if ($this->userType !== null && empty($this->userType)) {
228
            throw new QueryAbortedException();
229
        }
230
231
        if (empty($this->userType)) {
232
            return;
233
        }
234
235
        $typeAlias = 'ut_user';
236
237
        $this->subQuery->innerJoin(
238
            UserTypeAssociationRecord::tableName() . ' ' . $typeAlias,
239
            '[[' . $typeAlias . '.userId]] = [[' . $alias . '.userId]]'
240
        );
241
242
        $this->subQuery->andWhere(
243
            Db::parseParam($typeAlias . '.typeId', $this->parseUserTypeValue($this->userType))
244
        );
245
    }
246
247
248
    /************************************************************
249
     * USER STATE
250
     ************************************************************/
251
252
    /**
253
     * @param string $alias
254
     *
255
     * @return void
256
     * @throws QueryAbortedException
257
     */
258
    protected function applyUserStateParam(string $alias)
259
    {
260
        // Is the query already doomed?
261
        if ($this->userState !== null && empty($this->userState)) {
262
            throw new QueryAbortedException();
263
        }
264
265
        if (empty($this->userState)) {
266
            return;
267
        }
268
269
        $this->subQuery->andWhere(
270
            Db::parseParam($alias . '.state', $this->userState)
271
        );
272
    }
273
274
275
    /************************************************************
276
     * TYPE
277
     ************************************************************/
278
279
    /**
280
     * @return void
281
     * @throws QueryAbortedException
282
     */
283
    protected function applyTypeParam()
284
    {
285
        // Is the query already doomed?
286
        if ($this->organizationType !== null && empty($this->organizationType)) {
287
            throw new QueryAbortedException();
288
        }
289
290
        if (empty($this->organizationType)) {
291
            return;
292
        }
293
294
        $alias = $this->joinOrganizationTypeTable();
295
296
        $this->subQuery
297
            ->andWhere(
298
                Db::parseParam($alias . '.typeId', $this->parseOrganizationTypeValue($this->organizationType))
299
            );
300
    }
301
}
302