Completed
Push — master ( 170acb...bd48a4 )
by Daniel
04:18 queued 02:10
created

CollectionsAgent::find()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Psi\Bridge\ObjectAgent\Doctrine\Collections;
6
7
use Doctrine\Common\Collections\Criteria;
8
use Psi\Component\ObjectAgent\AgentInterface;
9
use Psi\Component\ObjectAgent\Exception\BadMethodCallException;
10
use Psi\Component\ObjectAgent\Exception\ObjectNotFoundException;
11
use Psi\Component\ObjectAgent\Query\Query;
12
13
class CollectionsAgent implements AgentInterface
14
{
15
    private $store;
16
17
    public function __construct(Store $store)
18
    {
19
        $this->store = $store;
20
    }
21
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public function supports(string $classFqn): bool
26
    {
27
        return $this->store->hasCollection($classFqn);
28
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function find($identifier, string $classFqn = null)
34
    {
35
        if (null === $classFqn) {
36
            throw BadMethodCallException::classArgumentIsMandatory(__CLASS__);
37
        }
38
39
        $object = $this->store->find($classFqn, $identifier);
40
41
        if (null === $object) {
42
            throw new ObjectNotFoundException(sprintf(
43
                'Could not find object of class "%s" with identifier "%s"',
44
                $classFqn, $identifier
45
            ));
46
        }
47
48
        return $object;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function save($object)
55
    {
56
        // do nothing ...
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function delete($object)
63
    {
64
        $this->store->delete($object);
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function query(Query $query): \Traversable
71
    {
72
        $collection = $this->store->getCollection($query->getClassFqn());
73
        $expressionBuilder = Criteria::expr();
74
        $visitor = new CollectionsVisitor($expressionBuilder);
75
        $doctrineExpression = $visitor->dispatch($query->getExpression());
76
        $criteria = new Criteria($doctrineExpression);
77
78
        return $collection->matching($criteria);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function getIdentifier($object)
85
    {
86
        foreach ($this->store->getCollection(get_class($object)) as $identifier => $element) {
87
            if ($element === $object) {
88
                return $identifier;
89
            }
90
        }
91
92
        throw new \RuntimeException(sprintf(
93
            'Could not find identifier for object of class "%s"',
94
            get_class($object)
95
        ));
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function setParent($object, $parent)
102
    {
103
        throw BadMethodCallException::setParentNotSupported(__CLASS__);
104
    }
105
}
106