Passed
Pull Request — master (#225)
by
unknown
04:29
created

ObjectStateMatcher::matchObjectState()   B

Complexity

Conditions 11
Paths 19

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
cc 11
eloc 19
nc 19
nop 1
dl 0
loc 30
ccs 0
cts 22
cp 0
crap 132
rs 7.3166
c 0
b 0
f 0

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\ObjectState\ObjectState;
6
use Kaliop\eZMigrationBundle\API\Collection\ObjectStateCollection;
7
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;
8
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
9
use Kaliop\eZMigrationBundle\API\Exception\InvalidMatchConditionsException;
10
11
class ObjectStateMatcher extends RepositoryMatcher implements KeyMatcherInterface
12
{
13
    use FlexibleKeyMatcherTrait;
14
15
    const MATCH_OBJECTSTATE_ID = 'objectstate_id';
16
    const MATCH_OBJECTSTATE_IDENTIFIER = 'objectstate_identifier';
17
18
    protected $allowedConditions = array(
19
        self::MATCH_ALL, self::MATCH_AND, self::MATCH_OR, self::MATCH_NOT,
20
        self::MATCH_OBJECTSTATE_ID, self::MATCH_OBJECTSTATE_IDENTIFIER,
21
        // aliases
22
        'id', 'identifier'
23
    );
24
    protected $returns = 'ObjectState';
25
26
    /**
27
     * @param array $conditions key: condition, value: int / string / int[] / string[]
28
     * @return ObjectStateCollection
29
     * @throws InvalidMatchConditionsException
30
     */
31
    public function match(array $conditions)
32
    {
33
        return $this->matchObjectState($conditions);
34
    }
35
36
    /**
37
     * @param array $conditions key: condition, value: int / string / int[] / string[]
38
     * @return ObjectStateCollection
39
     * @throws InvalidMatchConditionsException
40
     */
41
    public function matchObjectState(array $conditions)
42
    {
43
        $this->validateConditions($conditions);
44
45
        foreach ($conditions as $key => $values) {
46
47
            if (!is_array($values)) {
48
                $values = array($values);
49
            }
50
51
            switch ($key) {
52
                case 'id':
53
                case self::MATCH_OBJECTSTATE_ID:
54
                   return new ObjectStateCollection($this->findObjectStatesById($values));
55
56
                case 'identifier':
57
                case self::MATCH_OBJECTSTATE_IDENTIFIER:
58
                    return new ObjectStateCollection($this->findObjectStatesByIdentifier($values));
59
60
                case self::MATCH_ALL:
61
                    return new ObjectStateCollection($this->findAllObjectStates());
62
63
                case self::MATCH_AND:
64
                    return $this->matchAnd($values);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->matchAnd($values) returns the type array which is incompatible with the documented return type Kaliop\eZMigrationBundle...n\ObjectStateCollection.
Loading history...
65
66
                case self::MATCH_OR:
67
                    return $this->matchOr($values);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->matchOr($values) returns the type array which is incompatible with the documented return type Kaliop\eZMigrationBundle...n\ObjectStateCollection.
Loading history...
68
69
                case self::MATCH_NOT:
70
                    return new ObjectStateCollection(array_diff_key($this->findAllObjectStates(), $this->matchObjectState($values)->getArrayCopy()));
71
            }
72
        }
73
    }
74
75
    protected function getConditionsFromKey($key)
76
    {
77
        if (is_int($key) || ctype_digit($key)) {
78
            return array(self::MATCH_OBJECTSTATE_ID => $key);
79
        }
80
        return array(self::MATCH_OBJECTSTATE_IDENTIFIER => $key);
81
    }
82
83
    /**
84
     * @param int[] $objectStateIds
85
     * @return ObjectState[]
86
     */
87
    protected function findObjectStatesById(array $objectStateIds)
88
    {
89
        $objectStates = [];
90
91
        foreach ($objectStateIds as $objectStateId) {
92
            // return unique contents
93
            $objectState = $this->repository->getObjectStateService()->loadObjectState($objectStateId);
94
            $objectStates[$objectState->id] = $objectState;
95
        }
96
97
        return $objectStates;
98
    }
99
100
    /**
101
     * @param string[] $stateIdentifiers Accepts the state identifier if unique, otherwise "group-identifier/state-identifier"
102
     * @return ObjectState[]
103
     * @throws NotFoundException
104
     */
105
    protected function findObjectStatesByIdentifier(array $stateIdentifiers)
106
    {
107
        // we have to build this list, as the ObjectStateService does not allow to load a State by identifier...
108
        $statesList = $this->loadAvailableStates();
109
110
        $states = [];
111
112
        foreach ($stateIdentifiers as $stateIdentifier) {
113
            if (!isset($statesList[$stateIdentifier])) {
114
                // a quick and dirty way of letting the user know that he/she might be using a non-unique identifier
115
                throw new NotFoundException("ObjectState", $stateIdentifier . "' (either missing or non unique)");
116
            }
117
            $states[$statesList[$stateIdentifier]->id] = $statesList[$stateIdentifier];
118
        }
119
120
        return $states;
121
    }
122
123
    /**
124
     * @return ObjectState[] key: id
125
     */
126
    protected function findAllObjectStates()
127
    {
128
        $states = array();
129
130
        foreach ($this->loadAvailableStates() as $key => $state) {
131
            if (strpos($key, '/') !== false) {
132
                $states[$state->id] = $state;
133
            }
134
        }
135
136
        return $states;
137
    }
138
139
    /**
140
     * @return ObjectState[] key: the state identifier (for unique identifiers), group_identifier/state_identifier for all
141
     */
142
    protected function loadAvailableStates()
143
    {
144
        $statesList = array();
145
        $nonUniqueIdentifiers = array();
146
147
        $groups = $this->repository->getObjectStateService()->loadObjectStateGroups();
148
        foreach ($groups as $group) {
149
            $groupStates = $this->repository->getObjectStateService()->loadObjectStates($group);
150
            foreach ($groupStates as $groupState) {
151
                // we always add the states using 'group/state' identifiers
152
                $statesList[$group->identifier . '/' . $groupState->identifier] = $groupState;
153
                // we only add the state using plain identifier if it is unique
154
                if (isset($statesList[$groupState->identifier])) {
155
                    unset($statesList[$groupState->identifier]);
156
                    $nonUniqueIdentifiers[] = $groupState->identifier;
157
                } else {
158
                    if (!isset($nonUniqueIdentifiers[$groupState->identifier])) {
159
                        $statesList[$groupState->identifier] = $groupState;
160
                    }
161
                }
162
            }
163
        }
164
165
        return $statesList;
166
    }
167
}
168