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