Completed
Push — ezp-30936-edit-content-new-req... ( 953d44...df9d75 )
by
unknown
19:03
created

FieldEmpty::handle()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 4
dl 0
loc 47
rs 9.1563
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
declare(strict_types=1);
8
9
namespace eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriterionHandler;
10
11
use eZ\Publish\API\Repository\FieldTypeService;
12
use eZ\Publish\Core\Search\Legacy\Content\Common\Gateway\CriteriaConverter;
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\Database\SelectQuery;
18
use eZ\Publish\SPI\Persistence\Content\Type\Handler as ContentTypeHandler;
19
use eZ\Publish\SPI\Persistence\Content\Language\Handler as LanguageHandler;
20
use eZ\Publish\Core\Persistence\Database\Expression;
21
22
/**
23
 * Field criterion handler.
24
 */
25
class FieldEmpty 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
     * @var \eZ\Publish\API\Repository\FieldTypeService
36
     */
37
    protected $fieldTypeService;
38
39
    public function __construct(
40
        DatabaseHandler $dbHandler,
41
        ContentTypeHandler $contentTypeHandler,
42
        LanguageHandler $languageHandler,
43
        Registry $fieldConverterRegistry,
44
        FieldTypeService $fieldTypeService
45
    ) {
46
        parent::__construct($dbHandler, $contentTypeHandler, $languageHandler);
47
48
        $this->fieldConverterRegistry = $fieldConverterRegistry;
49
        $this->fieldTypeService = $fieldTypeService;
50
    }
51
52
    /**
53
     * Check if this criterion handler accepts to handle the given criterion.
54
     */
55
    public function accept(Criterion $criterion): bool
56
    {
57
        return $criterion instanceof Criterion\IsFieldEmpty;
58
    }
59
60
    /**
61
     * Returns relevant field information for the specified field.
62
     *
63
     * Returns an array of the attribute,
64
     * identifier and the sort column, which should be used.
65
     *
66
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If no searchable fields are found for the given $fieldIdentifier.
67
     * @throws \RuntimeException if no converter is found
68
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
69
     */
70
    protected function getFieldsInformation(string $fieldIdentifier): array
71
    {
72
        $fieldMapArray = [];
73
        $fieldMap = $this->contentTypeHandler->getSearchableFieldMap();
74
75
        foreach ($fieldMap as $contentTypeIdentifier => $fieldIdentifierMap) {
76
            if (!isset($fieldIdentifierMap[$fieldIdentifier])) {
77
                continue;
78
            }
79
80
            $fieldTypeIdentifier = $fieldIdentifierMap[$fieldIdentifier]['field_type_identifier'];
81
            $fieldMapArray[$fieldTypeIdentifier]['ids'][] = $fieldIdentifierMap[$fieldIdentifier]['field_definition_id'];
82 View Code Duplication
            if (!isset($fieldMapArray[$fieldTypeIdentifier]['column'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
83
                $fieldMapArray[$fieldTypeIdentifier]['column'] = $this->fieldConverterRegistry->getConverter($fieldTypeIdentifier)->getIndexColumn();
84
            }
85
86
            $fieldType = $this->fieldTypeService->getFieldType($fieldTypeIdentifier);
87
            $fieldMapArray[$fieldTypeIdentifier]['empty_value'] = $fieldType->getEmptyValue();
88
        }
89
90
        if (empty($fieldMapArray)) {
91
            throw new InvalidArgumentException(
92
                '$criterion->target',
93
                "No searchable fields found for the given criterion target '{$fieldIdentifier}'."
94
            );
95
        }
96
97
        return $fieldMapArray;
98
    }
99
100
    /**
101
     * Generate query expression for a Criterion this handler accepts.
102
     *
103
     * accept() must be called before calling this method.
104
     *
105
     * @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException If no searchable fields are found for the given criterion target.
106
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
107
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
108
     */
109
    public function handle(
110
        CriteriaConverter $converter,
111
        SelectQuery $query,
112
        Criterion $criterion,
113
        array $languageSettings
114
    ): string {
115
        $fieldsInformation = $this->getFieldsInformation($criterion->target);
116
117
        $subSelect = $query->subSelect();
118
        $subSelect->select(
119
            $this->dbHandler->quoteColumn('contentobject_id')
120
        )->from(
121
            $this->dbHandler->quoteTable('ezcontentobject_attribute')
122
        );
123
124
        $whereExpressions = [];
125
126
        foreach ($fieldsInformation as $fieldTypeIdentifier => $fieldsInfo) {
127
            if ($fieldsInfo['column'] === false) {
128
                continue;
129
            }
130
131
            $filterPlaceholder = $subSelect->bindValue(
132
                $fieldsInfo['empty_value'],
133
                ':fieldTypeIdentifier'
134
            );
135
            $filter = $criterion->value[0]
136
                ? $subSelect->expr->eq($fieldsInfo['column'], $filterPlaceholder)
137
                : $subSelect->expr->neq($fieldsInfo['column'], $filterPlaceholder);
138
139
            $whereExpressions[] = $subSelect->expr->lAnd(
140
                $subSelect->expr->in(
141
                    $this->dbHandler->quoteColumn('contentclassattribute_id'),
142
                    $fieldsInfo['ids']
143
                ),
144
                $filter
145
            );
146
        }
147
148
        return $this->getInExpressionWithFieldConditions(
149
            $query,
150
            $subSelect,
151
            $languageSettings,
152
            $whereExpressions,
153
            $fieldsInformation
154
        );
155
    }
156
}
157