From 7420f2ff98df44fccecee5f98112cea6aefa5842 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Thu, 22 Apr 2021 12:33:45 +0300 Subject: [PATCH] orm refactoring using injectable factory for entities --- application/Espo/Core/Entities/Person.php | 26 +++++++++-- application/Espo/Core/ORM/EntityFactory.php | 45 +++++++++++++++---- application/Espo/Core/ORM/EntityManager.php | 32 ------------- .../Espo/Core/ORM/EntityManagerFactory.php | 3 -- application/Espo/Core/ORM/Helper.php | 2 +- .../Espo/Core/ORM/RepositoryFactory.php | 10 ++--- application/Espo/ORM/EntityFactory.php | 2 +- .../Espo/ORM/Repository/RepositoryFactory.php | 2 +- 8 files changed, 68 insertions(+), 54 deletions(-) diff --git a/application/Espo/Core/Entities/Person.php b/application/Espo/Core/Entities/Person.php index 5a90a31847..102a775ebe 100644 --- a/application/Espo/Core/Entities/Person.php +++ b/application/Espo/Core/Entities/Person.php @@ -31,18 +31,38 @@ namespace Espo\Core\Entities; use Espo\Core\{ ORM\Entity, + ORM\Helper, Fields\EmailAddressGroup, Fields\PhoneNumberGroup, Fields\Address, }; +use Espo\ORM\{ + EntityManager, + Value\ValueAccessorFactory, +}; + class Person extends Entity { + private $helper; + + public function __construct( + string $entityType, + array $defs, + EntityManager $entityManager, + ValueAccessorFactory $valueAccessorFactory, + Helper $helper + ) { + parent::__construct($entityType, $defs, $entityManager, $valueAccessorFactory); + + $this->helper = $helper; + } + protected function _setLastName($value) { $this->setInContainer('lastName', $value); - $name = $this->getEntityManager()->getHelper()->formatPersonName($this, 'name'); + $name = $this->helper->formatPersonName($this, 'name'); $this->setInContainer('name', $name); } @@ -51,7 +71,7 @@ class Person extends Entity { $this->setInContainer('firstName', $value); - $name = $this->getEntityManager()->getHelper()->formatPersonName($this, 'name'); + $name = $this->helper->formatPersonName($this, 'name'); $this->setInContainer('name', $name); } @@ -60,7 +80,7 @@ class Person extends Entity { $this->setInContainer('middleName', $value); - $name = $this->getEntityManager()->getHelper()->formatPersonName($this, 'name'); + $name = $this->helper->formatPersonName($this, 'name'); $this->setInContainer('name', $name); } diff --git a/application/Espo/Core/ORM/EntityFactory.php b/application/Espo/Core/ORM/EntityFactory.php index 62eec9aeaf..b1ac4d81f6 100644 --- a/application/Espo/Core/ORM/EntityFactory.php +++ b/application/Espo/Core/ORM/EntityFactory.php @@ -33,7 +33,11 @@ use Espo\Core\Exceptions\Error; use Espo\Core\{ Utils\ClassFinder, + InjectableFactory, ORM\Entity as BaseEntity, + Binding\BindingContainer, + Binding\BindingData, + Binding\Binder, }; use Espo\ORM\{ @@ -47,18 +51,24 @@ class EntityFactory implements EntityFactoryInterface { private $classFinder; + private $helper; + + private $injectableFactory; + private $entityManager = null; private $valueAccessorFactory = null; - public function __construct(ClassFinder $classFinder) + public function __construct(ClassFinder $classFinder, Helper $helper, InjectableFactory $injectableFactory) { $this->classFinder = $classFinder; + $this->helper = $helper; + $this->injectableFactory = $injectableFactory; } - private function getClassName(string $name): ?string + private function getClassName(string $entityType): ?string { - return $this->classFinder->find('Entities', $name); + return $this->classFinder->find('Entities', $entityType); } public function setEntityManager(EntityManager $entityManager): void @@ -79,20 +89,39 @@ class EntityFactory implements EntityFactoryInterface $this->valueAccessorFactory = $valueAccessorFactory; } - public function create(string $name): Entity + public function create(string $entityType): Entity { - $className = $this->getClassName($name); + $className = $this->getClassName($entityType); if (!class_exists($className)) { $className = BaseEntity::class; } - $defs = $this->entityManager->getMetadata()->get($name); + $defs = $this->entityManager->getMetadata()->get($entityType); if (is_null($defs)) { - throw new Error("Entity '{$name}' is not defined in metadata."); + throw new Error("Entity '{$entityType}' is not defined in metadata."); } - return new $className($name, $defs, $this->entityManager, $this->valueAccessorFactory); + $bindingContainer = $this->getBindingContainer($className, $entityType, $defs); + + return $this->injectableFactory->createWithBinding($className, $bindingContainer); + } + + private function getBindingContainer(string $className, string $entityType, array $defs): BindingContainer + { + $data = new BindingData(); + + $binder = new Binder($data); + + $binder + ->for($className) + ->bindValue('$entityType', $entityType) + ->bindValue('$defs', $defs) + ->bindInstance(EntityManager::class, $this->entityManager) + ->bindInstance(ValueAccessorFactory::class, $this->valueAccessorFactory) + ->bindInstance(Helper::class, $this->helper); + + return new BindingContainer($data); } } diff --git a/application/Espo/Core/ORM/EntityManager.php b/application/Espo/Core/ORM/EntityManager.php index a3bcfa3899..ace9196846 100644 --- a/application/Espo/Core/ORM/EntityManager.php +++ b/application/Espo/Core/ORM/EntityManager.php @@ -31,41 +31,9 @@ namespace Espo\Core\ORM; use Espo\ORM\{ EntityManager as BaseEntityManager, - Metadata, - Value\ValueFactoryFactory, - Value\AttributeExtractorFactory, - EventDispatcher, }; class EntityManager extends BaseEntityManager { - private $helper; - public function __construct( - array $params, - Metadata $metadata, - RepositoryFactory $repositoryFactory, - EntityFactory $entityFactory, - ValueFactoryFactory $valueFactoryFactory, - AttributeExtractorFactory $attributeExtractorFactory, - EventDispatcher $eventDispatcher, - Helper $helper - ) { - parent::__construct( - $params, - $metadata, - $repositoryFactory, - $entityFactory, - $valueFactoryFactory, - $attributeExtractorFactory, - $eventDispatcher - ); - - $this->helper = $helper; - } - - public function getHelper(): Helper - { - return $this->helper; - } } diff --git a/application/Espo/Core/ORM/EntityManagerFactory.php b/application/Espo/Core/ORM/EntityManagerFactory.php index 7436a41929..d232bd3e8f 100644 --- a/application/Espo/Core/ORM/EntityManagerFactory.php +++ b/application/Espo/Core/ORM/EntityManagerFactory.php @@ -69,8 +69,6 @@ class EntityManagerFactory 'entityFactory' => $entityFactory, ]); - $helper = $this->injectableFactory->create(Helper::class); - $config = $this->config; $params = [ @@ -115,7 +113,6 @@ class EntityManagerFactory 'valueFactoryFactory' => $valueFactoryFactory, 'attributeExtractorFactory' => $attributeExtractorFactory, 'eventDispatcher' => $this->eventDispatcher, - 'helper' => $helper, ] ); diff --git a/application/Espo/Core/ORM/Helper.php b/application/Espo/Core/ORM/Helper.php index c104eed062..fe12990903 100644 --- a/application/Espo/Core/ORM/Helper.php +++ b/application/Espo/Core/ORM/Helper.php @@ -35,7 +35,7 @@ use Espo\ORM\Entity; class Helper { - protected $config; + private $config; public function __construct(Config $config) { diff --git a/application/Espo/Core/ORM/RepositoryFactory.php b/application/Espo/Core/ORM/RepositoryFactory.php index f0774409f7..1b0df05429 100644 --- a/application/Espo/Core/ORM/RepositoryFactory.php +++ b/application/Espo/Core/ORM/RepositoryFactory.php @@ -61,14 +61,14 @@ class RepositoryFactory implements RepositoryFactoryInterface $this->classFinder = $classFinder; } - protected function getClassName(string $name): ?string + protected function getClassName(string $entityType): ?string { - return $this->classFinder->find('Repositories', $name); + return $this->classFinder->find('Repositories', $entityType); } - public function create(string $name): Repository + public function create(string $entityType): Repository { - $className = $this->getClassName($name); + $className = $this->getClassName($entityType); if (!$className || !class_exists($className)) { $className = $this->defaultClassName; @@ -76,7 +76,7 @@ class RepositoryFactory implements RepositoryFactoryInterface return $this->injectableFactory->createWith($className, [ 'entityFactory' => $this->entityFactory, - 'entityType' => $name, + 'entityType' => $entityType, ]); } } diff --git a/application/Espo/ORM/EntityFactory.php b/application/Espo/ORM/EntityFactory.php index cecf320105..06035c90ee 100644 --- a/application/Espo/ORM/EntityFactory.php +++ b/application/Espo/ORM/EntityFactory.php @@ -36,7 +36,7 @@ interface EntityFactory /** * Create an entity. */ - public function create(string $name): Entity; + public function create(string $entityType): Entity; /** * For internal use. diff --git a/application/Espo/ORM/Repository/RepositoryFactory.php b/application/Espo/ORM/Repository/RepositoryFactory.php index 15b2ee8b8c..b4dcc24db0 100644 --- a/application/Espo/ORM/Repository/RepositoryFactory.php +++ b/application/Espo/ORM/Repository/RepositoryFactory.php @@ -31,5 +31,5 @@ namespace Espo\ORM\Repository; interface RepositoryFactory { - public function create(string $name): Repository; + public function create(string $entityType): Repository; }