Completed
Push — develop ( 2c76d9...35dfd0 )
by Nate
09:57
created

ModifyElementsQueryTrait   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 3
dl 0
loc 99
ccs 0
cts 70
cp 0
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A modifyElementsQuery() 0 17 5
A modifyElementsQueryForStringValue() 0 13 4
A modifyElementsQueryForTargetValue() 0 18 1
A modifyElementsQueryForEmptyValue() 0 13 2
A emptyValueSubSelect() 0 10 1
1
<?php
2
/**
3
 * @copyright  Copyright (c) Flipbox Digital Limited
4
 * @license    https://github.com/flipboxfactory/craft-sortable-associations/blob/master/LICENSE
5
 * @link       https://github.com/flipboxfactory/craft-sortable-associations
6
 */
7
8
namespace flipbox\craft\domains\fields;
9
10
use craft\elements\db\ElementQuery;
11
use craft\elements\db\ElementQueryInterface;
12
use craft\helpers\Db;
13
use flipbox\craft\domains\records\Domain;
14
15
/**
16
 * @author Flipbox Factory <[email protected]>
17
 * @since 1.0.0
18
 *
19
 * @property int $id
20
 */
21
trait ModifyElementsQueryTrait
22
{
23
    /**
24
     * @inheritdoc
25
     */
26
    public function modifyElementsQuery(
27
        ElementQueryInterface $query,
28
        $value
29
    ) {
30
        if ($value === null || !$query instanceof ElementQuery) {
31
            return null;
32
        }
33
        if ($value === false) {
34
            return false;
35
        }
36
        if (is_string($value)) {
37
            $this->modifyElementsQueryForStringValue($query, $value);
38
            return null;
39
        }
40
        $this->modifyElementsQueryForTargetValue($query, $value);
41
        return null;
42
    }
43
44
    /**
45
     * @param ElementQuery $query
46
     * @param string $value
47
     */
48
    protected function modifyElementsQueryForStringValue(
49
        ElementQuery $query,
50
        string $value
51
    ) {
52
        if ($value === 'not :empty:') {
53
            $value = ':notempty:';
54
        }
55
        if ($value === ':notempty:' || $value === ':empty:') {
56
            $this->modifyElementsQueryForEmptyValue($query, $value);
57
            return;
58
        }
59
        $this->modifyElementsQueryForTargetValue($query, $value);
60
    }
61
62
    /**
63
     * @param ElementQuery $query
64
     * @param $value
65
     */
66
    protected function modifyElementsQueryForTargetValue(
67
        ElementQuery $query,
68
        $value
69
    ) {
70
        $alias = Domain::tableAlias();
71
        $name = Domain::tableName();
72
73
        $joinTable = "{$name} {$alias}";
74
        $query->query->innerJoin($joinTable, "[[{$alias}.elementId]] = [[subquery.elementsId]]");
75
        $query->subQuery->innerJoin($joinTable, "[[{$alias}.elementId]] = [[elements.id]]");
76
        $query->subQuery->andWhere(
77
            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...
78
        );
79
        $query->subQuery->andWhere(
80
            Db::parseParam($alias . '.domain', $value)
1 ignored issue
show
Bug introduced by
It seems like \craft\helpers\Db::parse...as . '.domain', $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...
81
        );
82
        $query->query->distinct(true);
83
    }
84
85
    /**
86
     * @param ElementQuery $query
87
     * @param string $value
88
     */
89
    protected function modifyElementsQueryForEmptyValue(
90
        ElementQuery $query,
91
        string $value
92
    ) {
93
        $operator = ($value === ':notempty:' ? '!=' : '=');
94
        $query->subQuery->andWhere(
95
            $this->emptyValueSubSelect(
0 ignored issues
show
Documentation introduced by
$this->emptyValueSubSele...tableName(), $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...
96
                Domain::tableAlias(),
97
                Domain::tableName(),
98
                $operator
99
            )
100
        );
101
    }
102
103
    /**
104
     * @param string $alias
105
     * @param string $name
106
     * @param string $operator
107
     * @return string
108
     */
109
    protected function emptyValueSubSelect(
110
        string $alias,
111
        string $name,
112
        string $operator
113
    ): string {
114
        return "(select count([[{$alias}.elementId]]) from " .
115
            $name .
116
            " {{{$alias}}} where [[{$alias}.elementId" .
117
            "]] = [[elements.id]] and [[{$alias}.fieldId]] = {$this->id}) {$operator} 0";
118
    }
119
}