Code

< 40 %
40-60 %
> 60 %
1
<?php
2
3
namespace Bankiru\Api\Doctrine;
4
5
use Bankiru\Api\Doctrine\Mapping\ApiMetadata;
6
use Bankiru\Api\Doctrine\Mapping\EntityMetadata;
7
use Bankiru\Api\Doctrine\Proxy\ApiCollection;
8
use Bankiru\Api\Doctrine\Proxy\ProxyFactory;
9
use Bankiru\Api\Doctrine\Utility\IdentifierFixer;
10
use Doctrine\Common\Persistence\ObjectRepository;
11
use Doctrine\Common\Proxy\Proxy;
12
13
class EntityManager implements ApiEntityManager
14
{
15
    /** @var EntityMetadataFactory */
16
    private $metadataFactory;
17
    /** @var  Configuration */
18
    private $configuration;
19
    /** @var ObjectRepository[] */
20
    private $repositories = [];
21
    /** @var UnitOfWork */
22
    private $unitOfWork;
23
    /** @var ProxyFactory */
24
    private $proxyFactory;
25
26
    /**
27
     * EntityManager constructor.
28
     *
29
     * @param Configuration $configuration
30
     */
31
    public function __construct(Configuration $configuration)
32
    {
33
        $this->configuration = $configuration;
34
35
        $this->metadataFactory = $configuration->getMetadataFactory();
36
        $this->metadataFactory->setEntityManager($this);
37
38
        $this->unitOfWork   = new UnitOfWork($this);
39
        $this->proxyFactory = new ProxyFactory($this);
40
    }
41
42
    /** {@inheritdoc} */
43
    public function getConfiguration()
44
    {
45
        return $this->configuration;
46
    }
47
48
    /** {@inheritdoc} */
49
    public function find($className, $id)
50
    {
51
        $metadata = $this->getClassMetadata($className);
52
        $id       = IdentifierFixer::fixScalarId($id, $metadata);
53
54
        /** @var EntityMetadata $metadata */
55
        if (false !== ($entity = $this->getUnitOfWork()->tryGetById($id, $metadata->rootEntityName))) {
56
            return $entity instanceof $metadata->name ? $entity : null;
57
        }
58
59
        return $this->getUnitOfWork()->getEntityPersister($className)->loadById($id);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     * @return ApiMetadata
65
     */
66
    public function getClassMetadata($className)
67
    {
68
        return $this->getMetadataFactory()->getMetadataFor($className);
69
    }
70
71
    /** {@inheritdoc} */
72
    public function getMetadataFactory()
73
    {
74
        return $this->metadataFactory;
75
    }
76
77
    /** {@inheritdoc} */
78
    public function getUnitOfWork()
79
    {
80
        return $this->unitOfWork;
81
    }
82
83
    /** {@inheritdoc} */
84
    public function persist($object)
85
    {
86
        if (!is_object($object)) {
87
            throw new \InvalidArgumentException('Not an object to persist');
88
        }
89
90
        $this->getUnitOfWork()->persist($object);
91
    }
92
93
    /** {@inheritdoc} */
94
    public function remove($object)
95
    {
96
        $this->getUnitOfWork()->getEntityPersister(get_class($object))
97
                ->delete($object);
98
    }
99
100
    /** {@inheritdoc} */
101
    public function merge($object)
102
    {
103
        throw new \BadMethodCallException('Merge is not supported');
104
    }
105
106
    /** {@inheritdoc} */
107
    public function clear($objectName = null)
108
    {
109
        $this->getUnitOfWork()->clear($objectName);
110
    }
111
112
    /** {@inheritdoc} */
113
    public function detach($object)
114
    {
115
        $this->getUnitOfWork()->detach($object);
116
    }
117
118
    /** {@inheritdoc} */
119
    public function refresh($object)
120
    {
121
        $this->getRepository(get_class($object))->find($object->getId());
122
    }
123
124
    /** {@inheritdoc} */
125
    public function getRepository($className)
126
    {
127
        if (!array_key_exists($className, $this->repositories)) {
128
            /** @var ApiMetadata $metadata */
129
            $metadata        = $this->getClassMetadata($className);
130
            $repositoryClass = $metadata->getRepositoryClass();
131
            /** @noinspection PhpInternalEntityUsedInspection */
132
            $this->repositories[$className] = new $repositoryClass($this, $className);
133
        }
134
135
        return $this->repositories[$className];
136
    }
137
138
    /** {@inheritdoc} */
139
    public function flush($entity = null)
140
    {
141
        $this->unitOfWork->commit($entity);
142
    }
143
144
    /** {@inheritdoc} */
145
    public function initializeObject($obj)
146
    {
147
        if ($obj instanceof Proxy && !$obj->__isInitialized()) {
148
            $obj->__load();
149
        } elseif ($obj instanceof ApiCollection) {
150
            $obj->initialize();
151
        }
152
    }
153
154
    /** {@inheritdoc} */
155
    public function contains($object)
156
    {
157
        return false;
158
    }
159
160
    /**
161
     * Gets a reference to the entity identified by the given type and identifier
162
     * without actually loading it, if the entity is not yet loaded.
163
     *
164
     * @param string $entityName The name of the entity type.
165
     * @param mixed  $id         The entity identifier.
166
     *
167
     * @return object The entity reference.
168
     */
169
    public function getReference($entityName, $id)
170
    {
171
        /** @var EntityMetadata $metadata */
172
        $metadata = $this->getClassMetadata($entityName);
173
        $id       = IdentifierFixer::fixScalarId($id, $metadata);
174
175
        if (false !== ($entity = $this->getUnitOfWork()->tryGetById($id, $metadata->rootEntityName))) {
176
            return $entity instanceof $metadata->name ? $entity : null;
177
        }
178
179
        $proxy = $this->getProxyFactory()->getProxy($entityName, $id);
180
        $this->getUnitOfWork()->registerManaged($proxy, $id, null);
181
182
        return $proxy;
183
    }
184
185
    /** {@inheritdoc} */
186
    public function getProxyFactory()
187
    {
188
        return $this->proxyFactory;
189
    }
190
}
191