Completed
Push — develop ( a13565...8d3950 )
by Nate
09:35
created

modifyElementsQueryForStringValue()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 14
cp 0
rs 9.7
c 0
b 0
f 0
nc 4
cc 4
nop 2
crap 20
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-integration/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-integration/
7
 */
8
9
namespace flipbox\craft\integration\fields;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\base\ElementInterface;
14
use craft\base\Field;
15
use craft\elements\db\ElementQuery;
16
use craft\elements\db\ElementQueryInterface;
17
use craft\helpers\Component as ComponentHelper;
18
use craft\helpers\Db;
19
use craft\helpers\StringHelper;
20
use flipbox\craft\ember\helpers\ModelHelper;
21
use flipbox\craft\ember\records\ActiveRecord;
22
use flipbox\craft\ember\validators\MinMaxValidator;
23
use flipbox\craft\integration\events\RegisterIntegrationFieldActionsEvent;
24
use flipbox\craft\integration\fields\actions\IntegrationActionInterface;
25
use flipbox\craft\integration\fields\actions\IntegrationItemActionInterface;
26
use flipbox\craft\integration\queries\IntegrationAssociationQuery;
27
use flipbox\craft\integration\records\IntegrationAssociation;
28
use flipbox\craft\integration\web\assets\integrations\Integrations as IntegrationsAsset;
29
use yii\base\Exception;
30
use yii\helpers\ArrayHelper;
31
32
/**
33
 * @author Flipbox Factory <[email protected]>
34
 * @since 1.0.0
35
 *
36
 * @property int|null id
37
 */
38
trait ModifyElementQueryTrait
39
{
40
    /**
41
     * @return string
42
     */
43
    abstract protected static function tableAlias(): string;
44
45
    /**
46
     * @inheritdoc
47
     */
48
    public function modifyElementsQuery(ElementQueryInterface $query, $value)
49
    {
50
        if ($value === null || !$query instanceof ElementQuery) {
51
            return null;
52
        }
53
54
        if ($value === false) {
55
            return false;
56
        }
57
58
        if (is_string($value)) {
59
            $this->modifyElementsQueryForStringValue($query, $value);
60
            return null;
61
        }
62
63
        $this->modifyElementsQueryForTargetValue($query, $value);
64
        return null;
65
    }
66
67
    /**
68
     * @param ElementQuery $query
69
     * @param string $value
70
     */
71
    protected function modifyElementsQueryForStringValue(
72
        ElementQuery $query,
73
        string $value
74
    )
75
    {
76
77
        if ($value === 'not :empty:') {
78
            $value = ':notempty:';
79
        }
80
81
        if ($value === ':notempty:' || $value === ':empty:') {
82
            $this->modifyElementsQueryForEmptyValue($query, $value);
83
            return;
84
        }
85
86
        $this->modifyElementsQueryForTargetValue($query, $value);
87
    }
88
89
    /**
90
     * @param ElementQuery $query
91
     * @param $value
92
     */
93
    protected function modifyElementsQueryForTargetValue(
94
        ElementQuery $query,
95
        $value
96
    )
97
    {
98
99
        $alias = $this->tableAlias();
100
        $name = '{{%' . $this->tableAlias() . '}}';
101
102
        $joinTable = "{$name} {$alias}";
103
        $query->query->innerJoin($joinTable, "[[{$alias}.elementId]] = [[subquery.elementsId]]");
104
        $query->subQuery->innerJoin($joinTable, "[[{$alias}.elementId]] = [[elements.id]]");
105
106
        $query->subQuery->andWhere(
107
            Db::parseParam($alias . '.fieldId', $this->id)
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse... '.fieldId', $this->id) targeting craft\helpers\Db::parseParam() can also be of type string; however, craft\db\Query::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...
108
        );
109
110
        $query->subQuery->andWhere(
111
            Db::parseParam($alias . '.objectId', $value)
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse... . '.objectId', $value) targeting craft\helpers\Db::parseParam() can also be of type string; however, craft\db\Query::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...
112
        );
113
114
        $query->query->distinct(true);
115
    }
116
117
    /**
118
     * @param ElementQuery $query
119
     * @param string $value
120
     */
121
    protected function modifyElementsQueryForEmptyValue(
122
        ElementQuery $query,
123
        string $value
124
    )
125
    {
126
127
        $operator = ($value === ':notempty:' ? '!=' : '=');
128
        $query->subQuery->andWhere(
129
            $this->emptyValueSubSelect(
0 ignored issues
show
Documentation introduced by
$this->emptyValueSubSele...as() . '}}', $operator) is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
130
                $this->tableAlias(),
131
                '{{%' . $this->tableAlias() . '}}',
132
                $operator
133
            )
134
        );
135
    }
136
137
    /**
138
     * @param string $alias
139
     * @param string $name
140
     * @param string $operator
141
     * @return string
142
     */
143
    protected function emptyValueSubSelect(
144
        string $alias,
145
        string $name,
146
        string $operator
147
    ): string
148
    {
149
150
        return "(select count([[{$alias}.elementId]]) from " .
151
            $name .
152
            " {{{$alias}}} where [[{$alias}.elementId" .
153
            "]] = [[elements.id]] and [[{$alias}.fieldId]] = {$this->id}) {$operator} 0";
154
    }
155
}