Completed
Branch develop (17e8cf)
by Nate
10:01
created

AssociationQuery::prepare()   B

Complexity

Conditions 10
Paths 9

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 0
cts 22
cp 0
rs 7.6666
c 0
b 0
f 0
cc 10
nc 9
nop 1
crap 110

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://www.flipboxfactory.com/software/element-lists/license
6
 * @link       https://www.flipboxfactory.com/software/element-lists/
7
 */
8
9
namespace flipbox\craft\element\lists\queries;
10
11
use Craft;
12
use craft\db\QueryAbortedException;
13
use craft\helpers\Db;
14
use flipbox\craft\ember\helpers\QueryHelper;
15
use flipbox\craft\ember\queries\AuditAttributesTrait;
16
use flipbox\craft\ember\queries\CacheableActiveQuery;
17
use flipbox\craft\ember\queries\FieldAttributeTrait;
18
use flipbox\craft\ember\queries\SiteAttributeTrait;
19
use flipbox\craft\integration\records\IntegrationAssociation;
20
use yii\db\Query;
21
22
/**
23
 * @author Flipbox Factory <[email protected]>
24
 * @since 2.0.0
25
 *
26
 * @method IntegrationAssociation[] getCachedResult()
27
 * @method IntegrationAssociation[] all()
28
 * @method IntegrationAssociation one()
29
 */
30
class AssociationQuery extends CacheableActiveQuery
31
{
32
    use AuditAttributesTrait,
33
        FieldAttributeTrait,
34
        SiteAttributeTrait;
35
36
    /**
37
     * @var int|null Sort order
38
     */
39
    public $sortOrder;
40
41
    /**
42
     * @var string|string[]|null
43
     */
44
    public $target;
45
46
    /**
47
     * @var string|string[]|null
48
     */
49
    public $source;
50
51
    /**
52
     * @param $value
53
     * @return $this
54
     */
55
    public function sortOrder($value)
56
    {
57
        $this->sortOrder = $value;
58
        return $this;
59
    }
60
61
    /**
62
     * @param $value
63
     * @return $this
64
     */
65
    public function setSortOrder($value)
66
    {
67
        return $this->sortOrder($value);
68
    }
69
70
    /**
71
     * @param int|int[]|null $value
72
     * @return static
73
     */
74
    public function setTargetId($value)
75
    {
76
        return $this->setTarget($value);
77
    }
78
79
    /**
80
     * @param int|int[]|null $value
81
     * @return static
82
     */
83
    public function targetId($value)
84
    {
85
        return $this->setTarget($value);
86
    }
87
88
    /**
89
     * @param int|int[]|null $value
90
     * @return static
91
     */
92
    public function setTarget($value)
93
    {
94
        $this->target = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value can also be of type integer or array<integer,integer>. However, the property $target is declared as type string|array<integer,string>|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
95
        return $this;
96
    }
97
98
    /**
99
     * @param int|int[]|null $value
100
     * @return static
101
     */
102
    public function target($value)
103
    {
104
        return $this->setTarget($value);
105
    }
106
107
108
    /**
109
     * @param int|int[]|null $value
110
     * @return static
111
     */
112
    public function setSourceId($value)
113
    {
114
        return $this->setSource($value);
115
    }
116
117
    /**
118
     * @param int|int[]|null $value
119
     * @return static
120
     */
121
    public function sourceId($value)
122
    {
123
        return $this->setSource($value);
124
    }
125
126
    /**
127
     * @param int|int[]|null $value
128
     * @return static
129
     */
130
    public function setSource($value)
131
    {
132
        $this->source = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value can also be of type integer or array<integer,integer>. However, the property $source is declared as type string|array<integer,string>|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
133
        return $this;
134
    }
135
136
    /**
137
     * @param int|int[]|null $value
138
     * @return static
139
     */
140
    public function source($value)
141
    {
142
        return $this->setSource($value);
143
    }
144
145
    /**
146
     * @inheritdoc
147
     */
148
    public function init()
149
    {
150
        parent::init();
151
152
        if ($this->select === null) {
153
            $this->select = ['*'];
154
        }
155
156
        if ($this->orderBy === null) {
157
            $this->orderBy = ['sortOrder' => SORT_ASC];
158
        }
159
    }
160
161
    /**
162
     * @inheritdoc
163
     * @throws QueryAbortedException
164
     */
165
    public function prepare($builder)
166
    {
167
        // Is the query already doomed?
168
        if (($this->field !== null && empty($this->field)) ||
169
            ($this->target !== null && empty($this->target)) ||
170
            ($this->source !== null && empty($this->source))
171
        ) {
172
            throw new QueryAbortedException();
173
        }
174
175
        $this->applyFieldConditions();
176
        $this->applySiteConditions();
177
        $this->applyAuditAttributeConditions();
178
179
        if ($this->sortOrder !== null) {
180
            $this->andWhere(Db::parseParam('sortOrder', $this->sortOrder));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...der', $this->sortOrder) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
181
        }
182
183
        if ($this->target !== null) {
184
            $this->andWhere(Db::parseParam('targetId', $this->parseElementValue($this->target)));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...ntValue($this->target)) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
185
        }
186
187
        if ($this->source !== null) {
188
            $this->andWhere(Db::parseParam('sourceId', $this->parseElementValue($this->source)));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...ntValue($this->source)) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
189
        }
190
191
        return parent::prepare($builder);
192
    }
193
194
    /**
195
     * Apply attribute conditions
196
     */
197
    protected function applyFieldConditions()
198
    {
199
        if ($this->field !== null) {
200
            $this->andWhere(Db::parseParam('fieldId', $this->parseFieldValue($this->field)));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...eldValue($this->field)) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
201
        }
202
    }
203
204
    /**
205
     * Apply attribute conditions
206
     */
207
    protected function applySiteConditions()
208
    {
209
        if ($this->site !== null) {
210
            $this->andWhere(Db::parseParam('siteId', $this->parseSiteValue($this->site)));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...SiteValue($this->site)) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
211
        } else {
212
            $this->andWhere(Db::parseParam('siteId', Craft::$app->getSites()->currentSite->id));
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...tes()->currentSite->id) targeting craft\helpers\Db::parseParam() can also be of type string; however, flipbox\craft\ember\quer...ActiveQuery::andWhere() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
213
        }
214
    }
215
216
    /**
217
     * @param $value
218
     * @return array|string
219
     */
220
    protected function parseElementValue($value)
221
    {
222
        return QueryHelper::prepareParam(
223
            $value,
224
            function (string $uri) {
225
                $value = (new Query())
226
                    ->select(['id'])
227
                    ->from(['{{%elements_sites}} elements_sites'])
228
                    ->where(['uri' => $uri])
229
                    ->scalar();
230
                return empty($value) ? false : $value;
231
            }
232
        );
233
    }
234
}
235