Completed
Push — master ( 21def9...8c5037 )
by Gaetano
21:26
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_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_NOT:
61
                    return new ObjectStateCollection(array_diff_key($this->findAllObjectStates(), $this->matchObjectState($values)->getArrayCopy()));
62
            }
63
        }
64
    }
65
66
    protected function getConditionsFromKey($key)
67
    {
68
        if (is_int($key) || ctype_digit($key)) {
69
            return array(self::MATCH_OBJECTSTATE_ID => $key);
70
        }
71
        return array(self::MATCH_OBJECTSTATE_IDENTIFIER => $key);
72
    }
73
74
    /**
75
     * @param int[] $objectStateIds
76
     * @return ObjectState[]
77
     */
78
    protected function findObjectStatesById(array $objectStateIds)
79
    {
80
        $objectStates = [];
81
82
        foreach ($objectStateIds as $objectStateId) {
83
            // return unique contents
84
            $objectState = $this->repository->getObjectStateService()->loadObjectState($objectStateId);
85
            $objectStates[$objectState->id] = $objectState;
86
        }
87
88
        return $objectStates;
89
    }
90
91
    /**
92
     * @param string[] $stateIdentifiers Accepts the state identifier if unique, otherwise "group-identifier/state-identifier"
93
     * @return ObjectState[]
94
     * @throws NotFoundException
95
     */
96
    protected function findObjectStatesByIdentifier(array $stateIdentifiers)
97
    {
98
        // we have to build this list, as the ObjectStateService does not allow to load a State by identifier...
99
        $statesList = $this->loadAvailableStates();
100
101
        $states = [];
102
103
        foreach ($stateIdentifiers as $stateIdentifier) {
104
            if (!isset($statesList[$stateIdentifier])) {
105
                // a quick and dirty way of letting the user know that he/she might be using a non-unique identifier
106
                throw new NotFoundException("ObjectState", $stateIdentifier . ' missing or non unique');
107
            }
108
            $states[$statesList[$stateIdentifier]->id] = $statesList[$stateIdentifier];
109
        }
110
111
        return $states;
112
    }
113
114
    /**
115
     * @return ObjectState[] key: id
116
     */
117
    protected function findAllObjectStates()
118
    {
119
        $states = array();
120
121
        foreach ($this->loadAvailableStates() as $key => $state) {
122
            if (strpos('/', $key) !== false) {
123
                $states[$state->id] = $state;
124
            }
125
        }
126
127
        return $states;
128
    }
129
130
    /**
131
     * @return ObjectState[] key: the state identifier (for unique identifiers), group_identifier/state_identifier for all
132
     */
133
    protected function loadAvailableStates()
134
    {
135
        $statesList = array();
136
        $nonUniqueIdentifiers = array();
137
138
        $groups = $this->repository->getObjectStateService()->loadObjectStateGroups();
139
        foreach ($groups as $group) {
140
            $groupStates = $this->repository->getObjectStateService()->loadObjectStates($group);
141
            foreach ($groupStates as $groupState) {
142
                // we always add the states using 'group/state' identifiers
143
                $statesList[$group->identifier . '/' . $groupState->identifier] = $groupState;
144
                // we only add the state using plain identifier if it is unique
145
                if (isset($statesList[$groupState->identifier])) {
146
                    unset($statesList[$groupState->identifier]);
147
                    $nonUniqueIdentifiers[] = $groupState->identifier;
148
                } else {
149
                    if (!isset($nonUniqueIdentifiers[$groupState->identifier])) {
150
                        $statesList[$groupState->identifier] = $groupState;
151
                    }
152
                }
153
            }
154
        }
155
156
        return $statesList;
157
    }
158
}
159