Completed
Push — master ( 8c5037...eed80c )
by Gaetano
07:22
created

ObjectStateMatcher::loadAvailableStates()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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