203 Zeilen
5.7 KiB
PHP
203 Zeilen
5.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*
|
|
* https://www.d3data.de
|
|
*
|
|
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
|
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
|
* @link https://www.oxidmodule.com
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace D3\DIContainerHandler;
|
|
|
|
use d3DIContainerCache;
|
|
use Exception;
|
|
use OxidEsales\Eshop\Core\Config;
|
|
use OxidEsales\Eshop\Core\Registry;
|
|
use OxidEsales\Facts\Config\ConfigFile;
|
|
use Symfony\Component\Config\FileLocator;
|
|
use Symfony\Component\DependencyInjection\Container;
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
|
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
|
|
|
class d3DicHandler implements d3DicHandlerInterface
|
|
{
|
|
protected static Container|null $_instance = null;
|
|
|
|
public static array $circularReferenceMethodNames = [
|
|
'getViewConfig',
|
|
];
|
|
|
|
/**
|
|
* @return Container
|
|
* @throws d3DicException
|
|
*/
|
|
public static function getInstance(): Container
|
|
{
|
|
try {
|
|
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
|
$caller = $trace[1];
|
|
$functionName = $caller['function'];
|
|
|
|
if (in_array(strtolower($functionName), array_map('strtolower', self::$circularReferenceMethodNames))) {
|
|
throw oxNew(Exception::class, 'method ' . $functionName . " can't use DIC due the danger of circular reference");
|
|
}
|
|
|
|
if (null == self::$_instance) {
|
|
$oDicHandler = oxNew(d3DicHandler::class);
|
|
self::$_instance = $oDicHandler->buildContainer();
|
|
}
|
|
} catch (Exception $exception) {
|
|
throw new d3DicException($exception);
|
|
}
|
|
|
|
return self::$_instance;
|
|
}
|
|
|
|
/**
|
|
* get instance
|
|
* @throws d3DicException
|
|
*/
|
|
public static function getUncompiledInstance(): Container
|
|
{
|
|
try {
|
|
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
|
$caller = $trace[1];
|
|
$functionName = $caller['function'];
|
|
|
|
if (in_array(strtolower($functionName), array_map('strtolower', self::$circularReferenceMethodNames))) {
|
|
throw oxNew(Exception::class, 'method '.$functionName." can't use DIC due the danger of circular reference");
|
|
}
|
|
|
|
$oDicHandler = oxNew(d3DicHandler::class);
|
|
self::$_instance = $oDicHandler->buildContainer(false);
|
|
} catch (Exception $exception) {
|
|
throw new d3DicException($exception);
|
|
}
|
|
|
|
return self::$_instance;
|
|
}
|
|
|
|
public static function removeInstance(): void
|
|
{
|
|
self::$_instance = null;
|
|
}
|
|
|
|
public function d3GetConfig(): Config
|
|
{
|
|
return Registry::getConfig();
|
|
}
|
|
|
|
public function d3GetCacheFilePath(): string
|
|
{
|
|
return $this->d3GetConfig()->getConfigParam('sCompileDir').'/d3DicContainer_'.Registry::getConfig()->getShopId().'.php';
|
|
}
|
|
|
|
public function d3GetCacheContainer(): Container
|
|
{
|
|
require_once $this->d3GetCacheFilePath();
|
|
return oxNew(d3DIContainerCache::class);
|
|
}
|
|
|
|
public function d3GetFileLoader(ContainerBuilder $container): YamlFileLoader
|
|
{
|
|
/** @var YamlFileLoader $fileLoader */
|
|
$fileLoader = oxNew(
|
|
YamlFileLoader::class,
|
|
$container,
|
|
oxNew(FileLocator::class, d3DicUtilities::getVendorDir())
|
|
);
|
|
|
|
return $fileLoader;
|
|
}
|
|
|
|
/**
|
|
* @param ContainerBuilder $container
|
|
* @return void
|
|
* @throws Exception
|
|
*/
|
|
public function loadFiles(ContainerBuilder $container): void
|
|
{
|
|
$loader = $this->d3GetFileLoader($container);
|
|
|
|
$fileContainer = oxNew(definitionFileContainer::class);
|
|
foreach ($fileContainer->getYamlDefinitions() as $file) {
|
|
$fullPath = d3DicUtilities::getVendorDir().$file;
|
|
if (is_file($fullPath)) {
|
|
$loader->load($file);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function isNotInTest(): bool
|
|
{
|
|
return false == defined('OXID_PHP_UNIT') || true == defined('D3_MODCFG_TEST');
|
|
}
|
|
|
|
protected function cacheFileExists(): bool
|
|
{
|
|
return file_exists($this->d3GetCacheFilePath());
|
|
}
|
|
|
|
/**
|
|
* @param bool $compileAndDump
|
|
* @return Container
|
|
* @throws Exception
|
|
*/
|
|
public function buildContainer(bool $compileAndDump = true): Container
|
|
{
|
|
startProfile(__METHOD__);
|
|
|
|
if ($this->d3UseCachedContainer()) {
|
|
$container = $this->d3GetCacheContainer();
|
|
} else {
|
|
$container = $this->getContainerBuilder();
|
|
$this->loadFiles($container);
|
|
|
|
if ($compileAndDump) {
|
|
$container->compile();
|
|
|
|
if ($this->isNotInTest()) {
|
|
$dumper = new PhpDumper($container);
|
|
file_put_contents($this->d3GetCacheFilePath(), $dumper->dump(['class' => 'd3DIContainerCache']));
|
|
}
|
|
}
|
|
}
|
|
|
|
stopProfile(__METHOD__);
|
|
|
|
return $container;
|
|
}
|
|
|
|
protected function d3UseCachedContainer(): bool
|
|
{
|
|
$config = $this->d3GetConfig();
|
|
|
|
return $config->isProductiveMode()
|
|
&& !$config->getConfigParam('iDebug')
|
|
&& $this->isNotInTest()
|
|
&& $this->cacheFileExists();
|
|
}
|
|
|
|
public function getContainerBuilder(): ContainerBuilder
|
|
{
|
|
return oxNew(ContainerBuilder::class);
|
|
}
|
|
|
|
public function __clone()
|
|
{
|
|
/** keep clear */
|
|
}
|
|
|
|
public function __construct()
|
|
{
|
|
/** keep clear */
|
|
}
|
|
}
|