Completed
Push — master ( 70879e...9c56d3 )
by Gaetano
08:15
created

ContentMatcher::matchContent()   D

Complexity

Conditions 16
Paths 67

Size

Total Lines 48
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 18.8084

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 21
cts 27
cp 0.7778
rs 4.9765
c 0
b 0
f 0
cc 16
eloc 29
nc 67
nop 1
crap 18.8084

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Matcher;
4
5
use eZ\Publish\API\Repository\Values\Content\Content;
6
use eZ\Publish\API\Repository\Values\Content\Query;
7
use Kaliop\eZMigrationBundle\API\Collection\ContentCollection;
8
9
/**
10
 * @todo extend to allow matching by visibility, subtree, depth, object state, section, creation/modification date...
11
 * @todo extend to allow matching on multiple conditions (AND)
12
 */
13
class ContentMatcher extends AbstractMatcher
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_PARENT_LOCATION_ID = 'parent_location_id';
20
    const MATCH_PARENT_LOCATION_REMOTE_ID = 'parent_location_remote_id';
21
    const MATCH_CONTENT_TYPE_ID = 'contenttype_id';
22
    const MATCH_CONTENT_TYPE_IDENTIFIER = 'contenttype_identifier';
23
24
    protected $allowedConditions = array(
25
        self::MATCH_CONTENT_ID, self::MATCH_LOCATION_ID, self::MATCH_CONTENT_REMOTE_ID, self::MATCH_LOCATION_REMOTE_ID,
26
        self::MATCH_PARENT_LOCATION_ID, self::MATCH_PARENT_LOCATION_REMOTE_ID, self::MATCH_CONTENT_TYPE_IDENTIFIER,
27
        // aliases
28
        'content_type', 'content_type_id', 'content_type_identifier'
29
    );
30
    protected $returns = 'Content';
31
32
    /**
33 3
     * @param array $conditions key: condition, value: int / string / int[] / string[]
34
     * @return ContentCollection
35 3
     */
36
    public function match(array $conditions)
37
    {
38
        return $this->matchContent($conditions);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->matchContent($conditions); of type Kaliop\eZMigrationBundle...\ContentCollection|null adds the type Kaliop\eZMigrationBundle...ction\ContentCollection to the return on line 38 which is incompatible with the return type declared by the interface Kaliop\eZMigrationBundle...MatcherInterface::match of type array|Kaliop\eZMigrationBundle\API\ArrayObject.
Loading history...
39
    }
40
41
    /**
42 3
     * @param array $conditions key: condition, value: int / string / int[] / string[]
43
     * @return ContentCollection
44 3
     */
45
    public function matchContent(array $conditions)
46 3
    {
47
        $this->validateConditions($conditions);
48 3
49 3
        foreach ($conditions as $key => $values) {
50 3
51
            if (!is_array($values)) {
52
                $values = array($values);
53 3
            }
54 3
55
            // BC support
56 2
            if ($key == 'content_type') {
57 1
                if (is_int($key) || ctype_digit($key)) {
58
                    $key = self::MATCH_CONTENT_TYPE_ID;
59 2
                } else {
60
                    $key = self::MATCH_CONTENT_TYPE_IDENTIFIER;
61
                }
62 2
            }
63
64
            switch ($key) {
65 2
                case self::MATCH_CONTENT_ID:
66
                   return new ContentCollection($this->findContentsByContentIds($values));
67
68 2
                case self::MATCH_LOCATION_ID:
69
                    return new ContentCollection($this->findContentsByLocationIds($values));
70
71 2
                case self::MATCH_CONTENT_REMOTE_ID:
72 2
                    return new ContentCollection($this->findContentsByContentRemoteIds($values));
73
74
                case self::MATCH_LOCATION_REMOTE_ID:
75
                    return new ContentCollection($this->findContentsByLocationRemoteIds($values));
76
77
                case self::MATCH_PARENT_LOCATION_ID:
78
                    return new ContentCollection($this->findContentsByParentLocationIds($values));
79
80
                case self::MATCH_PARENT_LOCATION_REMOTE_ID:
81 3
                    return new ContentCollection($this->findContentsByParentLocationRemoteIds($values));
82
83 3
                case 'content_type_id':
84
                case self::MATCH_CONTENT_TYPE_ID:
85 3
                    return new ContentCollection($this->findContentsByContentTypeIds($values));
86
87 3
                case 'content_type_identifier':
88 3
                case self::MATCH_CONTENT_TYPE_IDENTIFIER:
89 3
                    return new ContentCollection($this->findContentsByContentTypeIdentifiers($values));
90
            }
91 3
        }
92
    }
93
94
    /**
95
     * @param int[] $contentIds
96
     * @return Content[]
97
     */
