Completed
Push — master ( 945efb...5cd333 )
by André
85:29 queued 68:53
created

Field::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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