Completed
Push — master ( 0a7f4f...30aa45 )
by Nate
08:01 queued 34s
created

ModifyElementQueryTrait   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 4
dl 0
loc 128
ccs 0
cts 85
cp 0
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B modifyElementsQuery() 0 23 6
A modifyElementsQueryForArrayValue() 0 15 3
A modifyElementsQueryForStringValue() 0 16 4
A modifyElementsQueryForTargetValue() 0 30 3
A modifyElementsQueryForEmptyValue() 0 15 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-element-lists/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-element-lists/
7
 */
8
9
namespace flipbox\craft\element\lists\fields;
10
11
use craft\elements\db\ElementQuery;
12
use craft\elements\db\ElementQueryInterface;
13
use craft\helpers\Db;
14
use flipbox\craft\element\lists\records\Association;
15
use flipbox\craft\ember\helpers\ArrayHelper;
16
17
/**
18
 * @author Flipbox Factory <[email protected]>
19
 * @since 2.0.0
20
 *
21
 * @property int|null id
22
 */
23
trait ModifyElementQueryTrait
24
{
25
    /**
26
     * @inheritdoc
27
     */
28
    public function modifyElementsQuery(ElementQueryInterface $query, $value)
29
    {
30
        if ($value === null || !$query instanceof ElementQuery) {
31
            return null;
32
        }
33
34
        if ($value === false) {
35
            return false;
36
        }
37
38
        if (is_array($value)) {
39
            $this->modifyElementsQueryForArrayValue($query, $value);
40
            return null;
41
        }
42
43
        if (is_string($value)) {
44
            $this->modifyElementsQueryForStringValue($query, $value);
45
            return null;
46
        }
47
48
        $this->modifyElementsQueryForTargetValue($query, $value);
49
        return null;
50
    }
51
52
    /**
53
     * @param ElementQuery $query
54
     * @param array $value
55
     * @return void
56
     */
57
    protected function modifyElementsQueryForArrayValue(
58
        ElementQuery $query,
59
        array $value
60
    ) {
61
        if (array_key_exists('source', $value)) {
62
            $this->modifyElementsQueryForStringValue(
63
                $query,
64
                $value['source'] ?: ':empty:',
65
                ArrayHelper::remove($value, 'sourceSiteId')
66
            );
67
            return null;
68
        }
69
70
        $this->modifyElementsQueryForTargetValue($query, $value);
71
    }
72
73
    /**
74
     * @param ElementQuery $query
75
     * @param string $value
76
     * @param $siteId
77
     */
78
    protected function modifyElementsQueryForStringValue(
79
        ElementQuery $query,
80
        string $value,
81
        $siteId = null
82
    ) {
83
        if ($value === 'not :empty:') {
84
            $value = ':notempty:';
85
        }
86
87
        if ($value === ':notempty:' || $value === ':empty:') {
88
            $this->modifyElementsQueryForEmptyValue($query, $value);
89
            return;
90
        }
91
92
        $this->modifyElementsQueryForTargetValue($query, $value, $siteId);
93
    }
94
95
    /**
96
     * @param ElementQuery $query
97
     * @param $sourceId
98
     * @param $siteId
99
     */
100
    protected function modifyElementsQueryForTargetValue(
101
        ElementQuery $query,
102
        $sourceId,
103
        $siteId = null
104
    ) {
105
        $alias = Association::tableAlias();
106
        $name = Association::tableName();
107
108
        $joinTable = "{$name} {$alias}";
109
        $query->query->innerJoin($joinTable, "[[{$alias}.targetId]] = [[subquery.elementsId]]");
110
        $query->subQuery->innerJoin($joinTable, "[[{$alias}.targetId]] = [[elements.id]]");
111
112
        $query->subQuery->addSelect(["{$alias}.sortOrder"]);
113
114
        $query->subQuery->andWhere(
115
            Db::parseParam($alias . '.fieldId', $this->id)
116
        );
117
118
        $query->subQuery->andWhere(
119
            Db::parseParam($alias . '.sourceId', $sourceId)
120
        );
121
122
        if ($this->localizeRelations && $siteId) {
0 ignored issues
show
Bug introduced by
The property localizeRelations does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
123
            $query->subQuery->andWhere(
124
                Db::parseParam($alias . '.sourceSiteId', $siteId)
125
            );
126
        }
127
128
        $query->query->distinct(true);
129
    }
130
131
    /**
132
     * @param ElementQuery $query
133
     * @param string $value
134
     */
135
    protected function modifyElementsQueryForEmptyValue(
136
        ElementQuery $query,
137
        string $value
138
    ) {
139
        $alias = Association::tableAlias();
140
        $name = Association::tableName();
141
142
        $operator = ($value === ':notempty:' ? '!=' : '=');
143
        $query->subQuery->andWhere(
144
            "(select count([[{$alias}.targetId]]) from " .
145
            $name .
146
            " {{{$alias}}} where [[{$alias}.targetId" .
147
            "]] = [[elements.id]] and [[{$alias}.fieldId]] = {$this->id}) {$operator} 0"
148
        );
149
    }
150
}
151