container = $c; $connectionNames = $c->get('doctrine.connections'); foreach ($connectionNames as $connectionName) { $this->indexConnection($connectionName); } $this->finishIndex(); } private function indexConnection(string $name) { $fullConnectionKey = 'doctrine.connection.' . $name; $fullEntityPathKey = 'doctrine.entity-paths.' . $name; if (!$this->container->has($fullEntityPathKey) || !$this->container->has($fullConnectionKey)) { return; } $entityPaths = $this->container->get($fullEntityPathKey); foreach ($entityPaths as $entityPath) { $this->entityManagerPathMap[$entityPath] = $name; } $this->entityManagerPaths = array_merge($this->entityManagerPaths, $entityPaths); } private function finishIndex() { sort($this->entityManagerPaths, SORT_DESC); sort($this->entityManagerKeys, SORT_DESC); } /** * @param $object * @return DefaultEntityManager * @throws \Doctrine\ORM\ORMException * @throws \ReflectionException */ public function getEntityManagerForObject($object): DefaultEntityManager { return $this->getEntityManagerForClass(get_class($object)); } /** * @param string $className * @return DefaultEntityManager * @throws \Doctrine\ORM\ORMException * @throws \ReflectionException */ public function getEntityManagerForClass(string $className): DefaultEntityManager { if (!isset($this->entityMangerKeyCache[$className])) { $this->entityMangerKeyCache[$className] = $this->resolveEntityManagerKeyForClass($className); } return $this->getResponsibleEntityManager($this->entityMangerKeyCache[$className]); } /** * @param string $className * @return string * @throws \ReflectionException */ private function resolveEntityManagerKeyForClass(string $className): string { if (isset($this->entityManagerKeyMap[$className])) { return $this->entityManagerKeyMap[$className]; } $reflection = new \ReflectionClass($className); $filePath = $reflection->getFileName(); foreach ($this->entityManagerPaths as $entityManagerPath) { if (strlen($entityManagerPath) > strlen($filePath)) { continue; } if (substr($filePath, 0, strlen($entityManagerPath)) === $entityManagerPath) { return $this->entityManagerPathMap[$entityManagerPath]; } } foreach ($this->entityManagerKeys as $entityManagerKey) { if (strlen($entityManagerKey) > strlen($className)) { continue; } if (substr($className, 0, strlen($entityManagerKey)) === $entityManagerKey) { return $this->entityManagerKeyMap[$entityManagerKey]; } } return 'default'; } /** * @param string $name * @return DefaultEntityManager */ public function getResponsibleEntityManager(string $name): DefaultEntityManager { if (!isset($this->entityManagers[$name])) { $this->entityManagers[$name] = $this->createEntityManager($name); } return $this->entityManagers[$name]; } protected function createEntityManager(string $name): DefaultEntityManager { if (!$this->container->has('doctrine.connection.' . $name)) { throw new \RuntimeException("Connection '{$name}' doesn't exist"); } $connection = $this->container->get('doctrine.connection.' . $name); if (!$this->container->has('doctrine.entity-paths.' . $name)) { throw new \RuntimeException("No entity paths defined for connection '{$name}'"); } $paths = $this->container->get('doctrine.entity-paths.' . $name); $config = Setup::createAnnotationMetadataConfiguration( $paths, $this->container->get('doctrine.debug'), null, null, false ); return DefaultEntityManager::create($connection, $config, null, $name); } /** * @param $className * @param $id * @return null|object * @throws \Doctrine\ORM\ORMException * @throws \ReflectionException */ public function find($className, $id) { return $this->getEntityManagerForClass($className)->find($className, $id); } public function persist($object) { return $this->getEntityManagerForObject($object)->persist($object); } public function remove($object) { return $this->getEntityManagerForObject($object)->remove($object); } public function merge($object) { return $this->getEntityManagerForObject($object)->merge($object); } public function clear($objectName = null) { if ($objectName !== null) { return $this->getEntityManagerForClass($objectName)->clear($objectName); } foreach ($this->entityManagers as $entityManager) { $entityManager->clear(); } } public function detach($object) { return $this->getEntityManagerForObject($object)->detach($object); } public function refresh($object) { return $this->getEntityManagerForObject($object)->refresh($object); } public function flush($entity = null) { if ($entity !== null) { return $this->getEntityManagerForObject($entity)->flush($entity); } foreach ($this->entityManagers as $entityManager) { $entityManager->flush(); } } public function getRepository($className) { return $this->getEntityManagerForClass($className)->getRepository($className); } public function getClassMetadata($className) { return $this->getEntityManagerForClass($className)->getClassMetadata($className); } public function initializeObject($object) { return $this->getEntityManagerForObject($object)->initializeObject($object); } public function contains($object) { return $this->getEntityManagerForObject($object)->contains($object); } public function close() { foreach ($this->entityManagers as $entityManager) { $entityManager->close(); } } public function copy($entity, $deep = false) { return $this->getEntityManagerForObject($entity)->copy($entity, $deep); } public function lock($entity, $lockMode, $lockVersion = null) { return $this->getEntityManagerForObject($entity)->lock($entity, $lockMode, $lockVersion); } }