1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the DoctrineDatabase base field value Handler class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\FieldValue; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\Core\Persistence\Database\DatabaseHandler; |
12
|
|
|
use eZ\Publish\API\Repository\Values\Content\Query\Criterion; |
13
|
|
|
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Operator as CriterionOperator; |
14
|
|
|
use eZ\Publish\Core\Persistence\Database\SelectQuery; |
15
|
|
|
use eZ\Publish\Core\Persistence\TransformationProcessor; |
16
|
|
|
use RuntimeException; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Content locator gateway implementation using the DoctrineDatabase. |
20
|
|
|
*/ |
21
|
|
|
abstract class Handler |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* DB handler to fetch additional field information. |
25
|
|
|
* |
26
|
|
|
* @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler |
27
|
|
|
* @deprecated Start to use DBAL $connection instead. |
28
|
|
|
*/ |
29
|
|
|
protected $dbHandler; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Map of criterion operators to the respective function names |
33
|
|
|
* in the DoctrineDatabase DBAL. |
34
|
|
|
* |
35
|
|
|
* @var array |
36
|
|
|
*/ |
37
|
|
|
protected $comparatorMap = array( |
38
|
|
|
CriterionOperator::EQ => 'eq', |
39
|
|
|
CriterionOperator::GT => 'gt', |
40
|
|
|
CriterionOperator::GTE => 'gte', |
41
|
|
|
CriterionOperator::LT => 'lt', |
42
|
|
|
CriterionOperator::LTE => 'lte', |
43
|
|
|
); |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Transformation processor. |
47
|
|
|
* |
48
|
|
|
* @var \eZ\Publish\Core\Persistence\TransformationProcessor |
49
|
|
|
*/ |
50
|
|
|
protected $transformationProcessor; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Creates a new criterion handler. |
54
|
|
|
* |
55
|
|
|
* @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $dbHandler |
56
|
|
|
* @param \eZ\Publish\Core\Persistence\TransformationProcessor $transformationProcessor |
57
|
|
|
*/ |
58
|
|
|
public function __construct(DatabaseHandler $dbHandler, TransformationProcessor $transformationProcessor) |
59
|
|
|
{ |
60
|
|
|
$this->dbHandler = $dbHandler; |
61
|
|
|
$this->transformationProcessor = $transformationProcessor; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Generates query expression for operator and value of a Field Criterion. |
66
|
|
|
* |
67
|
|
|
* @throws \RuntimeException If operator is not handled. |
68
|
|
|
* |
69
|
|
|
* @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query |
70
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
71
|
|
|
* @param string $column |
72
|
|
|
* |
73
|
|
|
* @return \eZ\Publish\Core\Persistence\Database\Expression |
74
|
|
|
*/ |
75
|
|
|
public function handle(SelectQuery $query, Criterion $criterion, $column) |
76
|
|
|
{ |
77
|
|
|
$column = $this->dbHandler->quoteColumn($column); |
78
|
|
|
|
79
|
|
|
switch ($criterion->operator) { |
80
|
|
|
case Criterion\Operator::IN: |
81
|
|
|
$filter = $query->expr->in( |
82
|
|
|
$column, |
83
|
|
|
array_map(array($this, 'lowerCase'), $criterion->value) |
84
|
|
|
); |
85
|
|
|
break; |
86
|
|
|
|
87
|
|
|
case Criterion\Operator::BETWEEN: |
88
|
|
|
$filter = $query->expr->between( |
89
|
|
|
$column, |
90
|
|
|
$query->bindValue($this->lowerCase($criterion->value[0])), |
91
|
|
|
$query->bindValue($this->lowerCase($criterion->value[1])) |
92
|
|
|
); |
93
|
|
|
break; |
94
|
|
|
|
95
|
|
|
case Criterion\Operator::EQ: |
96
|
|
|
case Criterion\Operator::GT: |
97
|
|
|
case Criterion\Operator::GTE: |
98
|
|
|
case Criterion\Operator::LT: |
99
|
|
|
case Criterion\Operator::LTE: |
100
|
|
|
$operatorFunction = $this->comparatorMap[$criterion->operator]; |
101
|
|
|
$filter = $query->expr->$operatorFunction( |
102
|
|
|
$column, |
103
|
|
|
$query->bindValue($this->lowerCase($criterion->value)) |
104
|
|
|
); |
105
|
|
|
break; |
106
|
|
|
|
107
|
|
|
case Criterion\Operator::LIKE: |
108
|
|
View Code Duplication |
if (strpos($criterion->value, '%') !== false) { |
|
|
|
|
109
|
|
|
// @deprecated In 6.7.x/6.13.x/7.3.x and higher, to be removed in 8.0 |
110
|
|
|
@trigger_error( |
|
|
|
|
111
|
|
|
"Usage of '%' in Operator::LIKE criteria with Legacy Search Engine was never intended, " . |
112
|
|
|
"and is deprecated for removal in 8.0. Please use '*' like in FullText, works across engines", |
113
|
|
|
E_USER_DEPRECATED |
114
|
|
|
); |
115
|
|
|
$value = $this->lowerCase($criterion->value); |
116
|
|
|
} else { |
117
|
|
|
$value = str_replace('*', '%', $this->prepareLikeString($criterion->value)); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$filter = $query->expr->like( |
121
|
|
|
$column, |
122
|
|
|
$query->bindValue($value) |
123
|
|
|
); |
124
|
|
|
break; |
125
|
|
|
|
126
|
|
|
case Criterion\Operator::CONTAINS: |
127
|
|
|
$filter = $query->expr->like( |
128
|
|
|
$column, |
129
|
|
|
$query->bindValue( |
130
|
|
|
'%' . $this->prepareLikeString($criterion->value) . '%' |
131
|
|
|
) |
132
|
|
|
); |
133
|
|
|
break; |
134
|
|
|
|
135
|
|
|
default: |
136
|
|
|
throw new RuntimeException("Unknown operator '{$criterion->operator}' for Field criterion handler."); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
return $filter; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Returns the given $string prepared for use in SQL LIKE clause. |
144
|
|
|
* |
145
|
|
|
* LIKE clause wildcards '%' and '_' contained in the given $string will be escaped. |
146
|
|
|
* |
147
|
|
|
* @param $string |
148
|
|
|
* |
149
|
|
|
* @return string |
150
|
|
|
*/ |
151
|
|
|
protected function prepareLikeString($string) |
152
|
|
|
{ |
153
|
|
|
return addcslashes($this->lowerCase($string), '%_'); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Downcases a given string using string transformation processor. |
158
|
|
|
* |
159
|
|
|
* @param string $string |
160
|
|
|
* |
161
|
|
|
* @return string |
162
|
|
|
*/ |
163
|
|
|
protected function lowerCase($string) |
164
|
|
|
{ |
165
|
|
|
return $this->transformationProcessor->transformByGroup($string, 'lowercase'); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.