98 View Code Duplication
    protected function findContentsByContentIds(array $contentIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
99
    {
100
        $contents = [];
101
102
        foreach ($contentIds as $contentId) {
103
            // return unique contents
104
            $content = $this->repository->getContentService()->loadContent($contentId);
105
            $contents[$content->contentInfo->id] = $content;
106
        }
107
108
        return $contents;
109
    }
110
111
    /**
112
     * @param string[] $remoteContentIds
113
     * @return Content[]
114
     */
115 1 View Code Duplication
    protected function findContentsByContentRemoteIds(array $remoteContentIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
116
    {
117 1
        $contents = [];
118
119 1
        foreach ($remoteContentIds as $remoteContentId) {
120 1
            // return unique contents
121
            $content = $this->repository->getContentService()->loadContentByRemoteId($remoteContentId);
122 1
            $contents[$content->contentInfo->id] = $content;
123 1
        }
124
125 1
        return $contents;
126
    }
127
128
    /**
129
     * @param int[] $locationIds
130
     * @return Content[]
131
     */
132 View Code Duplication
    protected function findContentsByLocationIds(array $locationIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
133
    {
134
        $contentIds = [];
135
136
        foreach ($locationIds as $locationId) {
137
            $location = $this->repository->getLocationService()->loadLocation($locationId);
138
            // return unique ids
139
            $contentIds[$location->contentId] = $location->contentId;
140
        }
141
142
        return $this->findContentsByContentIds($contentIds);
143
    }
144
145
    /**
146
     * @param string[] $remoteLocationIds
147
     * @return Content[]
148
     */
149 View Code Duplication
    protected function findContentsByLocationRemoteIds($remoteLocationIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
150
    {
151
        $contentIds = [];
152
153
        foreach ($remoteLocationIds as $remoteLocationId) {
154
            $location = $this->repository->getLocationService()->loadLocationByRemoteId($remoteLocationId);
155
            // return unique ids
156
            $contentIds[$location->contentId] = $location->contentId;
157
        }
158
159
        return $this->findContentsByContentIds($contentIds);
160
    }
161
162
    /**
163
     * @param int[] $parentLocationIds
164
     * @return Content[]
165
     */
166
    protected function findContentsByParentLocationIds($parentLocationIds)
167
    {
168
        $query = new Query();
169
        $query->limit = PHP_INT_MAX;
170
        $query->filter = new Query\Criterion\ParentLocationId($parentLocationIds);
171
        $results = $this->repository->getSearchService()->findContent($query);
172
173
        $contents = [];
174
        foreach ($results->searchHits as $result) {
175
            // make sure we return every object only once
176
            $contents[$result->valueObject->contentInfo->id] = $result->valueObject;
177
        }
178
179
        return $contents;
180
    }
181
182
    /**
183
     * @param string[] $remoteParentLocationIds
184
     * @return Content[]
185
     */
186 2 View Code Duplication
    protected function findContentsByParentLocationRemoteIds($remoteParentLocationIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
187
    {
188 2
        $locationIds = [];
189 2
190 2
        foreach ($remoteParentLocationIds as $remoteParentLocationId) {
191
            $location = $this->repository->getLocationService()->loadLocationByRemoteId($remoteParentLocationId);
192
            // unique locations
193 2
            $locationIds[$location->id] = $location->id;
194 2
        }
195
196 2
        return $this->findContentsByParentLocationIds($locationIds);
197 2
    }
198
199 2
    /**
200 2
     * @param string[] $contentTypeIdentifiers
201
     * @return Content[]
202 2
     */
203 View Code Duplication
    protected function findContentsByContentTypeIdentifiers(array $contentTypeIdentifiers)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
204
    {
205
        $query = new Query();
206
        $query->limit = PHP_INT_MAX;
207
        $query->filter = new Query\Criterion\ContentTypeIdentifier($contentTypeIdentifiers);
208
        // sort objects by depth, lower to higher, so that deleting them has less chances of failure
209
        /// @todo replace with a location query, as we are using deprecated functionality
210
        $query->sortClauses = array(new Query\SortClause\LocationDepth(Query::SORT_DESC));
0 ignored issues
show
Deprecated Code introduced by
The class eZ\Publish\API\Repositor...ortClause\LocationDepth has been deprecated with message: Since 5.3, use Location search instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
211
        $results = $this->repository->getSearchService()->findContent($query);
212
213
        $contents = [];
214
        foreach ($results->searchHits as $result) {
215
            // make sure we return every object only once
216
            $contents[$result->valueObject->contentInfo->id] = $result->valueObject;
217
        }
218
219
        return $contents;
220
    }
221
222
    /**
223
     * @param int[] $contentTypeIds
224
     * @return Content[]
225
     */
226 View Code Duplication
    protected function findContentsByContentTypeIds(array $contentTypeIds)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
227
    {
228
        $query = new Query();
229
        $query->limit = PHP_INT_MAX;
230
        $query->filter = new Query\Criterion\ContentTypeId($contentTypeIds);
231
        // sort objects by depth, lower to higher, so that deleting them has less chances of failure
232
        /// @todo replace with a location query, as we are using deprecated functionality
233
        $query->sortClauses = array(new Query\SortClause\LocationDepth(Query::SORT_DESC));
0 ignored issues
show
Deprecated Code introduced by
The class eZ\Publish\API\Repositor...ortClause\LocationDepth has been deprecated with message: Since 5.3, use Location search instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
234
        $results = $this->repository->getSearchService()->findContent($query);
235
236
        $contents = [];
237
        foreach ($results->searchHits as $result) {
238
            // make sure we return every object only once
239
            $contents[$result->valueObject->contentInfo->id] = $result->valueObject;
240
        }
241
242
        return $contents;
243
    }
244
}
245