Completed
Push — master ( 00ac10...57b531 )
by Filipe
03:06
created

Orm::createRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 10
cts 10
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of slick/orm package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Orm;
11
12
use Slick\Database\Adapter\AdapterInterface;
13
use Slick\Orm\Descriptor\EntityDescriptor;
14
use Slick\Orm\Descriptor\EntityDescriptorRegistry;
15
use Slick\Orm\Exception\InvalidArgumentException;
16
use Slick\Orm\Mapper\EntityMapper;
17
use Slick\Orm\Mapper\MappersMap;
18
use Slick\Orm\Repository\EntityRepository;
19
use Slick\Orm\Repository\RepositoryMap;
20
21
/**
22
 * Orm registry
23
 *
24
 * @package Slick\Orm
25
 * @author  Filipe Silva <[email protected]>
26
 */
27
final class Orm
28
{
29
30
    /**
31
     * @var MappersMap|EntityMapperInterface[]
32
     */
33
    private $mappers;
34
35
    /**
36
     * @var Orm
37
     */
38
    private static $instance;
39
40
    /**
41
     * @var AdaptersMap
42
     */
43
    private $adapters;
44
45
    /**
46
     * @var RepositoryMap
47
     */
48
    private $repositories;
49
50
    /**
51
     * Initialize Orm registry with empty lists
52
     */
53 2
    private function __construct()
54
    {
55 2
        $this->mappers = new MappersMap();
56 2
        $this->adapters = new AdaptersMap();
57 2
        $this->repositories = new RepositoryMap();
58 2
    }
59
60
    /**
61
     * Avoid clone on a singleton
62
     * @codeCoverageIgnore
63
     */
64
    private function __clone()
65
    {
66
67
    }
68
69
    /**
70
     * Gets a ORM registry instance
71
     *
72
     * @return Orm
73
     */
74 16
    public static function getInstance()
75
    {
76 16
        if (null === self::$instance) {
77 2
            self::$instance = new static;
78 1
        }
79 16
        return self::$instance;
80
    }
81
82
    /**
83
     * Retrieves the mapper for provided entity
84
     *
85
     * If mapper does not exists it will be created and stored in the
86
     * mapper map.
87
     *
88
     * @param String $entity
89
     * @return EntityMapper
90
     */
91 6
    public static function getMapper($entity)
92
    {
93 6
        return self::getInstance()->getMapperFor($entity);
94
    }
95
96
    /**
97
     * Gets repository for provided entity class name
98
     *
99
     * @param string $entityClass FQ entity class name
100
     *
101
     * @return EntityRepository
102
     *
103
     * @throws InvalidArgumentException If provide class name is not
104
     *   from a class that implements the EntityInterface interface.
105
     */
106 8
    public static function getRepository($entityClass)
107
    {
108 8
        return self::getInstance()->getRepositoryFor($entityClass);
109
    }
110
111
    /**
112
     * Gets repository for provided entity class name
113
     *
114
     * @param string $entityClass FQ entity class name
115
     *
116
     * @return EntityRepository
117
     *
118
     * @throws InvalidArgumentException If provide class name is not
119
     *   from a class that implements the EntityInterface interface.
120
     */
121 8
    public function getRepositoryFor($entityClass)
122
    {
123 8
        if (!is_subclass_of($entityClass, EntityInterface::class)) {
124 2
            throw new InvalidArgumentException(
125
                'Cannot create ORM repository for a class that does not '.
126 1
                'implement EntityInterface.'
127 1
            );
128
        }
129
130 6
        return $this->repositories->containsKey($entityClass)
131 5
            ? $this->repositories->get($entityClass)
132 6
            : $this->createRepository($entityClass);
133
    }
134
135
    /**
136
     * Creates a repository for provided entity class name
137
     *
138
     * @param string $entityClass
139
     * @return EntityRepository
140
     */
141 2
    private function createRepository($entityClass)
142
    {
143 2
        $repository = new EntityRepository();
144 2
        $repository->setAdapter(
145 2
            $this->adapters->get($this->getAdapterAlias($entityClass))
146 1
        )
147 2
            ->setEntityMapper($this->getMapperFor($entityClass))
148 2
            ->setEntityDescriptor(EntityDescriptorRegistry::getInstance()
149 2
                ->getDescriptorFor($entityClass));
150 2
        $this->repositories->set($entityClass, $repository);
151 2
        return $repository;
152
    }
153
154
    /**
155
     * Retrieves the mapper for provided entity
156
     *
157
     * If mapper does not exists it will be created and stored in the
158
     * mapper map.
159
     *
160
     * @param string $entity
161
     * @return EntityMapper
162
     */
163 8
    public function getMapperFor($entity)
164
    {
165 8
        return  $this->mappers->containsKey($entity)
166 6
            ? $this->mappers->get($entity)
167 8
            : $this->createMapper($entity);
168
    }
169
170
    /**
171
     * Sets default adapter
172
     *
173
     * @param AdapterInterface $adapter
174
     * @return $this|Orm|self
175
     */
176 10
    public function setDefaultAdapter(AdapterInterface $adapter)
177
    {
178 10
        return $this->setAdapter('default', $adapter);
179
    }
180
181
    /**
182
     * Sets an adapter mapped with alias name
183
     *
184
     * @param string $alias
185
     * @param AdapterInterface $adapter
186
     *
187
     * @return $this|Orm|self
188
     */
189 10
    public function setAdapter($alias, AdapterInterface $adapter)
190
    {
191 10
        $this->adapters->set($alias, $adapter);
192 10
        return $this;
193
    }
194
195
    /**
196
     * Creates entity map for provided entity
197
     *
198
     * @param string $entity
199
     * @return EntityMapper
200
     */
201 4
    private function createMapper($entity)
202
    {
203 4
        $mapper = new EntityMapper();
204 4
        $mapper->setAdapter(
205 4
            $this->adapters->get(
206 4
                $this->getAdapterAlias($entity)
207 2
            )
208 2
        )
209 4
            ->setEntityClassName($entity);
210 4
        $this->mappers->set($entity, $mapper);
211 4
        return $mapper;
212
    }
213
214
    /**
215
     * Gets the adapter alias for current working entity
216
     *
217
     * @param string $entity
218
     *
219
     * @return EntityDescriptor|string
220
     */
221 6
    private function getAdapterAlias($entity)
222
    {
223 6
        $descriptor = EntityDescriptorRegistry::getInstance()
224 6
            ->getDescriptorFor($entity);
225 6
        return $descriptor->getAdapterAlias()
226 6
            ? $descriptor->getAdapterAlias()
227 6
            : 'default';
228
    }
229
}