Passed
Push — master ( 966fd5...e75d59 )
by Pavel
03:58
created

CollectionPersister::prefetch()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.243

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 10
cp 0.7
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
crap 3.243
1
<?php
2
3
namespace Bankiru\Api\Doctrine\Persister;
4
5
use Bankiru\Api\Doctrine\ApiEntityManager;
6
use Bankiru\Api\Doctrine\Mapping\ApiMetadata;
7
use Bankiru\Api\Doctrine\Proxy\LazyCriteriaCollection;
8
use Bankiru\Api\Doctrine\Utility\IdentifierFixer;
9
use Doctrine\Common\Collections\ArrayCollection;
10
use Doctrine\Common\Collections\Collection;
11
use Doctrine\Common\Collections\Criteria;
12
use Doctrine\Common\Collections\Selectable;
13
14
final class CollectionPersister
15
{
16
    /**
17
     * @var array
18
     */
19
    private $association;
20
    /**
21
     * @var ApiMetadata
22
     */
23
    private $metadata;
24
    /**
25
     * @var Selectable
26
     */
27
    private $matcher;
28
    /**
29
     * @var ApiEntityManager
30
     */
31
    private $manager;
32
33
    /**
34
     * CollectionPersister constructor.
35
     *
36
     * @param ApiEntityManager $manager
37
     * @param ApiMetadata      $metadata
38
     * @param Selectable       $matcher
39
     * @param array            $association
40
     *
41
     * @internal param CrudsApiInterface $api
42
     */
43 1
    public function __construct(
44
        ApiEntityManager $manager,
45
        ApiMetadata $metadata,
46
        Selectable $matcher,
47
        array $association
48
    ) {
49 1
        $this->association = $association;
50 1
        $this->metadata    = $metadata;
51 1
        $this->matcher     = $matcher;
52 1
        $this->manager     = $manager;
53 1
    }
54
55
    /**
56
     * Returns many to many collection for given identifiers.
57
     *
58
     * If every identifier is present in identifier map then initialized ArrayCollection is returned immediately
59
     *
60
     * @param array $identifiers
61
     *
62
     * @return Collection
63
     */
64 1
    public function getManyToManyCollection(array $identifiers)
65
    {
66 1
        if ($this->metadata->isIdentifierComposite()) {
67
            throw new \LogicException('Lazy loading entities with composite key is not supported');
68
        }
69
70 1
        $collection = $this->prefetch($identifiers);
71
72 1
        if (count($identifiers) === 0) {
73
            return $collection;
74
        }
75
76 1
        return $this->createLazyCriteria($identifiers, $collection);
77
    }
78
79
    /**
80
     * @param array $identifiers
81
     * @param       $collection
82
     *
83
     * @return LazyCriteriaCollection
84
     */
85 1
    private function createLazyCriteria(array $identifiers, $collection)
86 1
    {
87 1
        $identifierFields = $this->metadata->getIdentifierFieldNames();
88 1
        $identifierField  = array_shift($identifierFields);
89
90 1
        $criteria = new Criteria();
91 1
        $criteria->andWhere(Criteria::expr()->in($identifierField, array_values($identifiers)));
92
93 1
        if (null !== $this->association['orderBy']) {
94 1
            $criteria->orderBy($this->association['orderBy']);
95 1
        }
96
97 1
        return new LazyCriteriaCollection($this->matcher, $criteria, $collection);
98
    }
99
100
    /**
101
     * Prefetch some elements from identity map
102
     *
103
     * @param array $identifiers
104
     *
105
     * @return ArrayCollection
106
     */
107 1
    private function prefetch(array &$identifiers)
108
    {
109 1
        $prefetched = [];
110 1
        foreach ($identifiers as $key => $id) {
111 1
            $id = IdentifierFixer::fixScalarId($id, $this->metadata);
112 1
            if (false !== ($entity = $this->manager->getUnitOfWork()->tryGetById($id, $this->metadata->getName()))) {
113
                $prefetched[] = $entity;
114
                unset($identifiers[$key]);
115
            }
116 1
        }
117
118 1
        return new ArrayCollection($prefetched);
119
    }
120
}
121