Completed
Push — master ( 1bf270...21def9 )
by Gaetano
06:55
created

ObjectStateMatcher::getConditionsFromKey()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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