Completed
Push — master ( b27204...a2c64d )
by Nate
05:15 queued 02:48
created

OrganizationQuery::prepareRelationsParams()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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