RepositoryFactory::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * This file is part of the Kdyby (http://www.kdyby.org)
5
 *
6
 * Copyright (c) 2008 Filip Procházka ([email protected])
7
 *
8
 * For the full copyright and license information, please view the file license.txt that was distributed with this source code.
9
 */
10
11
namespace Kdyby\Doctrine;
12
13
use Doctrine;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Kdyby;
16
use Nette;
17
18
19
20
/**
21
 * @author Filip Procházka <[email protected]>
22
 */
23
class RepositoryFactory implements Doctrine\ORM\Repository\RepositoryFactory
24
{
25
26
	use \Kdyby\StrictObjects\Scream;
27
28
	/**
29
	 * @var Nette\DI\Container
30
	 */
31
	private $serviceLocator;
32
33
	/**
34
	 * The list of EntityRepository instances.
35
	 *
36
	 * @var Doctrine\ORM\EntityRepository[]
37
	 */
38
	private $repositoryList = [];
39
40
	/**
41
	 * @var array
42
	 */
43
	private $repositoryServicesMap = [];
44
45
	/**
46
	 * @var string
47
	 */
48
	private $defaultRepositoryFactory;
49
50
51
52
	public function __construct(Nette\DI\Container $serviceLocator)
53
	{
54
		$this->serviceLocator = $serviceLocator;
55
	}
56
57
58
59
	/**
60
	 * @param array $repositoryServicesMap [RepositoryType => repositoryServiceId]
61
	 * @param string $defaultRepositoryFactory
62
	 */
63
	public function setServiceIdsMap(array $repositoryServicesMap, $defaultRepositoryFactory)
64
	{
65
		$this->repositoryServicesMap = $repositoryServicesMap;
66
		$this->defaultRepositoryFactory = $defaultRepositoryFactory;
67
	}
68
69
70
71
	/**
72
	 * @param EntityManagerInterface|EntityManager $entityManager
73
	 * @param object|string $entityName
74
	 * @return Doctrine\ORM\EntityRepository
75
	 */
76
	public function getRepository(EntityManagerInterface $entityManager, $entityName)
77
	{
78
		if (is_object($entityName)) {
79
			$entityName = Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entityName));
80
		}
81
82
		$entityName = ltrim($entityName, '\\');
83
84
		$emId = spl_object_hash($entityManager);
85
		if (isset($this->repositoryList[$emId][$entityName])) {
86
			return $this->repositoryList[$emId][$entityName];
87
		}
88
89
		/** @var Doctrine\ORM\Mapping\ClassMetadata $metadata */
90
		$metadata = $entityManager->getClassMetadata($entityName);
91
		$repository = $this->createRepository($entityManager, $metadata);
92
93
		return $this->repositoryList[$emId][$entityName] = $repository;
94
	}
95
96
97
98
	/**
99
	 * Create a new repository instance for an entity class.
100
	 *
101
	 * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
102
	 * @param Doctrine\ORM\Mapping\ClassMetadata $metadata
103
	 * @return Doctrine\ORM\EntityRepository
104
	 */
105
	private function createRepository(EntityManagerInterface $entityManager, Doctrine\ORM\Mapping\ClassMetadata $metadata)
106
	{
107
		$defaultClass = $entityManager->getConfiguration()->getDefaultRepositoryClassName();
108
		$customClass = ltrim($metadata->customRepositoryClassName, '\\');
109
110
		if (empty($customClass) || $customClass === $defaultClass) {
111
			$factory = $this->getRepositoryFactory($this->defaultRepositoryFactory);
112
113
		} elseif (isset($this->repositoryServicesMap[$customClass])) {
114
			$factory = $this->getRepositoryFactory($this->repositoryServicesMap[$customClass]);
115
116
		} else {
117
			return new $customClass($entityManager, $metadata);
118
		}
119
120
		return $factory->create($entityManager, $metadata);
121
	}
122
123
124
125
	/**
126
	 * @param string $serviceName
127
	 * @return Kdyby\Doctrine\DI\IRepositoryFactory
128
	 */
129
	protected function getRepositoryFactory($serviceName)
130
	{
131
		$factory = $this->serviceLocator->getService($serviceName);
132
		if (!$factory instanceof Kdyby\Doctrine\DI\IRepositoryFactory) {
133
			throw new \RuntimeException("\$factory must be instance of" . Kdyby\Doctrine\DI\IRepositoryFactory::class);
134
		}
135
136
		return $factory;
137
	}
138
139
}
140