Completed
Push — master ( 7785c8...07cf23 )
by Gaetano
09:22
created

ObjectStateMatcher::findObjectStatesByIdentifier()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
c 0
b 0
f 0
rs 9.4285
cc 3
eloc 8
nc 3
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 AbstractMatcher 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_OBJECTSTATE_ID, self::MATCH_OBJECTSTATE_IDENTIFIER,
19
        // aliases
20
        'id', 'identifier'
21
    );
22
    protected $returns = 'ObjectState';
23
24
    /**
25
     * @param array $conditions key: condition, value: int / string / int[] / string[]
26
     * @return ObjectStateCollection
27
     */
28
    public function match(array $conditions)
29
    {
30
        return $this->matchObjectState($conditions);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->matchObjectState($conditions); of type Kaliop\eZMigrationBundle...ectStateCollection|null adds the type Kaliop\eZMigrationBundle...n\ObjectStateCollection to the return on line 30 which is incompatible with the return type declared by the interface Kaliop\eZMigrationBundle...MatcherInterface::match of type array|Kaliop\eZMigrationBundle\API\ArrayObject.
Loading history...
31
    }
32
33
    /**
34
     * @param array $conditions key: condition, value: int / string / int[] / string[]
35
     * @return ObjectStateCollection
36
     */
37
    public function matchObjectState(array $conditions)
38
    {
39
        $this->validateConditions($conditions);
40
41
        foreach ($conditions as $key => $values) {
42
43
            if (!is_array($values)) {
44
                $values = array($values);
45
            }
46
47
            switch ($key) {
48
                case 'id':
49
                case self::MATCH_OBJECTSTATE_ID:
50
                   return new ObjectStateCollection($this->findObjectStatesById($values));
51
52
                case 'identifier':
53
                case self::MATCH_OBJECTSTATE_IDENTIFIER:
54
                    return new ObjectStateCollection($this->findObjectStatesByIdentifier($values));
55
            }
56
        }
57
    }
58
59
    protected function getConditionsFromKey($key)
60
    {
61
        if (is_int($key) || ctype_digit($key)) {
62
            return array(self::MATCH_OBJECTSTATE_ID => $key);
63
        }
64
        return array(self::MATCH_OBJECTSTATE_IDENTIFIER => $key);
65
    }
66
67
    /**
68
     * @param int[] $objectStateIds
69
     * @return ObjectState[]
70
     */
71
    protected function findObjectStatesById(array $objectStateIds)
72
    {
73
        $objectStates = [];
74
75
        foreach ($objectStateIds as $objectStateId) {
76
            // return unique contents
77
            $objectState = $this->repository->getObjectStateService()->loadObjectState($objectStateId);
78
            $objectStates[$objectState->id] = $objectState;
79
        }
80
81
        return $objectStates;
82
    }
83
84
    /**
85
     * @param string[] $stateIdentifiers Accepts the state identifier if unique, otherwise "group-identifier/state-identifier"
86
     * @return ObjectState[]
87
     * @throws NotFoundException
88
     */
89
    protected function findObjectStatesByIdentifier(array $stateIdentifiers)
90
    {
91
        // we have to build this list, as the ObjectStateService does not allow to load a State by identifier...
92
        $statesList = $this->loadAvailableStates();
93
94
        $states = [];
95
96
        foreach ($stateIdentifiers as $stateIdentifier) {
97
            if (!isset($statesList[$stateIdentifier])) {
98
                // a quick and dirty way of letting the user know that he/she might be using a non-unique identifier
99
                throw new NotFoundException("ObjectState", $stateIdentifier . ' missing or non unique');
100
            }
101
            $states[$statesList[$stateIdentifier]->id] = $statesList[$stateIdentifier];
102
        }
103
104
        return $states;
105
    }
106
107
    /**
108
     * @return ObjectState[] key: the state identifier (for unique identifiers), group_identifier/state_identifier for all
109
     */
110
    protected function loadAvailableStates()
111
    {
112
        $statesList = array();
113
        $nonuniqueIdentifiers = array();
114
115
        $groups = $this->repository->getObjectStateService()->loadObjectStateGroups();
116
        foreach ($groups as $group) {
117
            $groupStates = $this->repository->getObjectStateService()->loadObjectStates($group);
118
            foreach($groupStates as $groupState) {
119
                // we always add the states using 'group/state' identifiers
120
                $statesList[$group->identifier.'/'.$groupState->identifier] = $groupState;
121
                // we only add the state using plain identifier if it is unique
122
                if (isset($statesList[$groupState->identifier])) {
123
                    unset($statesList[$groupState->identifier]);
124
                    $nonuniqueIdentifiers[] = $groupState->identifier;
125
                } else {
126
                    if (!isset($nonuniqueIdentifiers[$groupState->identifier])) {
127
                        $statesList[$groupState->identifier] = $groupState;
128
                    }
129
                }
130
            }
131
        }
132
133
        return $statesList;
134
    }
135
}
136