AbstractManagerRegistry.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. namespace Doctrine\Persistence;
  3. use InvalidArgumentException;
  4. use ReflectionClass;
  5. use function explode;
  6. use function sprintf;
  7. use function strpos;
  8. /**
  9. * Abstract implementation of the ManagerRegistry contract.
  10. */
  11. abstract class AbstractManagerRegistry implements ManagerRegistry
  12. {
  13. /** @var string */
  14. private $name;
  15. /** @var string[] */
  16. private $connections;
  17. /** @var string[] */
  18. private $managers;
  19. /** @var string */
  20. private $defaultConnection;
  21. /** @var string */
  22. private $defaultManager;
  23. /** @var string */
  24. private $proxyInterfaceName;
  25. /**
  26. * @param string $name
  27. * @param string[] $connections
  28. * @param string[] $managers
  29. * @param string $defaultConnection
  30. * @param string $defaultManager
  31. * @param string $proxyInterfaceName
  32. */
  33. public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName)
  34. {
  35. $this->name = $name;
  36. $this->connections = $connections;
  37. $this->managers = $managers;
  38. $this->defaultConnection = $defaultConnection;
  39. $this->defaultManager = $defaultManager;
  40. $this->proxyInterfaceName = $proxyInterfaceName;
  41. }
  42. /**
  43. * Fetches/creates the given services.
  44. *
  45. * A service in this context is connection or a manager instance.
  46. *
  47. * @param string $name The name of the service.
  48. *
  49. * @return ObjectManager The instance of the given service.
  50. */
  51. abstract protected function getService($name);
  52. /**
  53. * Resets the given services.
  54. *
  55. * A service in this context is connection or a manager instance.
  56. *
  57. * @param string $name The name of the service.
  58. *
  59. * @return void
  60. */
  61. abstract protected function resetService($name);
  62. /**
  63. * Gets the name of the registry.
  64. *
  65. * @return string
  66. */
  67. public function getName()
  68. {
  69. return $this->name;
  70. }
  71. /**
  72. * {@inheritdoc}
  73. */
  74. public function getConnection($name = null)
  75. {
  76. if ($name === null) {
  77. $name = $this->defaultConnection;
  78. }
  79. if (! isset($this->connections[$name])) {
  80. throw new InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name));
  81. }
  82. return $this->getService($this->connections[$name]);
  83. }
  84. /**
  85. * {@inheritdoc}
  86. */
  87. public function getConnectionNames()
  88. {
  89. return $this->connections;
  90. }
  91. /**
  92. * {@inheritdoc}
  93. */
  94. public function getConnections()
  95. {
  96. $connections = [];
  97. foreach ($this->connections as $name => $id) {
  98. $connections[$name] = $this->getService($id);
  99. }
  100. return $connections;
  101. }
  102. /**
  103. * {@inheritdoc}
  104. */
  105. public function getDefaultConnectionName()
  106. {
  107. return $this->defaultConnection;
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. public function getDefaultManagerName()
  113. {
  114. return $this->defaultManager;
  115. }
  116. /**
  117. * {@inheritdoc}
  118. *
  119. * @throws InvalidArgumentException
  120. */
  121. public function getManager($name = null)
  122. {
  123. if ($name === null) {
  124. $name = $this->defaultManager;
  125. }
  126. if (! isset($this->managers[$name])) {
  127. throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
  128. }
  129. return $this->getService($this->managers[$name]);
  130. }
  131. /**
  132. * {@inheritdoc}
  133. */
  134. public function getManagerForClass($class)
  135. {
  136. // Check for namespace alias
  137. if (strpos($class, ':') !== false) {
  138. [$namespaceAlias, $simpleClassName] = explode(':', $class, 2);
  139. $class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
  140. }
  141. $proxyClass = new ReflectionClass($class);
  142. if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
  143. $parentClass = $proxyClass->getParentClass();
  144. if (! $parentClass) {
  145. return null;
  146. }
  147. $class = $parentClass->getName();
  148. }
  149. foreach ($this->managers as $id) {
  150. $manager = $this->getService($id);
  151. if (! $manager->getMetadataFactory()->isTransient($class)) {
  152. return $manager;
  153. }
  154. }
  155. return null;
  156. }
  157. /**
  158. * {@inheritdoc}
  159. */
  160. public function getManagerNames()
  161. {
  162. return $this->managers;
  163. }
  164. /**
  165. * {@inheritdoc}
  166. */
  167. public function getManagers()
  168. {
  169. $dms = [];
  170. foreach ($this->managers as $name => $id) {
  171. $dms[$name] = $this->getService($id);
  172. }
  173. return $dms;
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. public function getRepository($persistentObject, $persistentManagerName = null)
  179. {
  180. return $this
  181. ->selectManager($persistentObject, $persistentManagerName)
  182. ->getRepository($persistentObject);
  183. }
  184. /**
  185. * {@inheritdoc}
  186. */
  187. public function resetManager($name = null)
  188. {
  189. if ($name === null) {
  190. $name = $this->defaultManager;
  191. }
  192. if (! isset($this->managers[$name])) {
  193. throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
  194. }
  195. // force the creation of a new document manager
  196. // if the current one is closed
  197. $this->resetService($this->managers[$name]);
  198. return $this->getManager($name);
  199. }
  200. private function selectManager(string $persistentObjectName, ?string $persistentManagerName = null): ObjectManager
  201. {
  202. if ($persistentManagerName !== null) {
  203. return $this->getManager($persistentManagerName);
  204. }
  205. return $this->getManagerForClass($persistentObjectName) ?? $this->getManager();
  206. }
  207. }