Completed
Push — master ( ac3b8b...3c857d )
by Gaetano
18:21
created

QueryBasedMatcher::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 8
nc 1
nop 5
1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Matcher;
4
5
use eZ\Publish\API\Repository\Values\Content\Query;
6
use eZ\Publish\API\Repository\Repository;
7
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;
8
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Operator;
9
10
/**
11
 * @todo extend to allow matching by modifier, language code, content_type_group_id
12
 */
13
abstract class QueryBasedMatcher extends RepositoryMatcher
14
{
15
    const MATCH_CONTENT_ID = 'content_id';
16
    const MATCH_LOCATION_ID = 'location_id';
17
    const MATCH_CONTENT_REMOTE_ID = 'content_remote_id';
18
    const MATCH_LOCATION_REMOTE_ID = 'location_remote_id';
19
    const MATCH_ATTRIBUTE = 'attribute';
20
    const MATCH_CONTENT_TYPE_ID = 'contenttype_id';
21
    const MATCH_CONTENT_TYPE_IDENTIFIER = 'contenttype_identifier';
22
    const MATCH_CREATION_DATE = 'creation_date';
23
    const MATCH_GROUP = 'group';
24
    const MATCH_MODIFICATION_DATE = 'modification_date';
25
    const MATCH_OBJECT_STATE = 'object_state';
26
    const MATCH_OWNER = 'owner';
27
    const MATCH_PARENT_LOCATION_ID = 'parent_location_id';
28
    const MATCH_PARENT_LOCATION_REMOTE_ID = 'parent_location_remote_id';
29
    const MATCH_SECTION = 'section';
30
    const MATCH_SUBTREE = 'subtree';
31
    const MATCH_VISIBILITY = 'visibility';
32
33
    static protected $operatorsMap = array(
34
        'eq' => Operator::EQ,
35
        'gt' => Operator::GT,
36
        'gte' => Operator::GTE,
37
        'lt' => Operator::LT,
38
        'lte' => Operator::LTE,
39
        'in' => Operator::IN,
40
        'between' => Operator::BETWEEN,
41
        'like' => Operator::LIKE,
42
        'contains' => Operator::CONTAINS,
43
        Operator::EQ => Operator::EQ,
44
        Operator::GT => Operator::GT,
45
        Operator::GTE => Operator::GTE,
46
        Operator::LT => Operator::LT,
47
        Operator::LTE => Operator::LTE,
48
    );
49
50
    /** @var  KeyMatcherInterface $groupMatcher */
51
    protected $groupMatcher;
52
    /** @var  KeyMatcherInterface $sectionMatcher */
53
    protected $sectionMatcher;
54
    /** @var  KeyMatcherInterface $stateMatcher */
55
    protected $stateMatcher;
56
    /** @var  KeyMatcherInterface $userMatcher */
57
    protected $userMatcher;
58
59
    /**
60
     * @param Repository $repository
61
     * @param KeyMatcherInterface $groupMatcher
62
     * @param KeyMatcherInterface $sectionMatcher
63
     * @param KeyMatcherInterface $stateMatcher
64
     * @param KeyMatcherInterface $userMatcher
65
     * @todo inject the services needed, not the whole repository
66
     */
67
    public function __construct(Repository $repository, KeyMatcherInterface $groupMatcher = null,
0 ignored issues
show
Unused Code introduced by
The parameter $groupMatcher is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
        KeyMatcherInterface $sectionMatcher = null, KeyMatcherInterface $stateMatcher = null,
69
        KeyMatcherInterface $userMatcher = null)
70
    {
71
        parent::__construct($repository);
72
        $this->userMatcher = $userMatcher;
73
        $this->sectionMatcher = $sectionMatcher;
74
        $this->stateMatcher = $stateMatcher;
75
        $this->userMatcher = $userMatcher;
76
    }
77
78
    /**
79
     * @param $key
80
     * @param $values
81
     * @return mixed should it be \eZ\Publish\API\Repository\Values\Content\Query\CriterionInterface ?
82
     * @throws \Exception for unsupported keys
83
     */
84
    protected function getQueryCriterion($key, $values)
85
    {
86
        if (!is_array($values)) {
87
            $values = array($values);
88
        }
89
90
        switch ($key) {
91
            case self::MATCH_CONTENT_ID:
92
                return new Query\Criterion\ContentId($values);
93
94
            case self::MATCH_LOCATION_ID:
95
                // NB: seems to cause problems with EZP 2014.3
96
                return new Query\Criterion\LocationId(reset($values));
97
98
            case self::MATCH_CONTENT_REMOTE_ID:
99
                return new Query\Criterion\RemoteId($values);
100
101
            case self::MATCH_LOCATION_REMOTE_ID:
102
                return new Query\Criterion\LocationRemoteId($values);
103
104
            case self::MATCH_ATTRIBUTE:
105
                $spec = reset($values);
106
                $attribute = key($values);
107
                $match = reset($spec);
108
                $operator = key($spec);
109
                if (!isset(self::$operatorsMap[$operator])) {
110
                    throw new \Exception("Can not use '$operator' as comparison operator for attributes");
111
                }
112
                return new Query\Criterion\Field($attribute, self::$operatorsMap[$operator], $match);
113
114
            case 'content_type_id':
115
            case self::MATCH_CONTENT_TYPE_ID:
116
                return new Query\Criterion\ContentTypeId($values);
117
118
            case 'content_type_identifier':
119
            case self::MATCH_CONTENT_TYPE_IDENTIFIER:
120
                return new Query\Criterion\ContentTypeIdentifier($values);
121
122 View Code Duplication
            case self::MATCH_CREATION_DATE:
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...
123
                $match = reset($values);
124
                $operator = key($values);
125
                if (!isset(self::$operatorsMap[$operator])) {
126
                    throw new \Exception("Can not use '$operator' as comparison operator for dates");
127
                }
128
                return new Query\Criterion\DateMetadata(Query\Criterion\DateMetadata::CREATED, self::$operatorsMap[$operator], $match);
129
130 View Code Duplication
            case self::MATCH_GROUP:
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...
131
                foreach($values as &$value) {
132
                    if (!ctype_digit($value)) {
133
                        $value = $this->groupMatcher->matchOneByKey($value)->id;
134
                    }
135
                }
136
                return new Query\Criterion\UserMetadata(Query\Criterion\UserMetadata::GROUP, Operator::IN, $values);
137
138 View Code Duplication
            case self::MATCH_MODIFICATION_DATE:
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...
139
                $match = reset($values);
140
                $operator = key($values);
141
                if (!isset(self::$operatorsMap[$operator])) {
142
                    throw new \Exception("Can not use '$operator' as comparison operator for dates");
143
                }
144
                return new Query\Criterion\DateMetadata(Query\Criterion\DateMetadata::MODIFIED, self::$operatorsMap[$operator], $match);
145
146 View Code Duplication
            case self::MATCH_OBJECT_STATE:
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...
147
                foreach($values as &$value) {
148
                    if (!ctype_digit($value)) {
149
                        $value = $this->stateMatcher->matchOneByKey($value)->id;
150
                    }
151
                }
152
                return new Query\Criterion\ObjectStateId($values);
153
154 View Code Duplication
            case self::MATCH_OWNER:
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...
155
                foreach($values as &$value) {
156
                    if (!ctype_digit($value)) {
157
                        $value = $this->userMatcher->matchOneByKey($value)->id;
158
                    }
159
                }
160
                return new Query\Criterion\UserMetadata(Query\Criterion\UserMetadata::OWNER, Operator::IN, $values);
161
162
            case self::MATCH_PARENT_LOCATION_ID:
163
                return new Query\Criterion\ParentLocationId($values);
164
165
            case self::MATCH_PARENT_LOCATION_REMOTE_ID:
166
                $locationIds = [];
167
                foreach ($values as $remoteParentLocationId) {
168
                    $location = $this->repository->getLocationService()->loadLocationByRemoteId($remoteParentLocationId);
169
                    // unique locations
170
                    $locationIds[$location->id] = $location->id;
171
                }
172
                return new Query\Criterion\ParentLocationId($locationIds);
173
174 View Code Duplication
            case self::MATCH_SECTION:
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...
175
                foreach($values as &$value) {
176
                    if (!ctype_digit($value)) {
177
                        $value = $this->sectionMatcher->matchOneByKey($value)->id;
178
                    }
179
                }
180
                return new Query\Criterion\SectionId($values);
181
182
            case self::MATCH_SUBTREE:
183
                return new Query\Criterion\Subtree($values);
184
185 View Code Duplication
            case self::MATCH_VISIBILITY:
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...
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
186
                /// @todo error/warning if there is more than 1 value...
187
                $value = reset($values);
188
                if ($value) {
189
                    return new Query\Criterion\Visibility(Query\Criterion\Visibility::VISIBLE);
190
                } else {
191
                    return new Query\Criterion\Visibility(Query\Criterion\Visibility::HIDDEN);
192
                }
193
194 View Code Duplication
            case self::MATCH_AND:
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...
195
                $subCriteria = array();
196
                foreach($values as $subCriterion) {
197
                    $value = reset($subCriterion);
198
                    $subCriteria[] = $this->getQueryCriterion(key($subCriterion), $value);
199
                }
200
                return new Query\Criterion\LogicalAnd($subCriteria);
201
202 View Code Duplication
            case self::MATCH_OR:
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...
203
                $subCriteria = array();
204
                foreach($values as $subCriterion) {
205
                    $value = reset($subCriterion);
206
                    $subCriteria[] = $this->getQueryCriterion(key($subCriterion), $value);
207
                }
208
                return new Query\Criterion\LogicalOr($subCriteria);
209
210
            case self::MATCH_NOT:
211
                /// @todo throw if more than one sub-criteria found
212
                $value = reset($values);
213
                $subCriterion = $this->getQueryCriterion(key($values), $value);
214
                return new Query\Criterion\LogicalNot($subCriterion);
215
216
            default:
217
                throw new \Exception($this->returns . " can not be matched because matching condition '$key' is not supported. Supported conditions are: " .
218
                    implode(', ', $this->allowedConditions));
219
        }
220
    }
221
}
222