1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the DoctrineDatabase field criterion 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; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter; |
12
|
|
|
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\FieldValue\Converter as FieldValueConverter; |
13
|
|
|
use eZ\Publish\Core\Persistence\Database\DatabaseHandler; |
14
|
|
|
use eZ\Publish\API\Repository\Values\Content\Query\Criterion; |
15
|
|
|
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry as Registry; |
16
|
|
|
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException; |
17
|
|
|
use eZ\Publish\Core\Persistence\TransformationProcessor; |
18
|
|
|
use eZ\Publish\Core\Persistence\Database\SelectQuery; |
19
|
|
|
use eZ\Publish\SPI\Persistence\Content\Type\Handler as ContentTypeHandler; |
20
|
|
|
use eZ\Publish\SPI\Persistence\Content\Language\Handler as LanguageHandler; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Field criterion handler. |
24
|
|
|
*/ |
25
|
|
|
class Field extends FieldBase |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* Field converter registry. |
29
|
|
|
* |
30
|
|
|
* @var \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry |
31
|
|
|
*/ |
32
|
|
|
protected $fieldConverterRegistry; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Field value converter. |
36
|
|
|
* |
37
|
|
|
* @var \eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler\FieldValue\Converter |
38
|
|
|
*/ |
39
|
|
|
protected $fieldValueConverter; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Transformation processor. |
43
|
|
|
* |
44
|
|
|
* @var \eZ\Publish\Core\Persistence\TransformationProcessor |
45
|
|
|
*/ |
46
|
|
|
protected $transformationProcessor; |
47
|
|
|
|
48
|
|
|
public function __construct( |
49
|
|
|
DatabaseHandler $dbHandler, |
50
|
|
|
ContentTypeHandler $contentTypeHandler, |
51
|
|
|
LanguageHandler $languageHandler, |
52
|
|
|
Registry $fieldConverterRegistry, |
53
|
|
|
FieldValueConverter $fieldValueConverter, |
54
|
|
|
TransformationProcessor $transformationProcessor |
55
|
|
|
) { |
56
|
|
|
parent::__construct($dbHandler, $contentTypeHandler, $languageHandler); |
57
|
|
|
|
58
|
|
|
$this->fieldConverterRegistry = $fieldConverterRegistry; |
59
|
|
|
$this->fieldValueConverter = $fieldValueConverter; |
60
|
|
|
$this->transformationProcessor = $transformationProcessor; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Check if this criterion handler accepts to handle the given criterion. |
65
|
|
|
* |
66
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
67
|
|
|
* |
68
|
|
|
* @return bool |
69
|
|
|
*/ |
70
|
|
|
public function accept(Criterion $criterion) |
71
|
|
|
{ |
72
|
|
|
return $criterion instanceof Criterion\Field; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Returns relevant field information for the specified field. |
77
|
|
|
* |
78
|
|
|
* The returned information is returned as an array of the attribute |
79
|
|
|
* identifier and the sort column, which should be used. |
80
|
|
|
* |
81
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If no searchable fields are found for the given $fieldIdentifier. |
82
|
|
|
* @throws \RuntimeException if no converter is found |
83
|
|
|
* |
84
|
|
|
* @param string $fieldIdentifier |
85
|
|
|
* |
86
|
|
|
* @return array |
87
|
|
|
* |
88
|
|
|
* @throws \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter\Exception\NotFound |
89
|
|
|
*/ |
90
|
|
|
protected function getFieldsInformation($fieldIdentifier) |
91
|
|
|
{ |
92
|
|
|
$fieldMapArray = []; |
93
|
|
|
$fieldMap = $this->contentTypeHandler->getSearchableFieldMap(); |
94
|
|
|
|
95
|
|
|
foreach ($fieldMap as $contentTypeIdentifier => $fieldIdentifierMap) { |
96
|
|
|
// First check if field exists in the current ContentType, there is nothing to do if it doesn't |
97
|
|
|
if (!isset($fieldIdentifierMap[$fieldIdentifier])) { |
98
|
|
|
continue; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$fieldTypeIdentifier = $fieldIdentifierMap[$fieldIdentifier]['field_type_identifier']; |
102
|
|
|
$fieldMapArray[$fieldTypeIdentifier]['ids'][] = $fieldIdentifierMap[$fieldIdentifier]['field_definition_id']; |
103
|
|
View Code Duplication |
if (!isset($fieldMapArray[$fieldTypeIdentifier]['column'])) { |
|
|
|
|
104
|
|
|
$fieldMapArray[$fieldTypeIdentifier]['column'] = $this->fieldConverterRegistry->getConverter($fieldTypeIdentifier)->getIndexColumn(); |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
if (empty($fieldMapArray)) { |
109
|
|
|
throw new InvalidArgumentException( |
110
|
|
|
'$criterion->target', |
111
|
|
|
"No searchable fields found for the given criterion target '{$fieldIdentifier}'." |
112
|
|
|
); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return $fieldMapArray; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Generate query expression for a Criterion this handler accepts. |
120
|
|
|
* |
121
|
|
|
* accept() must be called before calling this method. |
122
|
|
|
* |
123
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException If no searchable fields are found for the given criterion target. |
124
|
|
|
* |
125
|
|
|
* @param \eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter $converter |
126
|
|
|
* @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query |
127
|
|
|
* @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
128
|
|
|
* @param array $languageSettings |
129
|
|
|
* |
130
|
|
|
* @return \eZ\Publish\Core\Persistence\Database\Expression |
131
|
|
|
* |
132
|
|
|
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
133
|
|
|
* @throws \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter\Exception\NotFound |
134
|
|
|
*/ |
135
|
|
|
public function handle( |
136
|
|
|
CriteriaConverter $converter, |
137
|
|
|
SelectQuery $query, |
138
|
|
|
Criterion $criterion, |
139
|
|
|
array $languageSettings |
140
|
|
|
) { |
141
|
|
|
$fieldsInformation = $this->getFieldsInformation($criterion->target); |
142
|
|
|
|
143
|
|
|
$subSelect = $query->subSelect(); |
144
|
|
|
$subSelect->select( |
145
|
|
|
$this->dbHandler->quoteColumn('contentobject_id') |
146
|
|
|
)->from( |
147
|
|
|
$this->dbHandler->quoteTable('ezcontentobject_attribute') |
148
|
|
|
); |
149
|
|
|
|
150
|
|
|
$whereExpressions = []; |
151
|
|
|
|
152
|
|
|
foreach ($fieldsInformation as $fieldTypeIdentifier => $fieldsInfo) { |
153
|
|
|
if ($fieldsInfo['column'] === false) { |
154
|
|
|
continue; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$filter = $this->fieldValueConverter->convertCriteria( |
158
|
|
|
$fieldTypeIdentifier, |
159
|
|
|
$subSelect, |
160
|
|
|
$criterion, |
161
|
|
|
$fieldsInfo['column'] |
162
|
|
|
); |
163
|
|
|
|
164
|
|
|
$whereExpressions[] = $subSelect->expr->lAnd( |
165
|
|
|
$subSelect->expr->in( |
166
|
|
|
$this->dbHandler->quoteColumn('contentclassattribute_id'), |
167
|
|
|
$fieldsInfo['ids'] |
168
|
|
|
), |
169
|
|
|
$filter |
170
|
|
|
); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
return $this->getInExpressionWithFieldConditions( |
174
|
|
|
$query, |
175
|
|
|
$subSelect, |
176
|
|
|
$languageSettings, |
177
|
|
|
$whereExpressions, |
178
|
|
|
$fieldsInformation |
179
|
|
|
); |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
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.