. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ namespace Espo\Core\Container; use Espo\Core\Application\ApplicationParams; use Espo\Core\Container; use Espo\Core\Container\Container as ContainerInterface; use Espo\Core\Binding\BindingContainer; use Espo\Core\Binding\BindingLoader; use Espo\Core\Binding\EspoBindingLoader; use Espo\Core\Loaders\ApplicationState as ApplicationStateLoader; use Espo\Core\Utils\File\Manager as FileManager; use Espo\Core\Utils\Config\ConfigFileManager; use Espo\Core\Utils\Config; use Espo\Core\Utils\DataCache; use Espo\Core\Utils\Module; use Espo\Core\Loaders\Log as LogLoader; use Espo\Core\Loaders\DataManager as DataManagerLoader; use Espo\Core\Loaders\Metadata as MetadataLoader; /** * Builds a service container. */ class ContainerBuilder { /** @var class-string */ private string $containerClassName = Container::class; /** @var class-string */ private string $containerConfigurationClassName = ContainerConfiguration::class; /** @var class-string */ private string $configClassName = Config::class; /** @var class-string */ private string $fileManagerClassName = FileManager::class; /** @var class-string */ private string $dataCacheClassName = DataCache::class; /** @var class-string */ private string $moduleClassName = Module::class; private ?BindingLoader $bindingLoader = null; /** @var array */ private $services = []; /** @var array> */ protected $loaderClassNames = [ 'log' => LogLoader::class, 'dataManager' => DataManagerLoader::class, 'metadata' => MetadataLoader::class, 'applicationState' => ApplicationStateLoader::class, ]; private ?ApplicationParams $params = null; public function withParams(?ApplicationParams $params): self { $this->params = $params; return $this; } public function withBindingLoader(BindingLoader $bindingLoader): self { $this->bindingLoader = $bindingLoader; return $this; } /** * @param array $services */ public function withServices(array $services): self { foreach ($services as $key => $value) { $this->services[$key] = $value; } return $this; } /** * @param array> $classNames * @noinspection PhpUnused */ public function withLoaderClassNames(array $classNames): self { foreach ($classNames as $key => $value) { $this->loaderClassNames[$key] = $value; } return $this; } /** * @param class-string $containerClassName */ public function withContainerClassName(string $containerClassName): self { $this->containerClassName = $containerClassName; return $this; } /** * @param class-string $containerConfigurationClassName */ public function withContainerConfigurationClassName(string $containerConfigurationClassName): self { $this->containerConfigurationClassName = $containerConfigurationClassName; return $this; } /** * @param class-string $configClassName */ public function withConfigClassName(string $configClassName): self { $this->configClassName = $configClassName; return $this; } /** * @param class-string $fileManagerClassName * @noinspection PhpUnused */ public function withFileManagerClassName(string $fileManagerClassName): self { $this->fileManagerClassName = $fileManagerClassName; return $this; } /** * @param class-string $dataCacheClassName * @noinspection PhpUnused */ public function withDataCacheClassName(string $dataCacheClassName): self { $this->dataCacheClassName = $dataCacheClassName; return $this; } public function build(): ContainerInterface { $this->services['applicationParams'] = $this->params ?? new ApplicationParams(); /** @var Config $config */ $config = $this->services['config'] ?? ( new $this->configClassName( new ConfigFileManager() ) ); /** @var FileManager $fileManager */ $fileManager = $this->services['fileManager'] ?? ( new $this->fileManagerClassName( $config->get('defaultPermissions') ) ); /** @var DataCache $dataCache */ $dataCache = $this->services['dataCache'] ?? ( new $this->dataCacheClassName($fileManager) ); $useCache = $config->get('useCache') ?? false; /** @var Module $module */ $module = $this->services['module'] ?? ( new $this->moduleClassName($fileManager, $dataCache, $useCache) ); $systemConfig = new Config\SystemConfig($config); $this->services['config'] = $config; $this->services['fileManager'] = $fileManager; $this->services['dataCache'] = $dataCache; $this->services['module'] = $module; $this->services['systemConfig'] = $systemConfig; $bindingLoader = $this->bindingLoader ?? ( new EspoBindingLoader( module: $module, binding: $this->params?->binding, ) ); $bindingContainer = new BindingContainer($bindingLoader->load()); return new $this->containerClassName( $this->containerConfigurationClassName, $bindingContainer, $this->loaderClassNames, $this->services ); } }