diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index 211dccb56e..a872d67ce5 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -30,7 +30,7 @@ namespace Espo\Core; use Espo\Core\{ - ContainerBuilder, + Container\ContainerBuilder, InjectableFactory, Container, ApplicationUser, diff --git a/application/Espo/Core/Binding/DefaultBinding.php b/application/Espo/Core/Binding/DefaultBinding.php index 5c4bdd7d7c..a238a8e9b4 100644 --- a/application/Espo/Core/Binding/DefaultBinding.php +++ b/application/Espo/Core/Binding/DefaultBinding.php @@ -43,6 +43,11 @@ class DefaultBinding 'container' ); + $binder->bindService( + 'Espo\\Core\\Container\\Container', + 'container' + ); + $binder->bindService( 'Espo\\ORM\\EntityManager', 'entityManager' diff --git a/application/Espo/Core/Container.php b/application/Espo/Core/Container.php index e41d06cff1..d1808f0252 100644 --- a/application/Espo/Core/Container.php +++ b/application/Espo/Core/Container.php @@ -30,20 +30,21 @@ namespace Espo\Core; use Espo\Core\{ - Exceptions\Error, InjectableFactory, - Loaders\Loader, + Container\Loader, + Container\Container as ContainerInterface, Binding\BindingContainer, }; use ReflectionClass; +use RuntimeException; /** * DI container for services. Lazy initialization is used. Services are instantiated only once. * * See https://docs.espocrm.com/development/di/. */ -class Container +class Container implements ContainerInterface { private $data = []; @@ -51,9 +52,9 @@ class Container private $loaderClassNames; - protected $configuration = null; + private $configuration = null; - protected $injectableFactory; + private $injectableFactory; public function __construct( string $configurationClassName, @@ -65,7 +66,7 @@ class Container foreach ($services as $name => $service) { if (!is_string($name) || !is_object($service)) { - throw new Error("Container: Bad service passed."); + throw new RuntimeException("Container: Bad service passed."); } $this->setForced($name, $service); @@ -80,6 +81,8 @@ class Container /** * Obtain a service object. + * + * @throws RuntimeException If not gettable. */ public function get(string $name) : object { @@ -87,7 +90,7 @@ class Container $this->load($name); if (!$this->isSet($name)) { - throw new Error("Could not load '{$name}' service."); + throw new RuntimeException("Could not load '{$name}' service."); } } @@ -133,7 +136,7 @@ class Container return isset($this->data[$name]); } - private function initClass(string $name) + private function initClass(string $name) : void { if ($this->isSet($name)) { $object = $this->get($name); @@ -165,7 +168,7 @@ class Container $loadMethod = $loaderClass->getMethod('load'); if (!$loadMethod->hasReturnType()) { - throw new Error("Loader method for service '{$name}' does not have a return type."); + throw new RuntimeException("Loader method for service '{$name}' does not have a return type."); } $className = $loadMethod->getReturnType()->getName(); @@ -182,11 +185,13 @@ class Container /** * Get a class of a service. + * + * @throws RuntimeException If not gettable. */ public function getClass(string $name) : ReflectionClass { if (!$this->has($name)) { - throw new Error("Service '{$name}' does not exist."); + throw new RuntimeException("Service '{$name}' does not exist."); } if (!isset($this->classCache[$name])) { @@ -198,21 +203,23 @@ class Container /** * Set a service object. Must be configured as settable. + * + * @throws RuntimeException Is not settable or already set. */ public function set(string $name, object $object) : void { if (!$this->configuration->isSettable($name)) { - throw new Error("Service '{$name}' is not settable."); + throw new RuntimeException("Service '{$name}' is not settable."); } if ($this->isSet($name)) { - throw new Error("Service '{$name}' is already set."); + throw new RuntimeException("Service '{$name}' is already set."); } $this->setForced($name, $object); } - protected function setForced(string $name, object $object) + protected function setForced(string $name, object $object) : void { $this->data[$name] = $object; } @@ -254,7 +261,7 @@ class Container $className = $this->configuration->getServiceClassName($name); if (!$className || !class_exists($className)) { - throw new Error("Could not load '{$name}' service."); + throw new RuntimeException("Could not load '{$name}' service."); } $dependencyList = $this->configuration->getServiceDependencyList($name); diff --git a/application/Espo/Core/Container/Container.php b/application/Espo/Core/Container/Container.php new file mode 100644 index 0000000000..054aca13b4 --- /dev/null +++ b/application/Espo/Core/Container/Container.php @@ -0,0 +1,67 @@ +container = $container; diff --git a/application/Espo/Core/Loaders/Language.php b/application/Espo/Core/Loaders/Language.php index 521482c1f7..82a74ec78b 100644 --- a/application/Espo/Core/Loaders/Language.php +++ b/application/Espo/Core/Loaders/Language.php @@ -30,6 +30,7 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, Utils\Metadata, Utils\Config, Utils\File\Manager as FileManager, @@ -42,9 +43,13 @@ use Espo\Entities\Preferences; class Language implements Loader { protected $fileManager; + protected $config; + protected $metadata; + protected $dataCache; + protected $preferences; public function __construct( diff --git a/application/Espo/Core/Loaders/Loader.php b/application/Espo/Core/Loaders/Loader.php index 80008f831f..5764e1f043 100644 --- a/application/Espo/Core/Loaders/Loader.php +++ b/application/Espo/Core/Loaders/Loader.php @@ -29,8 +29,11 @@ namespace Espo\Core\Loaders; -interface Loader +use Espo\Core\Container\Loader as BaseLoader; + +/** + * @deprecated Since v6.2.0. Use `Espo\Core\Container\Loader`. + */ +interface Loader extends BaseLoader { - // @todo Uncomment when PHP 7.4 is a min supported version. - //public function load() : object; } diff --git a/application/Espo/Core/Loaders/Log.php b/application/Espo/Core/Loaders/Log.php index 2d1389383d..02cb5d0827 100644 --- a/application/Espo/Core/Loaders/Log.php +++ b/application/Espo/Core/Loaders/Log.php @@ -30,13 +30,14 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, Log\LogLoader, Utils\Log as LogService, }; class Log implements Loader { - protected $logLoader; + private $logLoader; public function __construct(LogLoader $logLoader) { @@ -47,6 +48,7 @@ class Log implements Loader { $log = $this->logLoader->load(); + // @todo Remove in future. $GLOBALS['log'] = $log; return $log; diff --git a/application/Espo/Core/Loaders/Metadata.php b/application/Espo/Core/Loaders/Metadata.php index 21dafedc4f..474702e28e 100644 --- a/application/Espo/Core/Loaders/Metadata.php +++ b/application/Espo/Core/Loaders/Metadata.php @@ -30,8 +30,8 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, Utils\Metadata as MetadataService, - InjectableFactory, Utils\File\Manager as FileManager, Utils\DataCache, Utils\Config, @@ -39,9 +39,11 @@ use Espo\Core\{ class Metadata implements Loader { - protected $fileManager; - protected $dataCache; - protected $config; + private $fileManager; + + private $dataCache; + + private $config; public function __construct(FileManager $fileManager, DataCache $dataCache, Config $config) { diff --git a/application/Espo/Core/Loaders/NumberUtil.php b/application/Espo/Core/Loaders/NumberUtil.php index a1738fc860..1fd23d90ef 100644 --- a/application/Espo/Core/Loaders/NumberUtil.php +++ b/application/Espo/Core/Loaders/NumberUtil.php @@ -30,13 +30,14 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, Utils\Config, Utils\NumberUtil as NumberUtilService, }; class NumberUtil implements Loader { - protected $config; + private $config; public function __construct(Config $config) { diff --git a/application/Espo/Core/Loaders/OrmDefs.php b/application/Espo/Core/Loaders/OrmDefs.php index 2cbef6d05b..38cb15b8be 100644 --- a/application/Espo/Core/Loaders/OrmDefs.php +++ b/application/Espo/Core/Loaders/OrmDefs.php @@ -29,6 +29,10 @@ namespace Espo\Core\Loaders; +use Espo\{ + Core\Container\Loader, +}; + use Espo\{ ORM\Defs\Defs, ORM\EntityManager, @@ -36,7 +40,7 @@ use Espo\{ class OrmDefs implements Loader { - protected $entityManager; + private $entityManager; public function __construct(EntityManager $entityManager) { diff --git a/application/Espo/Core/Loaders/PortalAclManagerContainer.php b/application/Espo/Core/Loaders/PortalAclManagerContainer.php index bf77c82f85..01342c1c0b 100644 --- a/application/Espo/Core/Loaders/PortalAclManagerContainer.php +++ b/application/Espo/Core/Loaders/PortalAclManagerContainer.php @@ -30,13 +30,14 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, InjectableFactory, Portal\AclManagerContainer as PortalAclManagerContainerService }; class PortalAclManagerContainer implements Loader { - protected $injectableFactory; + private $injectableFactory; public function __construct(InjectableFactory $injectableFactory) { $this->injectableFactory = $injectableFactory; diff --git a/application/Espo/Core/Loaders/Preferences.php b/application/Espo/Core/Loaders/Preferences.php index d9904c8dbe..df928f6076 100644 --- a/application/Espo/Core/Loaders/Preferences.php +++ b/application/Espo/Core/Loaders/Preferences.php @@ -30,6 +30,7 @@ namespace Espo\Core\Loaders; use Espo\Core\{ + Container\Loader, ORM\EntityManager, ApplicationState, }; @@ -40,8 +41,9 @@ use Espo\Entities\{ class Preferences implements Loader { - protected $entityManager; - protected $applicationState; + private $entityManager; + + private $applicationState; public function __construct(EntityManager $entityManager, ApplicationState $applicationState) { diff --git a/application/Espo/Core/Portal/Application.php b/application/Espo/Core/Portal/Application.php index d250f3a75e..068568b319 100644 --- a/application/Espo/Core/Portal/Application.php +++ b/application/Espo/Core/Portal/Application.php @@ -36,9 +36,9 @@ use Espo\Core\Exceptions\{ }; use Espo\Core\{ - ContainerBuilder, + Container\ContainerBuilder, Portal\Container as PortalContainer, - Portal\ContainerConfiguration as PortalContainerConfiguration, + Portal\Container\ContainerConfiguration as PortalContainerConfiguration, Portal\Utils\Config, Application as BaseApplication, }; diff --git a/application/Espo/Core/Portal/ContainerConfiguration.php b/application/Espo/Core/Portal/Container/ContainerConfiguration.php similarity index 96% rename from application/Espo/Core/Portal/ContainerConfiguration.php rename to application/Espo/Core/Portal/Container/ContainerConfiguration.php index 4316bf9b28..c694c6ea81 100644 --- a/application/Espo/Core/Portal/ContainerConfiguration.php +++ b/application/Espo/Core/Portal/Container/ContainerConfiguration.php @@ -27,10 +27,10 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Portal; +namespace Espo\Core\Portal\Container; use Espo\Core\{ - ContainerConfiguration as BaseContainerConfiguration, + Container\ContainerConfiguration as BaseContainerConfiguration, }; class ContainerConfiguration extends BaseContainerConfiguration diff --git a/application/Espo/Core/Portal/Loaders/Acl.php b/application/Espo/Core/Portal/Loaders/Acl.php index 0f66d747eb..e82de130e9 100644 --- a/application/Espo/Core/Portal/Loaders/Acl.php +++ b/application/Espo/Core/Portal/Loaders/Acl.php @@ -30,8 +30,8 @@ namespace Espo\Core\Portal\Loaders; use Espo\Core\{ + Container\Loader, AclManager, - Loaders\Loader, Portal\Acl as AclService, }; @@ -39,6 +39,10 @@ use Espo\Entities\User; class Acl implements Loader { + private $aclManager; + + private $user; + public function __construct(AclManager $aclManager, User $user) { $this->aclManager = $aclManager; diff --git a/application/Espo/Core/Portal/Loaders/AclManager.php b/application/Espo/Core/Portal/Loaders/AclManager.php index 832a5901b8..b0a25c0361 100644 --- a/application/Espo/Core/Portal/Loaders/AclManager.php +++ b/application/Espo/Core/Portal/Loaders/AclManager.php @@ -30,16 +30,17 @@ namespace Espo\Core\Portal\Loaders; use Espo\Core\{ + Container\Loader, InjectableFactory, AclManager as InternalAclManager, - Loaders\Loader, Portal\AclManager as PortalAclManager, }; class AclManager implements Loader { - protected $injectableFactory; - protected $internalAclManager; + private $injectableFactory; + + private $internalAclManager; public function __construct(InjectableFactory $injectableFactory, InternalAclManager $internalAclManager) { diff --git a/application/Espo/Core/Portal/Loaders/InternalAclManager.php b/application/Espo/Core/Portal/Loaders/InternalAclManager.php index fb6a0fa59f..30ffdf271e 100644 --- a/application/Espo/Core/Portal/Loaders/InternalAclManager.php +++ b/application/Espo/Core/Portal/Loaders/InternalAclManager.php @@ -30,14 +30,14 @@ namespace Espo\Core\Portal\Loaders; use Espo\Core\{ - Loaders\Loader, + Container\Loader, InjectableFactory, AclManager as InternalAclManagerService, }; class InternalAclManager implements Loader { - protected $injectableFactory; + private $injectableFactory; public function __construct(InjectableFactory $injectableFactory) { diff --git a/application/Espo/Core/Portal/Loaders/Language.php b/application/Espo/Core/Portal/Loaders/Language.php index 82dbaffb6e..59347cbbde 100644 --- a/application/Espo/Core/Portal/Loaders/Language.php +++ b/application/Espo/Core/Portal/Loaders/Language.php @@ -30,11 +30,11 @@ namespace Espo\Core\Portal\Loaders; use Espo\Core\{ + Container\Loader, Utils\Metadata, Utils\Config, Utils\File\Manager as FileManager, Portal\Utils\Language as LanguageService, - Loaders\Loader as Loader, Utils\DataCache, }; @@ -45,15 +45,25 @@ use Espo\Entities\{ class Language implements Loader { - protected $fileManager; - protected $config; - protected $metadata; - protected $dataCache; - protected $preferences; - protected $portal; + private $fileManager; + + private $config; + + private $metadata; + + private $dataCache; + + private $preferences; + + private $portal; public function __construct( - FileManager $fileManager, Config $config, Metadata $metadata, DataCache $dataCache, Preferences $preferences, Portal $portal + FileManager $fileManager, + Config $config, + Metadata $metadata, + DataCache $dataCache, + Preferences $preferences, + Portal $portal ) { $this->fileManager = $fileManager; $this->config = $config;