Completed
Push — master ( fa2880...7af5aa )
by Nate
01:12
created

ModifyElementQueryTrait   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 2
dl 0
loc 118
ccs 0
cts 68
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
tableAlias() 0 1 ?
A modifyElementsQuery() 0 18 5
A modifyElementsQueryForStringValue() 0 17 4
A modifyElementsQueryForTargetValue() 0 23 1
A modifyElementsQueryForEmptyValue() 0 15 2
A emptyValueSubSelect() 0 12 1
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\elements\db\ElementQuery;
12
use craft\elements\db\ElementQueryInterface;
13
use craft\helpers\Db;
14
15
/**
16
 * @author Flipbox Factory <[email protected]>
17
 * @since 1.0.0
18
 *
19
 * @property int|null id
20
 */
21
trait ModifyElementQueryTrait
22
{
23
    /**
24
     * @return string
25
     */
26
    abstract protected static function tableAlias(): string;
27
28
    /**
29
     * @inheritdoc
30
     */
31
    public function modifyElementsQuery(ElementQueryInterface $query, $value)
32
    {
33
        if ($value === null || !$query instanceof ElementQuery) {
34
            return null;
35
        }
36
37
        if ($value === false) {
38
            return false;
39
        }
40
41
        if (is_string($value)) {
42
            $this->modifyElementsQueryForStringValue($query, $value);
43
            return null;
44
        }
45
46
        $this->modifyElementsQueryForTargetValue($query, $value);
47
        return null;
48
    }
49
50
    /**
51
     * @param ElementQuery $query
52
     * @param string $value
53
     */
54
    protected function modifyElementsQueryForStringValue(
55
        ElementQuery $query,
56
        string $value
57
    ) {
58
    
59
60
        if ($value === 'not :empty:') {
61
            $value = ':notempty:';
62
        }
63
64
        if ($value === ':notempty:' || $value === ':empty:') {
65
            $this->modifyElementsQueryForEmptyValue($query, $value);
66
            return;
67
        }
68
69
        $this->modifyElementsQueryForTargetValue($query, $value);
70
    }
71
72
    /**
73
     * @param ElementQuery $query
74
     * @param $value
75
     */
76
    protected function modifyElementsQueryForTargetValue(
77
        ElementQuery $query,
78
        $value
79
    ) {
80
    
81
82
        $alias = $this->tableAlias();
83
        $name = '{{%' . $this->tableAlias() . '}}';
84
85
        $joinTable = "{$name} {$alias}";
86
        $query->query->innerJoin($joinTable, "[[{$alias}.elementId]] = [[subquery.elementsId]]");
87
        $query->subQuery->innerJoin($joinTable, "[[{$alias}.elementId]] = [[elements.id]]");
88
89
        $query->subQuery->andWhere(
90
            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...
91
        );
92
93
        $query->subQuery->andWhere(
94
            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...
95
        );
96
97
        $query->query->distinct(true);
98
    }
99
100
    /**
101
     * @param ElementQuery $query
102
     * @param string $value
103
     */
104
    protected function modifyElementsQueryForEmptyValue(
105
        ElementQuery $query,
106
        string $value
107
    ) {
108
    
109
110
        $operator = ($value === ':notempty:' ? '!=' : '=');
111
        $query->subQuery->andWhere(
112
            $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...
113
                $this->tableAlias(),
114
                '{{%' . $this->tableAlias() . '}}',
115
                $operator
116
            )
117
        );
118
    }
119
120
    /**
121
     * @param string $alias
122
     * @param string $name
123
     * @param string $operator
124
     * @return string
125
     */
126
    protected function emptyValueSubSelect(
127
        string $alias,
128
        string $name,
129
        string $operator
130
    ): string {
131
    
132
133
        return "(select count([[{$alias}.elementId]]) from " .
134
            $name .
135
            " {{{$alias}}} where [[{$alias}.elementId" .
136
            "]] = [[elements.id]] and [[{$alias}.fieldId]] = {$this->id}) {$operator} 0";
137
    }
138
}
139