Completed
Branch master (e35419)
by Gaetano
06:40
created

ObjectStateMatcher::findObjectStatesByIdentifier()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 16
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 10
c 0
b 0
f 0
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 5
    public function match(array $conditions)
32
    {
33 5
        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 5
    public function matchObjectState(array $conditions)
42
    {
43 5
        $this->validateConditions($conditions);
44
45 5
        foreach ($conditions as $key => $values) {
46
47 5
            if (!is_array($values)) {
48 5
                $values = array($values);
49
            }
50
51
            switch ($key) {
52 5
                case 'id':
53 5
                case self::MATCH_OBJECTSTATE_ID:
54 1
                   return new ObjectStateCollection($this->findObjectStatesById($values));
55
56 5
                case 'identifier':
57 5
                case self::MATCH_OBJECTSTATE_IDENTIFIER:
58 2
                    return new ObjectStateCollection($this->findObjectStatesByIdentifier($values));
59
60 3
                case self::MATCH_ALL:
61 3
                    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 2
    protected function getConditionsFromKey($key)
76
    {
77 2
        if (is_int($key) || ctype_digit($key)) {
78
            return array(self::MATCH_OBJECTSTATE_ID => $key);
79
        }
80 2
        return array(self::MATCH_OBJECTSTATE_IDENTIFIER => $key);
81
    }
82
83
    /**
84
     * @param int[] $objectStateIds
85
     * @return ObjectState[]
86
     */
87 1
    protected function findObjectStatesById(array $objectStateIds)
88
    {
89 1
        $objectStates = [];
90
91 1
        foreach ($objectStateIds as $objectStateId) {
92
            // return unique contents
93 1
            $objectState = $this->repository->getObjectStateService()->loadObjectState($objectStateId);
94 1
            $objectStates[$objectState->id] = $objectState;
95
        }
96
97 1
        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 2
    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 2
        $statesList = $this->loadAvailableStates();
109
110 2
        $states = [];
111
112 2
        foreach ($stateIdentifiers as $stateIdentifier) {
113 2
            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 2
            $states[$statesList[$stateIdentifier]->id] = $statesList[$stateIdentifier];
118
        }
119
120 2
        return $states;
121
    }
122
123
    /**
124
     * @return ObjectState[] key: id
125
     */
126 3
    protected function findAllObjectStates()
127
    {
128 3
        $states = array();
129
130 3
        foreach ($this->loadAvailableStates() as $key => $state) {
131 3
            if (strpos($key, '/') !== false) {
132 3
                $states[$state->id] = $state;
133
            }
134
        }
135
136 3
        return $states;
137
    }
138
139
    /**
140
     * @return ObjectState[] key: the state identifier (for unique identifiers), group_identifier/state_identifier for all
141
     */
142 5
    protected function loadAvailableStates()
143
    {
144 5
        $statesList = array();
145 5
        $nonUniqueIdentifiers = array();
146
147 5
        $groups = $this->repository->getObjectStateService()->loadObjectStateGroups();
148 5
        foreach ($groups as $group) {
149 5
            $groupStates = $this->repository->getObjectStateService()->loadObjectStates($group);
150 5
            foreach ($groupStates as $groupState) {
151
                // we always add the states using 'group/state' identifiers
152 5
                $statesList[$group->identifier . '/' . $groupState->identifier] = $groupState;
153
                // we only add the state using plain identifier if it is unique
154 5
                if (isset($statesList[$groupState->identifier])) {
155
                    unset($statesList[$groupState->identifier]);
156
                    $nonUniqueIdentifiers[] = $groupState->identifier;
157
                } else {
158 5
                    if (!isset($nonUniqueIdentifiers[$groupState->identifier])) {
159 5
                        $statesList[$groupState->identifier] = $groupState;
160
                    }
161
                }
162
            }
163
        }
164
165 5
        return $statesList;
166
    }
167
}
168