diff --git a/config.example.php b/config.example.php
index 556f639..3cca2b6 100644
--- a/config.example.php
+++ b/config.example.php
@@ -14,6 +14,8 @@
'environment' => [
// site debugging (set false in production)
'displayErrorDetails' => false,
+ // site debugging (set false in production)
+ 'debug' => true,
// site profiling (benchmarking)
// profiling is consume high memory footprints (set false in production)
'profiling' => false,
@@ -60,7 +62,7 @@
// dev mode for development environment without cache (set false in production)
'devMode' => false,
// proxy entities directory
- 'proxyDir' => __DIR__ . '/storage/database/proxy',
+ 'proxyDirectory' => __DIR__ . '/storage/database/proxy',
// additional doctrine config
'options' => [
],
diff --git a/src/Bin.php b/src/Bin.php
index e0ea8b1..8183134 100644
--- a/src/Bin.php
+++ b/src/Bin.php
@@ -4,7 +4,7 @@
namespace ArrayAccess\TrayDigita;
use ArrayAccess\TrayDigita\Console\Application;
-use ArrayAccess\TrayDigita\Container\Container;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Http\Exceptions\HttpException;
use ArrayAccess\TrayDigita\Http\ServerRequest;
use ArrayAccess\TrayDigita\Kernel\Decorator;
@@ -45,7 +45,6 @@ final private function __construct()
/**
* @noinspection PhpMissingReturnTypeInspection
* @noinspection PhpIssetCanBeReplacedWithCoalesceInspection
- * @noinspection DuplicatedCode
* @throws Throwable
*/
final public static function run()
@@ -106,22 +105,22 @@ final public static function run()
chdir($root);
# TD_APP_DIRECTORY='app' php bin/console
if (!defined('TD_APP_DIRECTORY')) {
- $appDir = getenv('TD_APP_DIRECTORY')?: null;
- if ($appDir && is_string($appDir)) {
- $appDir = realpath($appDir) ?: (
- realpath($cwd . DIRECTORY_SEPARATOR . $appDir) ?: (
- realpath(TD_ROOT_COMPOSER_DIR . DIRECTORY_SEPARATOR . $appDir) ?: null
+ $appDirectory = getenv('TD_APP_DIRECTORY')?: null;
+ if ($appDirectory && is_string($appDirectory)) {
+ $appDirectory = realpath($appDirectory) ?: (
+ realpath($cwd . DIRECTORY_SEPARATOR . $appDirectory) ?: (
+ realpath(TD_ROOT_COMPOSER_DIR . DIRECTORY_SEPARATOR . $appDirectory) ?: null
)
);
}
- $appDir = isset($appDir) ? $appDir : TD_ROOT_COMPOSER_DIR . DIRECTORY_SEPARATOR . 'app';
- /*if (!is_dir($appDir)) {
+ $appDirectory = isset($appDirectory) ? $appDirectory : TD_ROOT_COMPOSER_DIR . DIRECTORY_SEPARATOR . 'app';
+ /*if (!is_dir($appDirectory)) {
echo "\n\033[0;31mCould not detect application directory\033[0m\n";
echo "\n";
exit(255);
}*/
- define('TD_APP_DIRECTORY', $appDir);
+ define('TD_APP_DIRECTORY', $appDirectory);
} elseif (!is_string(TD_APP_DIRECTORY)) {
echo "\n\033[0;31mConstant \033[0;0m`TD_APP_DIRECTORY`\033[0;31m is invalid\033[0m\n";
echo "\n";
@@ -158,7 +157,7 @@ final public static function run()
$kernel->boot();
/**
- * @var Container $container
+ * @var SystemContainerInterface $container
*/
$container = $kernel->getContainer();
$manager = $kernel->getManager();
diff --git a/src/ComposerCreateProject.php b/src/ComposerCreateProject.php
index d275bbb..c836713 100644
--- a/src/ComposerCreateProject.php
+++ b/src/ComposerCreateProject.php
@@ -64,36 +64,36 @@ public static function composerDoCreateProject($event)
return;
}
- $installDir = getcwd();
+ $installDirectory = getcwd();
///*
// $package = $event->getComposer()->getPackage();
// $event->getComposer()->getInstallationManager()->getInstallPath($package);
$prefixUnix = DIRECTORY_SEPARATOR === '/'
? "#!/usr/bin/env php\n"
: '';
- $vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
+ $vendorDirectory = $event->getComposer()->getConfig()->get('vendor-dir');
$consoleIO->write(
- sprintf('Install Directory [%s]', $installDir),
+ sprintf('Install Directory [%s]', $installDirectory),
true,
$consoleIO::VERY_VERBOSE
);
$consoleIO->write(
- sprintf('Vendor Directory [%s]', $vendorDir),
+ sprintf('Vendor Directory [%s]', $vendorDirectory),
true,
$consoleIO::VERY_VERBOSE
);
- if (!$vendorDir) {
+ if (!$vendorDirectory) {
return;
}
- $vendorDir = rtrim($vendorDir, '\\/');
- $installDir = realpath($installDir)?:$installDir;
- $installDir = rtrim($installDir, '\\/');
- $vendorDir = str_replace('\\', '/', $vendorDir);
- $installDir = str_replace('\\', '/', $installDir);
- if (!str_starts_with($vendorDir, $installDir . '/')) {
+ $vendorDirectory = rtrim($vendorDirectory, '\\/');
+ $installDirectory = realpath($installDirectory)?:$installDirectory;
+ $installDirectory = rtrim($installDirectory, '\\/');
+ $vendorDirectory = str_replace('\\', '/', $vendorDirectory);
+ $installDirectory = str_replace('\\', '/', $installDirectory);
+ if (!str_starts_with($vendorDirectory, $installDirectory . '/')) {
return;
}
- $vendor = substr($vendorDir, strlen($installDir) + 1);
+ $vendor = substr($vendorDirectory, strlen($installDirectory) + 1);
$vendor = addcslashes($vendor, "'");
$createFiles = [
'data/README.md' => <<write('Preparing to create application structures');
- if (!file_exists($installDir . DIRECTORY_SEPARATOR . 'config.php')) {
- if (!is_dir($installDir)) {
- mkdir($installDir, 0755, true);
+ if (!file_exists($installDirectory . DIRECTORY_SEPARATOR . 'config.php')) {
+ if (!is_dir($installDirectory)) {
+ mkdir($installDirectory, 0755, true);
}
$configFile = file_get_contents(dirname(__DIR__) .'/config.example.php');
$configFile = str_replace(
@@ -370,15 +370,15 @@ public static function composerDoCreateProject($event)
$consoleIO->write(
sprintf(
'[GENERATING CONFIG] %s',
- $installDir . '/config.php'
+ $installDirectory . '/config.php'
),
true,
$consoleIO::VERBOSE
);
- file_put_contents($installDir . '/config.php', $configFile);
+ file_put_contents($installDirectory . '/config.php', $configFile);
}
foreach ($createFiles as $pathName => $content) {
- $path = $installDir . DIRECTORY_SEPARATOR . $pathName;
+ $path = $installDirectory . DIRECTORY_SEPARATOR . $pathName;
$isConsole = $pathName === 'bin/tray-digita';
if (file_exists($path)) {
if (!$isConsole || is_link($path)) {
@@ -418,7 +418,7 @@ public static function composerDoCreateProject($event)
chmod($path, 0744);
}
}
- $langDir = $installDir . '/app/Languages';
+ $langDirectory = $installDirectory . '/app/Languages';
$consoleIO->write(
'Copying language files',
true,
@@ -436,10 +436,10 @@ public static function composerDoCreateProject($event)
continue;
}
$baseName = $directory->getBasename();
- if (file_exists($langDir . DIRECTORY_SEPARATOR . $baseName)) {
+ if (file_exists($langDirectory . DIRECTORY_SEPARATOR . $baseName)) {
continue;
}
- copy($directory->getRealPath(), $langDir . DIRECTORY_SEPARATOR . $baseName);
+ copy($directory->getRealPath(), $langDirectory . DIRECTORY_SEPARATOR . $baseName);
}
$consoleIO->write(
'Done',
diff --git a/src/Console/Command/ApplicationChecker/ContainerChecker.php b/src/Console/Command/ApplicationChecker/ContainerChecker.php
index 56844ca..e62cd74 100644
--- a/src/Console/Command/ApplicationChecker/ContainerChecker.php
+++ b/src/Console/Command/ApplicationChecker/ContainerChecker.php
@@ -4,7 +4,7 @@
namespace ArrayAccess\TrayDigita\Console\Command\ApplicationChecker;
use ArrayAccess\TrayDigita\Console\Command\Traits\WriterHelperTrait;
-use ArrayAccess\TrayDigita\Container\Container;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -36,7 +36,7 @@ public function check(InputInterface $input, OutputInterface $output) : int
true
);
if ($output->isVerbose()) {
- if ($container instanceof Container) {
+ if ($container instanceof SystemContainerInterface) {
$output->writeln('', OutputInterface::VERBOSITY_VERY_VERBOSE);
$this->writeIndent(
$output,
diff --git a/src/Console/Command/CommandGenerator.php b/src/Console/Command/CommandGenerator.php
index 07077dd..b031630 100644
--- a/src/Console/Command/CommandGenerator.php
+++ b/src/Console/Command/CommandGenerator.php
@@ -49,7 +49,7 @@ class CommandGenerator extends Command implements ContainerAllocatorInterface, M
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $commandDir = null;
+ private ?string $commandDirectory = null;
private string $commandNamespace;
protected function configure() : void
@@ -60,7 +60,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->commandNamespace = $kernel->getCommandNameSpace();
- $this->commandDir = $kernel->getRegisteredDirectories()[$this->commandNamespace]??null;
+ $this->commandDirectory = $kernel->getRegisteredDirectories()[$this->commandNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -140,7 +140,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->commandList === null) {
$this->commandList = [];
- $commandDirectory = $this->commandDir;
+ $commandDirectory = $this->commandDirectory;
$lengthStart = strlen($commandDirectory) + 1;
foreach (Finder::create()
->in($commandDirectory)
@@ -241,17 +241,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->commandDir) {
+ if (!$this->commandDirectory) {
$config = ContainerHelper::getNull(Config::class, $container) ?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $commandDir = $path?->get('command');
- if (is_string($commandDir) && is_dir($commandDir)) {
- $this->commandDir = realpath($commandDir) ?? $commandDir;
+ $commandDirectory = $path?->get('command');
+ if (is_string($commandDirectory) && is_dir($commandDirectory)) {
+ $this->commandDirectory = realpath($commandDirectory) ?? $commandDirectory;
}
}
- if (!$this->commandDir) {
+ if (!$this->commandDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -278,7 +278,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->commandDir
+ $fileName = $this->commandDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. '.php';
diff --git a/src/Console/Command/ControllerGenerator.php b/src/Console/Command/ControllerGenerator.php
index 805974f..ba2adc3 100644
--- a/src/Console/Command/ControllerGenerator.php
+++ b/src/Console/Command/ControllerGenerator.php
@@ -49,7 +49,7 @@ class ControllerGenerator extends Command implements ContainerAllocatorInterface
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $controllerDir = null;
+ private ?string $controllerDirectory = null;
private string $controllerNameSpace;
@@ -61,7 +61,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->controllerNameSpace = $kernel->getControllerNameSpace();
- $this->controllerDir = $kernel->getRegisteredDirectories()[$this->controllerNameSpace]??null;
+ $this->controllerDirectory = $kernel->getRegisteredDirectories()[$this->controllerNameSpace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -131,7 +131,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->controllerList === null) {
$this->controllerList = [];
- $controllerDirectory = $this->controllerDir;
+ $controllerDirectory = $this->controllerDirectory;
$lengthStart = strlen($controllerDirectory) + 1;
foreach (Finder::create()
->in($controllerDirectory)
@@ -211,17 +211,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->controllerDir) {
+ if (!$this->controllerDirectory) {
$config = ContainerHelper::getNull(Config::class, $container) ?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $controllerDir = $path?->get('controller');
- if (is_string($controllerDir) && is_dir($controllerDir)) {
- $this->controllerDir = realpath($controllerDir) ?? $controllerDir;
+ $controllerDirectory = $path?->get('controller');
+ if (is_string($controllerDirectory) && is_dir($controllerDirectory)) {
+ $this->controllerDirectory = realpath($controllerDirectory) ?? $controllerDirectory;
}
}
- if (!$this->controllerDir) {
+ if (!$this->controllerDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -248,7 +248,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->controllerDir
+ $fileName = $this->controllerDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $name)
. '.php';
diff --git a/src/Console/Command/DatabaseEventGenerator.php b/src/Console/Command/DatabaseEventGenerator.php
index 3e13348..2ac1330 100644
--- a/src/Console/Command/DatabaseEventGenerator.php
+++ b/src/Console/Command/DatabaseEventGenerator.php
@@ -49,7 +49,7 @@ class DatabaseEventGenerator extends Command implements ContainerAllocatorInterf
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $databaseEventDir = null;
+ private ?string $databaseEventDirectory = null;
private string $databaseEventNamespace;
protected function configure() : void
@@ -60,7 +60,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->databaseEventNamespace = $kernel->getDatabaseEventNameSpace();
- $this->databaseEventDir = $kernel->getRegisteredDirectories()[$this->databaseEventNamespace]??null;
+ $this->databaseEventDirectory = $kernel->getRegisteredDirectories()[$this->databaseEventNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -143,7 +143,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->databaseEventList === null) {
$this->databaseEventList = [];
- $databaseEventDirectory = $this->databaseEventDir;
+ $databaseEventDirectory = $this->databaseEventDirectory;
$lengthStart = strlen($databaseEventDirectory) + 1;
foreach (Finder::create()
->in($databaseEventDirectory)
@@ -244,12 +244,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$config = ContainerHelper::use(Config::class, $container)??new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $databaseEventDir = $path?->get('databaseEvent');
- if (is_string($databaseEventDir) && is_dir($databaseEventDir)) {
- $this->databaseEventDir = realpath($databaseEventDir)??$databaseEventDir;
+ $databaseEventDirectory = $path?->get('databaseEvent');
+ if (is_string($databaseEventDirectory) && is_dir($databaseEventDirectory)) {
+ $this->databaseEventDirectory = realpath($databaseEventDirectory)??$databaseEventDirectory;
}
- if (!$this->databaseEventDir) {
+ if (!$this->databaseEventDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -276,7 +276,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->databaseEventDir
+ $fileName = $this->databaseEventDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. '.php';
diff --git a/src/Console/Command/EntityGenerator.php b/src/Console/Command/EntityGenerator.php
index 2fcead5..e2611b6 100644
--- a/src/Console/Command/EntityGenerator.php
+++ b/src/Console/Command/EntityGenerator.php
@@ -49,7 +49,7 @@ class EntityGenerator extends Command implements ContainerAllocatorInterface, Ma
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $entityDir = null;
+ private ?string $entityDirectory = null;
private string $entityNamespace;
protected function configure() : void
@@ -60,7 +60,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->entityNamespace = $kernel->getEntityNamespace();
- $this->entityDir = $kernel->getRegisteredDirectories()[$this->entityNamespace]??null;
+ $this->entityDirectory = $kernel->getRegisteredDirectories()[$this->entityNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -138,10 +138,10 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->entityLists === null) {
$this->entityLists = [];
- $entityDir = $this->entityDir;
- $lengthStart = strlen($entityDir) + 1;
+ $entityDirectory = $this->entityDirectory;
+ $lengthStart = strlen($entityDirectory) + 1;
foreach (Finder::create()
- ->in($entityDir)
+ ->in($entityDirectory)
->ignoreVCS(true)
->ignoreDotFiles(true)
// depth <= 10
@@ -225,16 +225,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->entityDir) {
+ if (!$this->entityDirectory) {
$config = ContainerHelper::use(Config::class, $container) ?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $entityDir = $path?->get('entity');
- if (is_string($entityDir) && is_dir($entityDir)) {
- $this->entityDir = realpath($entityDir) ?? $entityDir;
+ $entityDirectory = $path?->get('entity');
+ if (is_string($entityDirectory) && is_dir($entityDirectory)) {
+ $this->entityDirectory = realpath($entityDirectory) ?? $entityDirectory;
}
}
- if (!$this->entityDir) {
+ if (!$this->entityDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -261,7 +261,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->entityDir
+ $fileName = $this->entityDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. '.php';
diff --git a/src/Console/Command/MiddlewareGenerator.php b/src/Console/Command/MiddlewareGenerator.php
index ceadde0..ce2bcf5 100644
--- a/src/Console/Command/MiddlewareGenerator.php
+++ b/src/Console/Command/MiddlewareGenerator.php
@@ -49,7 +49,7 @@ class MiddlewareGenerator extends Command implements ContainerAllocatorInterface
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $middlewareDir = null;
+ private ?string $middlewareDirectory = null;
private string $middlewareNamespace;
@@ -61,7 +61,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->middlewareNamespace = $kernel->getMiddlewareNamespace();
- $this->middlewareDir = $kernel->getRegisteredDirectories()[$this->middlewareNamespace]??null;
+ $this->middlewareDirectory = $kernel->getRegisteredDirectories()[$this->middlewareNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -139,7 +139,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->middlewareList === null) {
$this->middlewareList = [];
- $middlewareDirectory = $this->middlewareDir;
+ $middlewareDirectory = $this->middlewareDirectory;
$lengthStart = strlen($middlewareDirectory) + 1;
foreach (Finder::create()
->in($middlewareDirectory)
@@ -235,17 +235,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->middlewareDir) {
+ if (!$this->middlewareDirectory) {
$config = ContainerHelper::use(Config::class, $container) ?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $middlewareDir = $path?->get('middleware');
- if (is_string($middlewareDir) && is_dir($middlewareDir)) {
- $this->middlewareDir = realpath($middlewareDir) ?? $middlewareDir;
+ $middlewareDirectory = $path?->get('middleware');
+ if (is_string($middlewareDirectory) && is_dir($middlewareDirectory)) {
+ $this->middlewareDirectory = realpath($middlewareDirectory) ?? $middlewareDirectory;
}
}
- if (!$this->middlewareDir) {
+ if (!$this->middlewareDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -272,7 +272,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->middlewareDir
+ $fileName = $this->middlewareDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. '.php';
diff --git a/src/Console/Command/ModuleGenerator.php b/src/Console/Command/ModuleGenerator.php
index c01d96c..a4b03e8 100644
--- a/src/Console/Command/ModuleGenerator.php
+++ b/src/Console/Command/ModuleGenerator.php
@@ -49,7 +49,7 @@ class ModuleGenerator extends Command implements ContainerAllocatorInterface, Ma
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $moduleDir = null;
+ private ?string $moduleDirectory = null;
private string $moduleNamespace;
protected function configure() : void
@@ -60,7 +60,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->moduleNamespace = $kernel->getControllerNameSpace();
- $this->moduleDir = $kernel->getRegisteredDirectories()[$this->moduleNamespace]??null;
+ $this->moduleDirectory = $kernel->getRegisteredDirectories()[$this->moduleNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -139,7 +139,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->moduleList === null) {
$this->moduleList = [];
- $moduleDirectory = $this->moduleDir;
+ $moduleDirectory = $this->moduleDirectory;
$lengthStart = strlen($moduleDirectory) + 1;
foreach (Finder::create()
->in($moduleDirectory)
@@ -240,17 +240,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->moduleDir) {
+ if (!$this->moduleDirectory) {
$config = ContainerHelper::use(Config::class, $container) ?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $moduleDir = $path?->get('module');
- if (is_string($moduleDir) && is_dir($moduleDir)) {
- $this->moduleDir = realpath($moduleDir) ?? $moduleDir;
+ $moduleDirectory = $path?->get('module');
+ if (is_string($moduleDirectory) && is_dir($moduleDirectory)) {
+ $this->moduleDirectory = realpath($moduleDirectory) ?? $moduleDirectory;
}
}
- if (!$this->moduleDir) {
+ if (!$this->moduleDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -277,7 +277,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->moduleDir
+ $fileName = $this->moduleDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. DIRECTORY_SEPARATOR
diff --git a/src/Console/Command/SchedulerGenerator.php b/src/Console/Command/SchedulerGenerator.php
index a781c11..8f2158c 100644
--- a/src/Console/Command/SchedulerGenerator.php
+++ b/src/Console/Command/SchedulerGenerator.php
@@ -49,7 +49,7 @@ class SchedulerGenerator extends Command implements ContainerAllocatorInterface,
ManagerAllocatorTrait,
TranslatorTrait;
- private ?string $schedulerDir = null;
+ private ?string $schedulerDirectory = null;
private string $schedulerNamespace;
@@ -61,7 +61,7 @@ protected function configure() : void
);
if ($kernel instanceof BaseKernel) {
$this->schedulerNamespace = $kernel->getSchedulerNamespace();
- $this->schedulerDir = $kernel->getRegisteredDirectories()[$this->schedulerNamespace]??null;
+ $this->schedulerDirectory = $kernel->getRegisteredDirectories()[$this->schedulerNamespace]??null;
} else {
$namespace = dirname(
str_replace(
@@ -141,7 +141,7 @@ private function isFileExists(string $className) : bool
$lowerClassName = strtolower($className);
if ($this->schedulerList === null) {
$this->schedulerList = [];
- $schedulerDirectory = $this->schedulerDir;
+ $schedulerDirectory = $this->schedulerDirectory;
$lengthStart = strlen($schedulerDirectory) + 1;
foreach (Finder::create()
->in($schedulerDirectory)
@@ -245,18 +245,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$input->setInteractive(true);
$container = $this->getContainer();
- if (!$this->schedulerDir) {
+ if (!$this->schedulerDirectory) {
$config = ContainerHelper::use(Config::class, $container)
?? new Config();
$path = $config->get('path');
$path = $path instanceof Config ? $path : null;
- $schedulerDir = $path?->get('scheduler');
- if (is_string($schedulerDir) && is_dir($schedulerDir)) {
- $this->schedulerDir = realpath($schedulerDir) ?? $schedulerDir;
+ $schedulerDirectory = $path?->get('scheduler');
+ if (is_string($schedulerDirectory) && is_dir($schedulerDirectory)) {
+ $this->schedulerDirectory = realpath($schedulerDirectory) ?? $schedulerDirectory;
}
}
- if (!$this->schedulerDir) {
+ if (!$this->schedulerDirectory) {
$output->writeln(
sprintf(
$this->translateContext(
@@ -283,7 +283,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return self::FAILURE;
}
- $fileName = $this->schedulerDir
+ $fileName = $this->schedulerDirectory
. DIRECTORY_SEPARATOR
. str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $named['className'])
. '.php';
diff --git a/src/Container/Container.php b/src/Container/Container.php
index 7aeaa2e..9123b1a 100644
--- a/src/Container/Container.php
+++ b/src/Container/Container.php
@@ -3,16 +3,14 @@
namespace ArrayAccess\TrayDigita\Container;
-use ArrayAccess;
use ArrayAccess\TrayDigita\Container\Exceptions\ContainerFrozenException;
use ArrayAccess\TrayDigita\Container\Exceptions\ContainerNotFoundException;
-use ArrayAccess\TrayDigita\Container\Interfaces\UnInvokableInterface;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Container\Traits\ContainerDecorator;
use ArrayAccess\TrayDigita\Exceptions\Logical\InvokeAbleException;
use ArrayAccess\TrayDigita\Traits\Service\CallStackTraceTrait;
use ArrayAccess\TrayDigita\Util\Filter\Consolidation;
use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\ContainerInterface;
use SensitiveParameter;
use Throwable;
use function array_key_exists;
@@ -23,7 +21,7 @@
/**
* @template T of object
*/
-class Container implements ContainerInterface, ArrayAccess, UnInvokableInterface
+class Container implements SystemContainerInterface
{
use CallStackTraceTrait,
ContainerDecorator;
@@ -235,6 +233,7 @@ public function getFrozenServices(): array
*/
public function get(string $id)
{
+ /** @noinspection DuplicatedCode */
if ($this->hasRawService($id)) {
$this->frozenServices[$id] ??= true;
return $this->getRawService($id);
@@ -259,7 +258,6 @@ public function get(string $id)
$this->assertCallstack();
$value = $this->getResolver()->resolve($id);
$this->removeQueuedService($id);
-
// call
$this->raw($id, $value);
$this->frozenServices[$id] = true;
diff --git a/src/Container/ContainerResolver.php b/src/Container/ContainerResolver.php
index fb89816..638785d 100644
--- a/src/Container/ContainerResolver.php
+++ b/src/Container/ContainerResolver.php
@@ -6,6 +6,7 @@
use ArrayAccess\TrayDigita\Container\Exceptions\ContainerNotFoundException;
use ArrayAccess\TrayDigita\Container\Interfaces\ContainerAllocatorInterface;
use ArrayAccess\TrayDigita\Container\Interfaces\ContainerIndicateInterface;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Container\Interfaces\UnInvokableInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerAllocatorInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
@@ -172,7 +173,7 @@ public function allocateService($containerValue) : void
public function resolve(string $id): mixed
{
$container = $this->getContainer();
- if (!$container instanceof Container || !$container->hasQueuedService($id)) {
+ if (!$container instanceof SystemContainerInterface || !$container->hasQueuedService($id)) {
throw new ContainerNotFoundException(
sprintf('Queued container service %s has not found.', $id)
);
@@ -204,8 +205,14 @@ private function resolveTheArgumentObjectBuiltin(
return null;
}
if ($type->isBuiltin()) {
+ $builtin = [
+ 'bool' => 'boolean',
+ 'float' => 'double',
+ ];
$argType = gettype($argumentValue);
- $found = $argType === $type->getName();
+ $argType = $builtin[$argType]??$argType;
+ $argName = $builtin[$type->getName()]??$type->getName();
+ $found = $argType === $argName;
return $found ? $argumentValue : null;
}
if (is_object($argumentValue) && is_a($argumentValue, $type->getName())) {
@@ -291,7 +298,6 @@ private function resolveInternalArgument(
}
return;
}
-
if (!$refType instanceof ReflectionNamedType) {
return;
}
@@ -323,7 +329,9 @@ private function resolveInternalArgument(
}
}
- if ($refName === ContainerInterface::class || is_a($refName, $this->container::class)) {
+ if ($refName === ContainerInterface::class
+ || $refName === SystemContainerInterface::class
+ || is_a($refName, $this->container::class)) {
$paramFound = true;
if ($this->container->has($refName)) {
try {
diff --git a/src/Container/ContainerWrapper.php b/src/Container/ContainerWrapper.php
index 19502a2..b0c9aaf 100644
--- a/src/Container/ContainerWrapper.php
+++ b/src/Container/ContainerWrapper.php
@@ -3,52 +3,152 @@
namespace ArrayAccess\TrayDigita\Container;
-use ArrayAccess;
-use ArrayAccess\TrayDigita\Container\Interfaces\UnInvokableInterface;
+use ArrayAccess\TrayDigita\Container\Exceptions\ContainerFrozenException;
+use ArrayAccess\TrayDigita\Container\Exceptions\ContainerNotFoundException;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Container\Traits\ContainerDecorator;
use ArrayAccess\TrayDigita\Exceptions\Logical\InvokeAbleException;
+use ArrayAccess\TrayDigita\Traits\Service\CallStackTraceTrait;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
+use SensitiveParameter;
use Throwable;
+use function array_key_exists;
+use function array_keys;
+use function array_merge;
use function method_exists;
use function sprintf;
-class ContainerWrapper implements ContainerInterface, ArrayAccess, UnInvokableInterface
+final class ContainerWrapper implements SystemContainerInterface
{
- private ContainerInterface $container;
+ use ContainerDecorator,
+ CallStackTraceTrait;
- use ContainerDecorator;
+ private ContainerInterface|SystemContainerInterface $container;
- private ?ContainerResolver $resolver;
+ private ?ContainerResolver $resolver = null;
+
+ /**
+ * @var array
+ */
+ private array $aliases = [];
+
+ private array $queuedServices = [];
+
+ private array $arguments = [];
+
+ private array $parameters = [];
+
+ private array $rawServices = [];
+
+ private array $frozenServices = [];
public function __construct(ContainerInterface $container)
{
$this->container = $container;
- if ($container instanceof Container) {
- $this->resolver = $container->getResolver();
- } else {
- $this->resolver = new ContainerResolver($container);
+ if (!$container instanceof SystemContainerInterface) {
+ $this->resolver = new ContainerResolver($this);
+ }
+ }
+
+ /**
+ * @param string $id
+ * @return void
+ * @throws ContainerFrozenException
+ */
+ private function assertFrozen(string $id): void
+ {
+ if ($this->isFrozen($id)) {
+ throw new ContainerFrozenException(
+ sprintf('Container %s has frozen', $id)
+ );
}
}
- public static function createFromContainer(ContainerInterface $container) : static
+ public function getContainer(): ContainerInterface
{
- return new static($container);
+ return $this->container;
}
- public static function maybeContainerOrCreate(ContainerInterface $container) : static|ContainerWrapper|Container
+ public static function createFromContainer(ContainerInterface $container) : ContainerWrapper
{
- if ($container instanceof ContainerWrapper || $container instanceof Container) {
+ return new ContainerWrapper($container);
+ }
+
+ public static function maybeContainerOrCreate(
+ ContainerInterface $container
+ ) : SystemContainerInterface {
+ if ($container instanceof ContainerWrapper) {
+ $theContainer = $container->getContainer();
+ if ($theContainer instanceof SystemContainerInterface) {
+ return $theContainer;
+ }
+ }
+
+ if ($container instanceof SystemContainerInterface) {
return $container;
}
- return static::createFromContainer($container);
+ return self::createFromContainer($container);
}
+ /**
+ * @template T
+ * @param string|class-string $id
+ * @return T|mixed
+ * @throws ContainerFrozenException
+ * @throws ContainerNotFoundException
+ * @throws Throwable
+ */
public function get(string $id)
{
- return $this->container->get($id);
+ if ($this->container instanceof SystemContainerInterface
+ || $this->container->has($id)
+ ) {
+ return $this->container->get($id);
+ }
+
+ /** @noinspection DuplicatedCode */
+ if ($this->hasRawService($id)) {
+ $this->frozenServices[$id] ??= true;
+ return $this->getRawService($id);
+ }
+
+ $exists = $this->hasQueuedService($id);
+ if (!$exists && $this->hasAlias($id)) {
+ $newId = $this->getAlias($id);
+ if ($this->hasRawService($newId)) {
+ $this->frozenServices[$id] ??= true;
+ return $this->getRawService($newId);
+ }
+ if ($this->hasQueuedService($newId)) {
+ $id = $newId;
+ $exists = true;
+ }
+ }
+
+ if ($exists) {
+ try {
+ // assert
+ $this->assertCallstack();
+ $value = $this->getResolver()->resolve($id);
+ $this->removeQueuedService($id);
+ // call
+ $this->raw($id, $value);
+ $this->frozenServices[$id] = true;
+ // reset
+ $this->resetCallstack();
+ return $value;
+ } catch (Throwable $e) {
+ $this->resetCallstack();
+ throw $e;
+ }
+ }
+
+ throw new ContainerNotFoundException(
+ sprintf('Container %s has not found.', $id)
+ );
}
public function has(string $id): bool
@@ -58,37 +158,44 @@ public function has(string $id): bool
public function remove(string $id): void
{
- if ($this->container instanceof Container) {
- $this->container->remove($id);
- return;
- }
- if (method_exists($this->container, 'remove')) {
+ if ($this->container instanceof SystemContainerInterface) {
$this->container->remove($id);
return;
}
- if ($this->container instanceof ArrayAccess) {
- unset($this->container[$id]);
- }
+
+ unset(
+ $this->queuedServices[$id],
+ $this->frozenServices[$id],
+ $this->rawServices[$id],
+ $this->arguments[$id]
+ );
}
public function set(string $id, mixed $container, ...$arguments): void
{
- if ($this->container instanceof Container) {
+ if ($this->container instanceof SystemContainerInterface) {
$this->container->set($id, $container, ...$arguments);
return;
}
+
if (method_exists($this->container, 'set')) {
- $this->container->set($id, $container, ...$arguments);
+ $this->container->set($id, function () use ($container, $arguments) {
+ return $this->getResolver()->resolveCallable($container, $arguments);
+ });
return;
}
- if ($this->container instanceof ArrayAccess) {
- $this->container[$id] = $container;
+
+ $this->assertFrozen($id);
+ unset($this->rawServices[$id]);
+ $this->queuedServices[$id] = $container;
+ if ($arguments === []) {
+ $this->arguments[$id] = $arguments;
}
}
- public function getResolver(): ?ContainerResolver
+ public function getResolver(): ContainerResolver
{
- return $this->resolver;
+ return $this->resolver??$this->container->getResolver();
}
public function offsetExists(mixed $offset): bool
@@ -122,4 +229,202 @@ public function __invoke()
sprintf('Class %s is not invokable', $this::class)
);
}
+
+ public function hasArgument(string $serviceId): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->hasArgument($serviceId);
+ }
+ return array_key_exists($serviceId, $this->arguments);
+ }
+
+ public function getArgument(string $serviceId)
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getArgument($serviceId);
+ }
+ return $this->arguments[$serviceId]??null;
+ }
+
+ public function setAlias(string $id, string $containerId): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->setAlias($id, $containerId);
+ return;
+ }
+ $this->aliases[$id] = $containerId;
+ }
+
+ public function removeAlias(string $id): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->removeAlias($id);
+ return;
+ }
+ unset($this->aliases[$id]);
+ }
+
+ public function getAliases(): array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getAliases();
+ }
+ return $this->aliases;
+ }
+
+ public function hasAlias(string $id): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->hasAlias($id);
+ }
+ return array_key_exists($id, $this->aliases);
+ }
+
+ public function getAlias(string $id): ?string
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getAlias($id);
+ }
+ return $this->aliases[$id]??null;
+ }
+
+ public function getParameter(string $name)
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getParameter($name);
+ }
+ return $this->parameters[$name]??null;
+ }
+
+ public function getParameters(): array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getParameters();
+ }
+ return $this->parameters;
+ }
+
+ public function setParameters(array $parameters): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->setParameters($parameters);
+ return;
+ }
+ $this->parameters = $parameters;
+ }
+
+ public function setParameter(string $name, #[SensitiveParameter] $value): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->setParameter($name, $value);
+ return;
+ }
+ $this->parameters[$name] = $value;
+ }
+
+ public function add(ContainerInvokable $objectContainer, ...$arguments): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->add($objectContainer, ...$arguments);
+ return;
+ }
+ $this->set($objectContainer->getId(), $objectContainer, ...$arguments);
+ }
+
+ public function raw(string $id, $raw): void
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ $this->container->raw($id, $raw);
+ return;
+ }
+ $this->assertFrozen($id);
+ $this->rawServices[$id] = $raw;
+ }
+
+ public function getQueuedServices(): array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getQueuedServices();
+ }
+ return $this->queuedServices;
+ }
+
+ public function hasQueuedService(string $id): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->hasQueuedService($id);
+ }
+ return array_key_exists($id, $this->queuedServices);
+ }
+
+ public function removeQueuedService(string $id): mixed
+ {
+ $value = $this->getQueueService($id);
+ unset($this->queuedServices[$id], $this->arguments[$id]);
+ return $value;
+ }
+
+ public function inQueue(string $id): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->inQueue($id);
+ }
+ return array_key_exists($id, $this->queuedServices);
+ }
+
+ public function getQueueService(string $id) : mixed
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getQueueService($id);
+ }
+ return $this->queuedServices[$id]??null;
+ }
+
+ public function isFrozen(string $id): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->isFrozen($id);
+ }
+ return isset($this->frozenServices[$id]);
+ }
+
+ public function getRawServices(): array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getRawServices();
+ }
+ return $this->rawServices;
+ }
+
+ public function getRawService(string $id)
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getRawServices();
+ }
+ return $this->rawServices[$id]??null;
+ }
+
+ public function hasRawService(string $id): bool
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->hasRawService($id);
+ }
+ return array_key_exists($id, $this->rawServices);
+ }
+
+ public function getFrozenServices(): array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->getFrozenServices();
+ }
+ return $this->frozenServices;
+ }
+
+ public function keys() : array
+ {
+ if ($this->container instanceof SystemContainerInterface) {
+ return $this->container->keys();
+ }
+ return array_merge(array_keys($this->queuedServices), array_keys($this->rawServices));
+ }
}
diff --git a/src/Container/Factory/ContainerFactory.php b/src/Container/Factory/ContainerFactory.php
index 0628580..14dc6ea 100644
--- a/src/Container/Factory/ContainerFactory.php
+++ b/src/Container/Factory/ContainerFactory.php
@@ -22,7 +22,9 @@
use ArrayAccess\TrayDigita\Collection\Config;
use ArrayAccess\TrayDigita\Console\Application;
use ArrayAccess\TrayDigita\Container\Container;
+use ArrayAccess\TrayDigita\Container\ContainerWrapper;
use ArrayAccess\TrayDigita\Container\Exceptions\ContainerFrozenException;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Container\Interfaces\ContainerFactoryInterface;
use ArrayAccess\TrayDigita\Database\Connection;
use ArrayAccess\TrayDigita\Database\DatabaseEventsCollector;
@@ -43,6 +45,8 @@
use ArrayAccess\TrayDigita\Image\ImageResizer;
use ArrayAccess\TrayDigita\Image\Interfaces\ImageResizerFactoryInterface;
use ArrayAccess\TrayDigita\Kernel\HttpKernel;
+use ArrayAccess\TrayDigita\Kernel\Interfaces\KernelInterface;
+use ArrayAccess\TrayDigita\Kernel\Kernel;
use ArrayAccess\TrayDigita\L10n\Translations\Interfaces\TranslatorInterface;
use ArrayAccess\TrayDigita\L10n\Translations\Translator;
use ArrayAccess\TrayDigita\Logger\Logger;
@@ -103,8 +107,12 @@ class ContainerFactory implements ContainerFactoryInterface
RouteRunnerInterface::class => RouteRunner::class,
MiddlewareDispatcherInterface::class => MiddlewareDispatcher::class,
ResponseEmitterInterface::class => ResponseEmitter::class,
+ // kernel
+ KernelInterface::class => Kernel::class,
HttpKernelInterface::class => HttpKernel::class,
+ // scheduler
Scheduler::class => Scheduler::class,
+ // assets
AssetsCollectionInterface::class => AssetCollection::class,
// i18n
TranslatorInterface::class => Translator::class,
@@ -273,17 +281,20 @@ public function createContainer(
foreach ($aliases as $id => $target) {
$container->setAlias($id, $target);
}
+
return $container;
}
/**
- * @psalm-return Container|ContainerInterface
+ * @return SystemContainerInterface
* @throws ContainerFrozenException
*/
- public function createDefault(): ContainerInterface
+ public function createDefault(): SystemContainerInterface
{
$default = array_merge($this->defaultServices, self::DEFAULT_SERVICES);
$defaultAliases = array_merge($this->defaultServiceAliases, self::DEFAULT_SERVICE_ALIASES);
- return $this->createContainer($default, $defaultAliases);
+ return ContainerWrapper::maybeContainerOrCreate(
+ $this->createContainer($default, $defaultAliases)
+ );
}
}
diff --git a/src/Container/Interfaces/SystemContainerInterface.php b/src/Container/Interfaces/SystemContainerInterface.php
new file mode 100644
index 0000000..a6b998a
--- /dev/null
+++ b/src/Container/Interfaces/SystemContainerInterface.php
@@ -0,0 +1,74 @@
+getSchemaAssetsFilter())) {
$orm->setSchemaAssetsFilter($schema);
}
- $entityDir = null;
+ $entityDirectory = null;
$storage = null;
- $proxyDir = null;
+ $proxyDirectory = null;
if (method_exists($container, 'getParameter')) {
- $entityDir = $container->getParameter('entitiesDir');
- $storage = $container->getParameter('storageDir');
- $proxyDir = $container->getParameter('proxyDir');
+ $entityDirectory = $container->getParameter('entitiesDirectory');
+ $storage = $container->getParameter('storageDirectory');
+ $proxyDirectory = $container->getParameter('proxyDirectory');
}
$storage = is_string($storage) ? $storage : $path->get('storage');
- $entityDir = is_string($entityDir) ? $entityDir : $path->get('entity');
- $proxyPath = is_string($proxyDir) ? $proxyDir : $database->get('proxyDir');
+ $entityDirectory = is_string($entityDirectory) ? $entityDirectory : $path->get('entity');
+ $proxyPath = is_string($proxyDirectory) ? $proxyDirectory : $database->get('proxyDirectory');
$proxyPath = $proxyPath ?: "$storage/database/proxy";
$proxyPath = $configuration->getProxyDir() ?: $proxyPath;
if (!is_dir($proxyPath) && ! Consolidation::isCli()) {
@@ -158,13 +158,13 @@ protected function configureORMConfiguration(?Configuration $configuration) : Or
: preg_replace('~(.+)\\\[^\\\]+$~', '$1\\Storage\Proxy', __NAMESPACE__);
if (!$metadata instanceof AttributeDriver) {
$metadata = new AttributeDriver(
- [$entityDir],
+ [$entityDirectory],
true
);
}
$metadata->setFileExtension('.php');
- $metadata->addPaths([$entityDir]);
+ $metadata->addPaths([$entityDirectory]);
$orm->setMetadataDriverImpl($metadata);
$orm->setProxyDir($proxyPath);
$orm->setProxyNamespace($proxyNamesSpace);
diff --git a/src/HttpKernel/BaseKernel.php b/src/HttpKernel/BaseKernel.php
index 39b59b2..c57b0f9 100644
--- a/src/HttpKernel/BaseKernel.php
+++ b/src/HttpKernel/BaseKernel.php
@@ -7,7 +7,8 @@
use ArrayAccess\TrayDigita\Benchmark\Interfaces\ResetInterface;
use ArrayAccess\TrayDigita\Benchmark\Middlewares\DebuggingMiddleware;
use ArrayAccess\TrayDigita\Collection\Config;
-use ArrayAccess\TrayDigita\Container\Container;
+use ArrayAccess\TrayDigita\Container\Interfaces\ContainerIndicateInterface;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
use ArrayAccess\TrayDigita\Exceptions\Runtime\RuntimeException;
use ArrayAccess\TrayDigita\HttpKernel\Helper\KernelCommandLoader;
@@ -30,6 +31,7 @@
use ArrayAccess\TrayDigita\Util\Filter\DataNormalizer;
use ArrayAccess\TrayDigita\Util\Parser\DotEnv;
use DateTimeZone;
+use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
@@ -72,10 +74,9 @@
abstract class BaseKernel implements
KernelInterface,
RequestHandlerInterface,
- RebootableInterface
+ RebootableInterface,
+ ContainerIndicateInterface
{
- const DEFAULT_EXPIRED_AFTER = 7200;
-
private int $bootStack = 0;
private bool $booted = false;
@@ -131,6 +132,14 @@ public function __construct(
}
}
+ /**
+ * @return ?ContainerInterface
+ */
+ public function getContainer(): ?ContainerInterface
+ {
+ return $this->getHttpKernel()->getContainer();
+ }
+
public function getStartMemory(): int
{
return $this->getHttpKernel()->getStartMemory();
@@ -175,16 +184,13 @@ public function boot()
if ($this->booted === true) {
if (!$this->requestStackSize
&& true === $this->resetServices
- && $this
- ->getHttpKernel()
- ->getContainer()
- ?->has(ResetInterface::class)
+ && ($resetter = ContainerHelper::getNull(
+ ResetInterface::class,
+ $this->getContainer()
+ ))
) {
try {
- $resetter = $this->getHttpKernel()->getContainer()?->get(ResetInterface::class);
- if ($resetter instanceof ResetInterface) {
- $resetter->reset();
- }
+ $resetter->reset();
} catch (Throwable) {
}
}
@@ -387,7 +393,7 @@ final public function init() : static
}
/**
- * @var Container $container
+ * @var SystemContainerInterface $container
*/
$httpKernel = $this->getHttpKernel();
$container = $httpKernel->getContainer();
@@ -401,17 +407,17 @@ final public function init() : static
$container->remove(KernelInterface::class);
$container->raw(KernelInterface::class, $this);
- $appDir = realpath(TD_APP_DIRECTORY)?:TD_APP_DIRECTORY;
+ $appDirectory = realpath(TD_APP_DIRECTORY)?:TD_APP_DIRECTORY;
$this->rootDirectory = $root;
if (defined('TD_INDEX_FILE')
&& is_string(TD_INDEX_FILE)
&& file_exists(TD_INDEX_FILE)
) {
- $publicDir = dirname(realpath(TD_INDEX_FILE)??TD_INDEX_FILE);
+ $publicDirectory = dirname(realpath(TD_INDEX_FILE)??TD_INDEX_FILE);
} else {
if (Consolidation::isCli()) {
// use default public
- $publicDir = $root . DIRECTORY_SEPARATOR . 'public';
+ $publicDirectory = $root . DIRECTORY_SEPARATOR . 'public';
} else {
$documentRoot = $_SERVER['DOCUMENT_ROOT']??null;
$documentRoot = $documentRoot && is_dir($documentRoot)
@@ -421,27 +427,27 @@ final public function init() : static
&& is_string($_SERVER['SCRIPT_FILENAME']??null)
&& is_file($_SERVER['SCRIPT_FILENAME'])
) {
- $publicDir = dirname($_SERVER['SCRIPT_FILENAME']);
+ $publicDirectory = dirname($_SERVER['SCRIPT_FILENAME']);
} else {
- $publicDir = $root . DIRECTORY_SEPARATOR . 'public';
+ $publicDirectory = $root . DIRECTORY_SEPARATOR . 'public';
}
}
}
$defaultPaths = [
- 'controller' => $appDir . '/Controllers',
- 'entity' => $appDir . '/Entities',
- 'language' => $appDir . '/Languages',
- 'middleware' => $appDir . '/Middlewares',
- 'migration' => $appDir . '/Migrations',
- 'module' => $appDir . '/Modules',
- 'view' => $appDir . '/Views',
- 'databaseEvent' => $appDir . '/DatabaseEvents',
- 'scheduler' => $appDir . '/Schedulers',
- 'command' => $appDir . '/Commands',
+ 'controller' => $appDirectory . '/Controllers',
+ 'entity' => $appDirectory . '/Entities',
+ 'language' => $appDirectory . '/Languages',
+ 'middleware' => $appDirectory . '/Middlewares',
+ 'migration' => $appDirectory . '/Migrations',
+ 'module' => $appDirectory . '/Modules',
+ 'view' => $appDirectory . '/Views',
+ 'databaseEvent' => $appDirectory . '/DatabaseEvents',
+ 'scheduler' => $appDirectory . '/Schedulers',
+ 'command' => $appDirectory . '/Commands',
'storage' => $root . '/storage',
'data' => $root . '/data',
- 'public' => $publicDir,
- 'upload' => $publicDir . '/uploads',
+ 'public' => $publicDirectory,
+ 'upload' => $publicDirectory . '/uploads',
'template' => 'templates',
];
@@ -547,16 +553,16 @@ final public function init() : static
}
}
- $uploadDir = $path->get('upload');
- $uploadDir = $publicDir . DIRECTORY_SEPARATOR . $uploadDir;
- $uploadDir = realpath($uploadDir)??$uploadDir;
+ $uploadDirectory = $path->get('upload');
+ $uploadDirectory = $publicDirectory . DIRECTORY_SEPARATOR . $uploadDirectory;
+ $uploadDirectory = realpath($uploadDirectory)??$uploadDirectory;
$uploadPath = realpath($path->get('upload'))??null;
- if (!$uploadPath || !str_starts_with($uploadPath, $publicDir)) {
- if ($uploadPath && is_dir($publicDir . DIRECTORY_SEPARATOR . $uploadPath)) {
- $uploadDir = $publicDir . DIRECTORY_SEPARATOR . $uploadPath;
- $uploadDir = realpath($uploadDir)??$uploadDir;
+ if (!$uploadPath || !str_starts_with($uploadPath, $publicDirectory)) {
+ if ($uploadPath && is_dir($publicDirectory . DIRECTORY_SEPARATOR . $uploadPath)) {
+ $uploadDirectory = $publicDirectory . DIRECTORY_SEPARATOR . $uploadPath;
+ $uploadDirectory = realpath($uploadDirectory)??$uploadDirectory;
}
- $path->set('upload', $uploadDir);
+ $path->set('upload', $uploadDirectory);
}
if ($this->getConfigError()) {
@@ -566,11 +572,13 @@ final public function init() : static
|| $iniGet === '1'
|| $iniGet === 'true';
}
-
- $container->setParameter(
- 'displayErrorDetails',
- (bool)$environment['displayErrorDetails']
- );
+ // debug also display error
+ $debug = $environment->get('debug') === true;
+ if ($debug) {
+ $environment['displayErrorDetails'] = true;
+ }
+ $environment['displayErrorDetails'] = (bool)$environment['displayErrorDetails'];
+ $container->setParameter('displayErrorDetails', $environment['displayErrorDetails']);
if ($environment['displayErrorDetails']) {
$manager?->attach(
'jsonResponder.debug',
@@ -654,37 +662,37 @@ final public function init() : static
? $templatePath
: 'templates';
$path->set('template', $templatePath);
- $storageDir = $path->get('storage');
- $dataDir = $path->get('data');
+ $storageDirectory = $path->get('storage');
+ $dataDirectory = $path->get('data');
if (!Consolidation::isCli()) {
- if (!is_dir($storageDir)) {
- mkdir($storageDir, 0755, true);
+ if (!is_dir($storageDirectory)) {
+ mkdir($storageDirectory, 0755, true);
}
- if (!is_dir($dataDir)) {
- mkdir($dataDir, 0755, true);
+ if (!is_dir($dataDirectory)) {
+ mkdir($dataDirectory, 0755, true);
}
}
- $dataDir = realpath($dataDir)?:$dataDir;
- $storageDir = realpath($storageDir)?:$storageDir;
- $path->set('storage', $storageDir);
- $path->set('data', $dataDir);
+ $dataDirectory = realpath($dataDirectory)?:$dataDirectory;
+ $storageDirectory = realpath($storageDirectory)?:$storageDirectory;
+ $path->set('storage', $storageDirectory);
+ $path->set('data', $dataDirectory);
// directory parameter
- $container->setParameter('viewsDir', $path->get('view'));
- $container->setParameter('controllersDir', $path->get('controller'));
- $container->setParameter('languagesDir', $path->get('language'));
- $container->setParameter('migrationsDir', $path->get('migration'));
- $container->setParameter('modulesDir', $path->get('module'));
- $container->setParameter('entitiesDir', $path->get('entity'));
- // $container->setParameter('repositoriesDir', $path->get('repository'));
- $container->setParameter('databaseEventsDir', $path->get('databaseEvent'));
- $container->setParameter('schedulersDir', $path->get('scheduler'));
- $container->setParameter('commandsDir', $path->get('command'));
- $container->setParameter('middlewaresDir', $path->get('middleware'));
- $container->setParameter('storageDir', $storageDir);
- $container->setParameter('uploadsDir', $uploadDir);
- $container->setParameter('publicDir', $publicDir);
- $container->setParameter('dataDir', $dataDir);
+ $container->setParameter('viewsDirectory', $path->get('view'));
+ $container->setParameter('controllersDirectory', $path->get('controller'));
+ $container->setParameter('languagesDirectory', $path->get('language'));
+ $container->setParameter('migrationsDirectory', $path->get('migration'));
+ $container->setParameter('modulesDirectory', $path->get('module'));
+ $container->setParameter('entitiesDirectory', $path->get('entity'));
+ // $container->setParameter('repositoriesDirectory', $path->get('repository'));
+ $container->setParameter('databaseEventsDirectory', $path->get('databaseEvent'));
+ $container->setParameter('schedulersDirectory', $path->get('scheduler'));
+ $container->setParameter('commandsDirectory', $path->get('command'));
+ $container->setParameter('middlewaresDirectory', $path->get('middleware'));
+ $container->setParameter('storageDirectory', $storageDirectory);
+ $container->setParameter('uploadsDirectory', $uploadDirectory);
+ $container->setParameter('publicDirectory', $publicDirectory);
+ $container->setParameter('dataDirectory', $dataDirectory);
$container->setParameter('templatePath', $templatePath);
// security
@@ -842,7 +850,7 @@ protected function registerProviders(): void
return;
}
$this->providerRegistered = true;
- $container = $this->getHttpKernel()->getContainer();
+ $container = $this->getContainer();
$manager = ContainerHelper::use(ManagerInterface::class, $container);
$manager?->dispatch('kernel.beforeRegisterProviders', $this);
try {
@@ -853,7 +861,7 @@ protected function registerProviders(): void
? $translator
: null;
if ($translator) {
- if ($container instanceof Container) {
+ if ($container instanceof SystemContainerInterface) {
try {
$poMoAdapter = $container->decorate(PoMoAdapter::class);
$jsonAdapter = $container->decorate(JsonAdapter::class);
@@ -865,14 +873,14 @@ protected function registerProviders(): void
$translator->addAdapter($poMoAdapter);
$translator->addAdapter($jsonAdapter);
- $languageDir = $config?->get('language');
- if (is_string($languageDir) && is_dir($languageDir)) {
+ $languageDirectory = $config?->get('language');
+ if (is_string($languageDirectory) && is_dir($languageDirectory)) {
$poMoAdapter->registerDirectory(
- $languageDir,
+ $languageDirectory,
TranslatorInterface::DEFAULT_DOMAIN
);
$jsonAdapter->registerDirectory(
- $languageDir,
+ $languageDirectory,
TranslatorInterface::DEFAULT_DOMAIN
);
}
diff --git a/src/HttpKernel/Helper/AbstractHelper.php b/src/HttpKernel/Helper/AbstractHelper.php
index e20423d..d2119ec 100644
--- a/src/HttpKernel/Helper/AbstractHelper.php
+++ b/src/HttpKernel/Helper/AbstractHelper.php
@@ -10,10 +10,7 @@
use ArrayAccess\TrayDigita\HttpKernel\BaseKernel;
use ArrayAccess\TrayDigita\Util\Filter\Consolidation;
use ArrayAccess\TrayDigita\Util\Filter\ContainerHelper;
-use ArrayAccess\TrayDigita\Util\Parser\PhpClassParserSerial;
use DateInterval;
-use PhpParser\Node\Stmt\Class_;
-use PhpParser\Node\Stmt\Namespace_;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Container\ContainerInterface;
@@ -29,11 +26,14 @@
use function is_dir;
use function is_string;
use function md5;
+use function php_strip_whitespace;
+use function preg_match;
use function spl_object_hash;
use function sprintf;
use function str_replace;
use function str_starts_with;
use function ucfirst;
+use const PREG_UNMATCHED_AS_NULL;
abstract class AbstractHelper
{
@@ -75,9 +75,14 @@ protected function generateCacheKey(
*/
final protected function getClasNameFromFile(SplFileInfo $splFileInfo) : ?string
{
- if (!$splFileInfo->isFile()) {
+ if (!$splFileInfo->isFile()
+ || !$splFileInfo->isReadable()
+ || $splFileInfo->getExtension() !== 'php'
+ || $splFileInfo->getSize() > 1048576 // 1MiB
+ ) {
return null;
}
+
$realPath = $splFileInfo->getRealPath();
$mtime = $splFileInfo->getMTime();
$cacheKey = $this->generateCacheKey("class:$realPath");
@@ -90,7 +95,63 @@ final protected function getClasNameFromFile(SplFileInfo $splFileInfo) : ?string
|| (!is_string($cacheItems['className']) && $cacheItems['className'] !== false)
) {
try {
- $parser = PhpClassParserSerial::fromFileInfo($splFileInfo);
+ $source = php_strip_whitespace($splFileInfo->getRealPath());
+ // GETTING CLAS NAME
+ preg_match(
+ '~
+ ^<\?php\s+
+ # declare
+ (?:
+ (?:\s*declare\s*\(\s*
+ (?:
+ strict_types\s*=\s*[01]
+ |encoding\s*=\s*\'[^\']*\'
+ |ticks\s*=\s*[1-9][0-9]*(?:\.[0-9]*)?
+ )
+ (?:
+ \s*,\s*
+ (?:
+ strict_types\s*=\s*[01]
+ |encoding\s*=\s*\'[^\']*\'
+ |ticks\s*=\s*[1-9][0-9]*(?:\.[0-9]*)?
+ )
+ )*
+ \s*
+ \)
+ \s*;\s*
+ )*
+ )?
+ (?:\s*namespace\s+
+ (?
+ [A-Z-a-z_\x80-\xff]+
+ [A-Z-a-z_0-9\x80-\xff]*
+ (?:\\\[A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*)*
+ )\s*;
+ )?
+ \s*
+ (use\s+[^;]+;\s*(?!class\s+).*)?
+ (?:(?:final|readonly)\s+)?class\s+
+ (?
+ [A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*
+ )
+ [\s{]
+ ~xi',
+ $source,
+ $match,
+ PREG_UNMATCHED_AS_NULL
+ );
+ $className = false;
+ $ns = null;
+ if (!empty($match)) {
+ $ns = ($match['namespace']??null?:null);
+ $className = $match['className'];
+ }
+ /*
+ // use parser
+ $parser = PhpClassParserSerial::fromSource($source);
+ unset($source);
+ $parser->getSource();
+ echo microtime(true) * 1000 - $start."\n";
$className = false;
$ns = null;
foreach ($parser->getSource() as $stmt) {
@@ -109,6 +170,7 @@ final protected function getClasNameFromFile(SplFileInfo $splFileInfo) : ?string
break;
}
}
+ */
if ($className) {
if ($ns) {
$className = "$ns\\$className";
diff --git a/src/HttpKernel/Helper/KernelMiddlewareLoader.php b/src/HttpKernel/Helper/KernelMiddlewareLoader.php
index e00fcdc..0876d65 100644
--- a/src/HttpKernel/Helper/KernelMiddlewareLoader.php
+++ b/src/HttpKernel/Helper/KernelMiddlewareLoader.php
@@ -14,10 +14,8 @@
use function class_exists;
use function is_bool;
use function is_dir;
-use function ksort;
use function trim;
use function ucfirst;
-use const SORT_ASC;
class KernelMiddlewareLoader extends AbstractLoaderNameBased
{
@@ -74,53 +72,12 @@ protected function isProcessable(): bool
/**
* @var array>
*/
- private array $middlewares = [];
+ // private array $middlewares = [];
- protected function postProcess(): void
+ /*protected function postProcess(): void
{
- foreach ($this->kernel->getHttpKernel()->getDeferredMiddlewares() as $priority => $middlewares) {
- foreach ($middlewares as $middleware) {
- $this->middlewares[$priority][] = $middleware;
- }
- }
- // clear
- $this->kernel->getHttpKernel()->clearDeferredMiddlewares();
- ksort($this->middlewares, SORT_ASC);
- $manager = $this->getManager();
- foreach ($this->middlewares as $priority => $middlewares) {
- unset($this->middlewares[$priority]);
- foreach ($middlewares as $middleware) {
- try {
- // @dispatch(kernel.beforeRegisterMiddleware)
- $manager?->dispatch(
- 'kernel.beforeRegisterMiddleware',
- $this->kernel->getHttpKernel(),
- $this->kernel,
- $this,
- $middleware
- );
- $this->kernel->getHttpKernel()->addMiddleware($middleware);
- // @dispatch(kernel.registerMiddleware)
- $manager?->dispatch(
- 'kernel.registerMiddleware',
- $this->kernel->getHttpKernel(),
- $this->kernel,
- $this,
- $middleware
- );
- } finally {
- // @dispatch(kernel.afterRegisterMiddleware)
- $manager?->dispatch(
- 'kernel.afterRegisterMiddleware',
- $this->kernel->getHttpKernel(),
- $this->kernel,
- $this,
- $middleware
- );
- }
- }
- }
- }
+ $this->kernel->getHttpKernel()->dispatchDeferredMiddleware();
+ }*/
protected function doRegister(): bool
{
@@ -172,13 +129,14 @@ protected function loadService(
if (!$splFileInfo->isFile()) {
return;
}
+ $httpKernel = $this->kernel->getHttpKernel();
$realPath = $splFileInfo->getRealPath();
$manager = $this->getManager();
// @dispatch(kernel.beforeLoadMiddleware)
$manager?->dispatch(
'kernel.beforeLoadMiddleware',
$realPath,
- $this->kernel->getHttpKernel(),
+ $httpKernel,
$this->kernel,
$this
);
@@ -190,7 +148,7 @@ protected function loadService(
$manager?->dispatch(
'kernel.loadMiddleware',
$realPath,
- $this->kernel->getHttpKernel(),
+ $httpKernel,
$this->kernel,
$this
);
@@ -215,7 +173,7 @@ protected function loadService(
) {
$result = ContainerHelper::resolveCallable($className, $this->getContainer());
if ($result instanceof AbstractMiddleware) {
- $this->middlewares[$result->getPriority()][] = $result;
+ $httpKernel->addDeferredMiddleware($result);
}
}
} catch (Throwable $e) {
@@ -233,7 +191,7 @@ protected function loadService(
$manager?->dispatch(
'kernel.loadMiddleware',
$realPath,
- $this->kernel->getHttpKernel(),
+ $httpKernel,
$this->kernel,
$this,
$result
@@ -246,7 +204,7 @@ protected function loadService(
$manager?->dispatch(
'kernel.afterLoadMiddleware',
$realPath,
- $this->kernel->getHttpKernel(),
+ $httpKernel,
$this->kernel,
$this,
$result
diff --git a/src/HttpKernel/Interfaces/HttpKernelInterface.php b/src/HttpKernel/Interfaces/HttpKernelInterface.php
index 5ea0233..0be8018 100644
--- a/src/HttpKernel/Interfaces/HttpKernelInterface.php
+++ b/src/HttpKernel/Interfaces/HttpKernelInterface.php
@@ -7,6 +7,7 @@
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerIndicateInterface;
use ArrayAccess\TrayDigita\Handler\Interfaces\MiddlewareDispatcherInterface;
use ArrayAccess\TrayDigita\Http\Interfaces\ResponseDispatcherInterface;
+use ArrayAccess\TrayDigita\Kernel\Interfaces\KernelInterface;
use ArrayAccess\TrayDigita\Routing\Interfaces\RouterInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
@@ -24,6 +25,7 @@ interface HttpKernelInterface extends
ManagerIndicateInterface,
ContainerIndicateInterface
{
+ public function getKernel() : KernelInterface;
public function getStartMemory() : int;
@@ -45,6 +47,11 @@ public function addDeferredMiddleware(MiddlewareInterface $middleware);
* @return array>
*/
public function getDeferredMiddlewares() : array;
-
+
+ public function dispatchDeferredMiddleware();
+
+ /**
+ * Clear the deferred middleware
+ */
public function clearDeferredMiddlewares();
}
diff --git a/src/Kernel/AbstractHttpKernel.php b/src/Kernel/AbstractHttpKernel.php
new file mode 100644
index 0000000..aa65a7b
--- /dev/null
+++ b/src/Kernel/AbstractHttpKernel.php
@@ -0,0 +1,410 @@
+startTime = microtime(true);
+ $this->startMemory = memory_get_usage();
+
+ $container ??= (new ContainerFactory())->createDefault();
+ $this->container = $container;
+ $manager ??= ContainerHelper::use(ManagerInterface::class, $container);
+ if (!$manager) {
+ $container->remove(ManagerInterface::class);
+ $manager = new Manager();
+ $container->set(ManagerInterface::class, $manager);
+ }
+ $this->managerObject = $manager;
+ $this->container->set(HttpKernelInterface::class, fn () => $this);
+
+ // router
+ $definitions = [
+ RouterInterface::class => Router::class,
+ MiddlewareDispatcherInterface::class => MiddlewareDispatcher::class,
+ RouteRunnerInterface::class => RouteRunner::class,
+ ];
+
+ foreach ($definitions as $key => $item) {
+ try {
+ if (!$container->has($key)) {
+ $container->set($key, $item);
+ }
+ } catch (Throwable) {
+ }
+ }
+
+ $this->router = ContainerHelper::service(RouterInterface::class, $container);
+ $this->middlewareDispatcher = ContainerHelper::service(MiddlewareDispatcherInterface::class, $container);
+ }
+
+ public function getKernel(): KernelInterface
+ {
+ return $this->kernel;
+ }
+
+ public function getStartMemory(): int
+ {
+ return $this->startMemory;
+ }
+
+ public function getStartTime(): float
+ {
+ return $this->startTime;
+ }
+
+ public function getContainer(): ContainerInterface
+ {
+ return $this->container;
+ }
+
+ public function getRouter(): RouterInterface
+ {
+ return $this->router;
+ }
+
+ public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
+ {
+ return $this->middlewareDispatcher;
+ }
+
+ public function getManager(): ManagerInterface
+ {
+ return $this->managerObject;
+ }
+
+ public function addMiddleware(MiddlewareInterface $middleware): static
+ {
+ $this->getMiddlewareDispatcher()->addMiddleware($middleware);
+ return $this;
+ }
+
+ public function addDeferredMiddleware(MiddlewareInterface $middleware): static
+ {
+ $priority = $middleware instanceof AbstractMiddleware
+ ? $middleware->getPriority()
+ : 10;
+ $this->deferredMiddlewares[$priority][] = $middleware;
+ return $this;
+ }
+
+ public function getDeferredMiddlewares() : array
+ {
+ return $this->deferredMiddlewares;
+ }
+
+ public function clearDeferredMiddlewares(): void
+ {
+ $this->deferredMiddlewares = [];
+ }
+
+ public function getLastResponse(): ?ResponseInterface
+ {
+ return $this->lastResponse;
+ }
+
+ public function getLastRequest(): ?ServerRequestInterface
+ {
+ return $this->lastRequest;
+ }
+
+ public function dispatchDeferredMiddleware(): void
+ {
+ if (empty($this->deferredMiddlewares)) {
+ return;
+ }
+
+ ksort($this->deferredMiddlewares, SORT_ASC);
+ $manager = $this->getManager();
+ foreach ($this->deferredMiddlewares as $priority => $middlewares) {
+ unset($this->deferredMiddlewares[$priority]);
+ foreach ($middlewares as $middleware) {
+ try {
+ // @dispatch(kernel.beforeRegisterMiddleware)
+ $manager->dispatch(
+ 'kernel.beforeRegisterMiddleware',
+ $this,
+ $this->kernel,
+ $this,
+ $middleware
+ );
+ $this->addMiddleware($middleware);
+ // @dispatch(kernel.registerMiddleware)
+ $manager->dispatch(
+ 'kernel.registerMiddleware',
+ $this,
+ $this->kernel,
+ $this,
+ $middleware
+ );
+ } finally {
+ // @dispatch(kernel.afterRegisterMiddleware)
+ $manager->dispatch(
+ 'kernel.afterRegisterMiddleware',
+ $this,
+ $this->kernel,
+ $this,
+ $middleware
+ );
+ }
+ }
+ }
+ }
+
+ public function handle(ServerRequestInterface $request) : ResponseInterface
+ {
+ $this->assertCallstack();
+ if ($this->lastResponse
+ && $this->lastRequest
+ && spl_object_hash($request) === spl_object_hash($this->lastRequest)
+ ) {
+ $this->resetCallstack();
+ return $this->lastResponse;
+ }
+
+ $manager = $this->getManager();
+ $manager->dispatch('httpKernel.beforeHandle', $this);
+ // attach the middleware
+ $this->dispatchDeferredMiddleware();
+ try {
+ $this->lastRequest = $request;
+ // add middleware
+ $this->lastResponse = $this->getMiddlewareDispatcher()->handle($request);
+ /**
+ * This is to be in compliance with RFC 2616, Section 9.
+ * If the incoming request method is HEAD, we need to ensure that the response body
+ * is empty as the request may fall back on a GET route handler due to FastRoute's
+ * routing logic which could potentially append content to the response body
+ * https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
+ */
+ $method = strtoupper($request->getMethod());
+ if ($method === 'HEAD'
+ // also empty on cli
+ || $method === 'CLI'
+ ) {
+ $emptyBody = $this->getResponseFactory()->createResponse()->getBody();
+ $this->lastResponse = $this->lastResponse->withBody($emptyBody);
+ }
+ $manager->dispatch(
+ 'httpKernel.handle',
+ $this,
+ $this->lastResponse
+ );
+ $this->resetCallstack();
+ return $this->lastResponse;
+ } finally {
+ $manager->dispatch(
+ 'httpKernel.afterHandle',
+ $this
+ );
+ }
+ }
+
+ public function dispatchResponse(ResponseInterface $response): ResponseInterface
+ {
+ $this->assertCallstack();
+
+ $manager = $this->getManager();
+ // @dispatch(httpKernel.beforeDispatch)
+ $manager->dispatch(
+ 'httpKernel.beforeDispatch',
+ $this,
+ $response
+ );
+
+ /**
+ * @var SystemContainerInterface $container
+ */
+ $container = $this->getContainer();
+ $doEmit = ! Consolidation::isCli() || $manager->dispatch(
+ 'httpKernel.emitResponse',
+ false
+ ) === true;
+ $emitter = ContainerHelper::service(ResponseEmitterInterface::class, $container)
+ ?? new ResponseEmitter();
+ if ($emitter->isClosed()) {
+ throw new UnProcessableException(
+ 'Emitter has been closed.'
+ );
+ }
+
+ // @dispatch(httpKernel.dispatch)
+ $newResponse = $manager->dispatch('httpKernel.dispatch', $response);
+ if ($newResponse instanceof ResponseInterface) {
+ $response = $newResponse;
+ }
+
+ // @dispatch(response.final)
+ $newResponse = $manager->dispatch('response.final', $response);
+ if ($newResponse instanceof ResponseInterface) {
+ $response = $newResponse;
+ }
+
+ // @dispatch(httpKernel.afterDispatch)
+ $manager->dispatch(
+ 'httpKernel.afterDispatch',
+ $this,
+ $response
+ );
+
+ if ($doEmit) {
+ $reduceError = (bool) $manager
+ ->dispatch('response.reduceError', true);
+ $sendPreviousBuffer = (bool) $manager
+ ->dispatch('response.sendPreviousBuffer', true);
+ $emitter->emit($response, $reduceError, $sendPreviousBuffer);
+ }
+
+ // @dispatch(httpKernel.afterDispatch)
+ $manager->dispatch(
+ 'httpKernel.dispatched',
+ $this,
+ $response
+ );
+
+ $this->resetCallstack();
+
+ return $response;
+ }
+
+ public function run(ServerRequestInterface $request) : ResponseInterface
+ {
+ return $this->dispatchResponse($this->handle($request));
+ }
+
+ public function terminate(ServerRequestInterface $request, ResponseInterface $response): void
+ {
+ $this->assertCallstack();
+ $manager = $this->getManager();
+ // @dispatch(httpKernel.terminate)
+ $manager
+ ->dispatch(
+ 'httpKernel.beforeTerminate',
+ $this,
+ $request,
+ $response
+ );
+ try {
+ $manager->dispatch(
+ 'httpKernel.terminate',
+ $this,
+ $request,
+ $response
+ );
+ /*
+ * @var SystemContainerInterface $container
+ $container = $this->getContainer();
+ if (!$container->has(ResponseEmitterInterface::class)) {
+ return;
+ }
+ try {
+ $emitter = $container->get(ResponseEmitterInterface::class);
+ !$emitter->isClosed() && $emitter->close();
+ } catch (Throwable) {
+ }*/
+ } finally {
+ $manager->dispatch(
+ 'httpKernel.afterTerminate',
+ $this,
+ $request,
+ $response
+ );
+ $this->resetCallstack();
+ }
+ }
+
+ public function __call(string $name, array $arguments)
+ {
+ return $this->getRouter()->$name(...$arguments);
+ }
+
+ public function __debugInfo(): ?array
+ {
+ return Consolidation::debugInfo(
+ $this,
+ excludeKeys: [
+ 'router',
+ 'lastResponse',
+ 'lastRequest'
+ ]
+ );
+ }
+}
diff --git a/src/Kernel/AbstractKernel.php b/src/Kernel/AbstractKernel.php
index 6a0097c..aa16d1c 100644
--- a/src/Kernel/AbstractKernel.php
+++ b/src/Kernel/AbstractKernel.php
@@ -4,30 +4,48 @@
namespace ArrayAccess\TrayDigita\Kernel;
use ArrayAccess\TrayDigita\Container\Factory\ContainerFactory;
+use ArrayAccess\TrayDigita\Container\Interfaces\ContainerFactoryInterface;
+use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
+use ArrayAccess\TrayDigita\Exceptions\Runtime\RuntimeException;
use ArrayAccess\TrayDigita\HttpKernel\BaseKernel;
use ArrayAccess\TrayDigita\HttpKernel\Interfaces\HttpKernelInterface;
use ArrayAccess\TrayDigita\Kernel\Interfaces\KernelInterface;
-use Throwable;
+use ArrayAccess\TrayDigita\Util\Filter\ContainerHelper;
abstract class AbstractKernel extends BaseKernel
{
- public readonly ContainerFactory $containerFactory;
+ public readonly ContainerFactoryInterface $containerFactory;
public function __construct(
- ?ContainerFactory $containerFactory = null,
+ ?ContainerFactoryInterface $containerFactory = null,
?string $baseConfigFileName = KernelInterface::BASE_CONFIG_FILE_NAME
) {
$containerFactory ??= new ContainerFactory();
$this->containerFactory = $containerFactory;
$container = $containerFactory->createDefault();
- if (!$container->has(HttpKernelInterface::class)) {
- $container->set(HttpKernelInterface::class, HttpKernel::class);
+ if (!($hasRaw = $container->hasRawService(KernelInterface::class))
+ || $container->getRawService(KernelInterface::class) !== $this
+ ) {
+ if ($hasRaw) {
+ $container->remove(KernelInterface::class);
+ }
+ $container->raw(KernelInterface::class, $this);
}
- try {
- $kernel = $container->get(HttpKernelInterface::class);
- parent::__construct($kernel, $baseConfigFileName);
- } catch (Throwable) {
- parent::__construct(new HttpKernel($container));
+
+ $kernel = ContainerHelper::getNull(
+ HttpKernelInterface::class,
+ $container
+ )??new HttpKernel($this, $container, ContainerHelper::getNull(
+ ManagerInterface::class,
+ $container
+ ));
+
+ // kernel should equal this
+ if ($kernel->getKernel() !== $this) {
+ throw new RuntimeException(
+ 'Kernel instance could not contain outside current object'
+ );
}
+ parent::__construct($kernel, $baseConfigFileName);
}
}
diff --git a/src/Kernel/Decorator.php b/src/Kernel/Decorator.php
index f379c10..2eaccdd 100644
--- a/src/Kernel/Decorator.php
+++ b/src/Kernel/Decorator.php
@@ -7,9 +7,9 @@
use ArrayAccess\TrayDigita\Auth\Roles\Interfaces\PermissionInterface;
use ArrayAccess\TrayDigita\Benchmark\Interfaces\ProfilerInterface;
use ArrayAccess\TrayDigita\Collection\Config;
-use ArrayAccess\TrayDigita\Container\Container;
use ArrayAccess\TrayDigita\Container\ContainerWrapper;
use ArrayAccess\TrayDigita\Container\Factory\ContainerFactory;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Database\Connection;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
use ArrayAccess\TrayDigita\Exceptions\InvalidArgument\EmptyArgumentException;
@@ -267,7 +267,7 @@ public static function service(string $name)
return self::resolveDepend($name);
}
- private static function resolveInternal(string $name): Container|ContainerWrapper
+ private static function resolveInternal(string $name): SystemContainerInterface
{
$container = self::container();
$container = ContainerWrapper::maybeContainerOrCreate($container);
diff --git a/src/Kernel/HttpKernel.php b/src/Kernel/HttpKernel.php
index 10899d2..2af123f 100644
--- a/src/Kernel/HttpKernel.php
+++ b/src/Kernel/HttpKernel.php
@@ -3,359 +3,6 @@
namespace ArrayAccess\TrayDigita\Kernel;
-use ArrayAccess\TrayDigita\Container\Container;
-use ArrayAccess\TrayDigita\Container\Factory\ContainerFactory;
-use ArrayAccess\TrayDigita\Event\Interfaces\ManagerAllocatorInterface;
-use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
-use ArrayAccess\TrayDigita\Event\Manager;
-use ArrayAccess\TrayDigita\Exceptions\Runtime\UnProcessableException;
-use ArrayAccess\TrayDigita\Handler\Interfaces\MiddlewareDispatcherInterface;
-use ArrayAccess\TrayDigita\Http\Interfaces\ResponseEmitterInterface;
-use ArrayAccess\TrayDigita\Http\ResponseEmitter;
-use ArrayAccess\TrayDigita\HttpKernel\Interfaces\HttpKernelInterface;
-use ArrayAccess\TrayDigita\HttpKernel\Interfaces\TerminableInterface;
-use ArrayAccess\TrayDigita\Middleware\AbstractMiddleware;
-use ArrayAccess\TrayDigita\Middleware\MiddlewareDispatcher;
-use ArrayAccess\TrayDigita\Routing\Interfaces\RouterInterface;
-use ArrayAccess\TrayDigita\Routing\Interfaces\RouteRunnerInterface;
-use ArrayAccess\TrayDigita\Routing\Router;
-use ArrayAccess\TrayDigita\Routing\RouteRunner;
-use ArrayAccess\TrayDigita\Traits\Http\ResponseFactoryTrait;
-use ArrayAccess\TrayDigita\Traits\Manager\ManagerAllocatorTrait;
-use ArrayAccess\TrayDigita\Traits\Service\CallStackTraceTrait;
-use ArrayAccess\TrayDigita\Util\Filter\Consolidation;
-use ArrayAccess\TrayDigita\Util\Filter\ContainerHelper;
-use Psr\Container\ContainerInterface;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\MiddlewareInterface;
-use Throwable;
-use function memory_get_usage;
-use function microtime;
-use function spl_object_hash;
-use function strtoupper;
-
-/**
- * @mixin RouterInterface
- */
-class HttpKernel implements
- HttpKernelInterface,
- TerminableInterface,
- ManagerAllocatorInterface
+class HttpKernel extends AbstractHttpKernel
{
- use ResponseFactoryTrait,
- ManagerAllocatorTrait,
- CallStackTraceTrait;
-
- private MiddlewareDispatcherInterface $middlewareDispatcher;
-
- private ContainerInterface $container;
-
- private RouterInterface $router;
-
- private ?ResponseInterface $lastResponse = null;
-
- private ?ServerRequestInterface $lastRequest = null;
-
- /**
- * Start memory @uses memory_get_usage()
- * @var int
- */
- private int $startMemory;
-
- /**
- * Start time @uses microtime(true)
- * @var float
- */
- private float $startTime;
-
- /**
- * @var array
- */
- private array $deferredMiddlewares = [];
-
- public function __construct(
- ContainerInterface $container = null,
- ManagerInterface $manager = null
- ) {
- $this->startTime = microtime(true);
- $this->startMemory = memory_get_usage();
-
- $container ??= (new ContainerFactory())->createDefault();
- $this->container = $container;
- $manager ??= ContainerHelper::use(ManagerInterface::class, $container);
- if (!$manager) {
- $container->remove(ManagerInterface::class);
- $manager = new Manager();
- $container->set(ManagerInterface::class, $manager);
- }
- $this->managerObject = $manager;
- $this->container->set(HttpKernelInterface::class, fn () => $this);
-
- // router
- $definitions = [
- RouterInterface::class => Router::class,
- MiddlewareDispatcherInterface::class => MiddlewareDispatcher::class,
- RouteRunnerInterface::class => RouteRunner::class,
- ];
-
- foreach ($definitions as $key => $item) {
- try {
- if (!$container->has($key)) {
- $container->set($key, $item);
- }
- } catch (Throwable) {
- }
- }
-
- $this->router = ContainerHelper::service(RouterInterface::class, $container);
- $this->middlewareDispatcher = ContainerHelper::service(MiddlewareDispatcherInterface::class, $container);
- }
-
- public function getStartMemory(): int
- {
- return $this->startMemory;
- }
-
- public function getStartTime(): float
- {
- return $this->startTime;
- }
-
- public function getContainer(): ContainerInterface
- {
- return $this->container;
- }
-
- public function getRouter(): RouterInterface
- {
- return $this->router;
- }
-
- public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
- {
- return $this->middlewareDispatcher;
- }
-
- public function getManager(): ManagerInterface
- {
- return $this->managerObject;
- }
-
- public function addMiddleware(MiddlewareInterface $middleware): static
- {
- $this->getMiddlewareDispatcher()->addMiddleware($middleware);
- return $this;
- }
-
- public function addDeferredMiddleware(MiddlewareInterface $middleware): static
- {
- $priority = $middleware instanceof AbstractMiddleware
- ? $middleware->getPriority()
- : 10;
- $this->deferredMiddlewares[$priority][] = $middleware;
- return $this;
- }
-
- public function getDeferredMiddlewares() : array
- {
- return $this->deferredMiddlewares;
- }
-
- public function clearDeferredMiddlewares(): void
- {
- $this->deferredMiddlewares = [];
- }
-
- public function getLastResponse(): ?ResponseInterface
- {
- return $this->lastResponse;
- }
-
- public function getLastRequest(): ?ServerRequestInterface
- {
- return $this->lastRequest;
- }
-
- public function handle(ServerRequestInterface $request) : ResponseInterface
- {
- $this->assertCallstack();
- if ($this->lastResponse
- && $this->lastRequest
- && spl_object_hash($request) === spl_object_hash($this->lastRequest)
- ) {
- $this->resetCallstack();
- return $this->lastResponse;
- }
-
- $manager = $this->getManager();
- $manager->dispatch(
- 'httpKernel.beforeHandle',
- $this
- );
-
- try {
- $this->lastRequest = $request;
- // add middleware
- $this->lastResponse = $this->getMiddlewareDispatcher()->handle($request);
-
- /**
- * This is to be in compliance with RFC 2616, Section 9.
- * If the incoming request method is HEAD, we need to ensure that the response body
- * is empty as the request may fall back on a GET route handler due to FastRoute's
- * routing logic which could potentially append content to the response body
- * https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
- */
- $method = strtoupper($request->getMethod());
- if ($method === 'HEAD'
- // also empty on cli
- || $method === 'CLI'
- ) {
- $emptyBody = $this->getResponseFactory()->createResponse()->getBody();
- $this->lastResponse = $this->lastResponse->withBody($emptyBody);
- }
- $manager->dispatch(
- 'httpKernel.handle',
- $this,
- $this->lastResponse
- );
- $this->resetCallstack();
- return $this->lastResponse;
- } finally {
- $manager->dispatch(
- 'httpKernel.afterHandle',
- $this
- );
- }
- }
-
- public function dispatchResponse(ResponseInterface $response): ResponseInterface
- {
- $this->assertCallstack();
-
- $manager = $this->getManager();
- // @dispatch(httpKernel.beforeDispatch)
- $manager->dispatch(
- 'httpKernel.beforeDispatch',
- $this,
- $response
- );
-
- /**
- * @var Container $container
- */
- $container = $this->getContainer();
- $doEmit = ! Consolidation::isCli() || $manager->dispatch(
- 'httpKernel.emitResponse',
- false
- ) === true;
- $emitter = ContainerHelper::service(ResponseEmitterInterface::class, $container)
- ?? new ResponseEmitter();
- if ($emitter->isClosed()) {
- throw new UnProcessableException(
- 'Emitter has been closed.'
- );
- }
-
- // @dispatch(httpKernel.dispatch)
- $newResponse = $manager->dispatch('httpKernel.dispatch', $response);
- if ($newResponse instanceof ResponseInterface) {
- $response = $newResponse;
- }
-
- // @dispatch(response.final)
- $newResponse = $manager->dispatch('response.final', $response);
- if ($newResponse instanceof ResponseInterface) {
- $response = $newResponse;
- }
-
- // @dispatch(httpKernel.afterDispatch)
- $manager->dispatch(
- 'httpKernel.afterDispatch',
- $this,
- $response
- );
-
- if ($doEmit) {
- $reduceError = (bool) $manager
- ->dispatch('response.reduceError', true);
- $sendPreviousBuffer = (bool) $manager
- ->dispatch('response.sendPreviousBuffer', true);
- $emitter->emit($response, $reduceError, $sendPreviousBuffer);
- }
-
- // @dispatch(httpKernel.afterDispatch)
- $manager->dispatch(
- 'httpKernel.dispatched',
- $this,
- $response
- );
-
- $this->resetCallstack();
-
- return $response;
- }
-
- public function run(ServerRequestInterface $request) : ResponseInterface
- {
- return $this->dispatchResponse($this->handle($request));
- }
-
- public function terminate(ServerRequestInterface $request, ResponseInterface $response): void
- {
- $this->assertCallstack();
- $manager = $this->getManager();
- // @dispatch(httpKernel.terminate)
- $manager
- ->dispatch(
- 'httpKernel.beforeTerminate',
- $this,
- $request,
- $response
- );
- try {
- $manager->dispatch(
- 'httpKernel.terminate',
- $this,
- $request,
- $response
- );
- /*
- * @var Container $container
- $container = $this->getContainer();
- if (!$container->has(ResponseEmitterInterface::class)) {
- return;
- }
- try {
- $emitter = $container->get(ResponseEmitterInterface::class);
- !$emitter->isClosed() && $emitter->close();
- } catch (Throwable) {
- }*/
- } finally {
- $manager->dispatch(
- 'httpKernel.afterTerminate',
- $this,
- $request,
- $response
- );
- $this->resetCallstack();
- }
- }
-
- public function __call(string $name, array $arguments)
- {
- return $this->getRouter()->$name(...$arguments);
- }
-
- public function __debugInfo(): ?array
- {
- return Consolidation::debugInfo(
- $this,
- excludeKeys: [
- 'router',
- 'lastResponse',
- 'lastRequest'
- ]
- );
- }
}
diff --git a/src/Lang/default.pot b/src/Lang/default.pot
index f9cf6cb..eeb0c89 100644
--- a/src/Lang/default.pot
+++ b/src/Lang/default.pot
@@ -2,7 +2,7 @@
msgid ""
msgstr ""
"Project-Id-Version: TrayDigita 1.0.0\n"
-"POT-Creation-Date: 2023-10-21 03:07+0700\n"
+"POT-Creation-Date: 2023-10-22 02:40+0700\n"
"PO-Revision-Date: 2023-09-24 19:00+0700\n"
"Last-Translator: ArrayAccess\n"
"Language-Team: ArrayAccess\n"
@@ -1905,7 +1905,7 @@ msgctxt "chunk-uploader"
msgid "Directory %s is not writable"
msgstr ""
-#: Uploader/ChunkHandler.php:119 Uploader/ChunkProcessor.php:223
+#: Uploader/ChunkHandler.php:118 Uploader/ChunkProcessor.php:223
#, php-format
msgctxt "chunk-uploader"
msgid "Request id \"%s\" is not valid"
@@ -1916,44 +1916,44 @@ msgctxt "chunk-uploader"
msgid "Cache upload storage is not writable."
msgstr ""
-#: Uploader/ChunkHandler.php:280
+#: Uploader/ChunkHandler.php:281
msgctxt "chunk-uploader"
msgid "Upload cache file is not writable."
msgstr ""
-#: Uploader/ChunkHandler.php:294
+#: Uploader/ChunkHandler.php:295
msgctxt "chunk-uploader"
msgid "Can not create cached stream."
msgstr ""
-#: Uploader/ChunkHandler.php:305
+#: Uploader/ChunkHandler.php:306
msgctxt "chunk-uploader"
msgid "Cache file has been locked."
msgstr ""
-#: Uploader/ChunkHandler.php:417
+#: Uploader/ChunkHandler.php:420
msgctxt "chunk-uploader"
msgid "Offset upload position is invalid."
msgstr ""
-#: Uploader/ChunkHandler.php:451
+#: Uploader/ChunkHandler.php:454
msgctxt "chunk-uploader"
msgid "Source uploaded file does not exist."
msgstr ""
-#: Uploader/ChunkHandler.php:471
+#: Uploader/ChunkHandler.php:474
#, php-format
msgctxt "chunk-uploader"
msgid "Upload cache file is not ready to move : (%d)."
msgstr ""
-#: Uploader/ChunkHandler.php:520
+#: Uploader/ChunkHandler.php:523
#, php-format
msgctxt "chunk-uploader"
msgid "Target file \"%s\" is not writable."
msgstr ""
-#: Uploader/ChunkHandler.php:540
+#: Uploader/ChunkHandler.php:543
#, php-format
msgctxt "chunk-uploader"
msgid "Target directory \"%s\" is not writable."
diff --git a/src/Lang/id.po b/src/Lang/id.po
index a30642b..0219a0f 100644
--- a/src/Lang/id.po
+++ b/src/Lang/id.po
@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: TrayDigita 1.0.0\n"
-"POT-Creation-Date: 2023-10-21 03:07+0700\n"
-"PO-Revision-Date: 2023-10-21 03:07+0700\n"
+"POT-Creation-Date: 2023-10-22 02:40+0700\n"
+"PO-Revision-Date: 2023-10-22 02:40+0700\n"
"Last-Translator: \n"
"Language-Team: ArrayAccess\n"
"Language: id\n"
@@ -1973,7 +1973,7 @@ msgctxt "chunk-uploader"
msgid "Directory %s is not writable"
msgstr "Direktori %s tidak dapat ditulisi"
-#: Uploader/ChunkHandler.php:119 Uploader/ChunkProcessor.php:223
+#: Uploader/ChunkHandler.php:118 Uploader/ChunkProcessor.php:223
#, php-format
msgctxt "chunk-uploader"
msgid "Request id \"%s\" is not valid"
@@ -1984,44 +1984,44 @@ msgctxt "chunk-uploader"
msgid "Cache upload storage is not writable."
msgstr "Direktori penyimpanan cache tidak dapat ditulisi."
-#: Uploader/ChunkHandler.php:280
+#: Uploader/ChunkHandler.php:281
msgctxt "chunk-uploader"
msgid "Upload cache file is not writable."
msgstr "Berkas cache unggahan tidak dapat ditulisi."
-#: Uploader/ChunkHandler.php:294
+#: Uploader/ChunkHandler.php:295
msgctxt "chunk-uploader"
msgid "Can not create cached stream."
msgstr "Tidak dapat membuat cached stream."
-#: Uploader/ChunkHandler.php:305
+#: Uploader/ChunkHandler.php:306
msgctxt "chunk-uploader"
msgid "Cache file has been locked."
msgstr "Berkas cache terkunci."
-#: Uploader/ChunkHandler.php:417
+#: Uploader/ChunkHandler.php:420
msgctxt "chunk-uploader"
msgid "Offset upload position is invalid."
msgstr "Posisi offset unggahan tidak sah."
-#: Uploader/ChunkHandler.php:451
+#: Uploader/ChunkHandler.php:454
msgctxt "chunk-uploader"
msgid "Source uploaded file does not exist."
msgstr "Berkas sumber yang diunggah tidak ada."
-#: Uploader/ChunkHandler.php:471
+#: Uploader/ChunkHandler.php:474
#, php-format
msgctxt "chunk-uploader"
msgid "Upload cache file is not ready to move : (%d)."
msgstr "Berkas cache yang diunggah belum siap dipindahkan : (%d)."
-#: Uploader/ChunkHandler.php:520
+#: Uploader/ChunkHandler.php:523
#, php-format
msgctxt "chunk-uploader"
msgid "Target file \"%s\" is not writable."
msgstr "Berkas tujuan \"%s\" tidak dapat ditulisi."
-#: Uploader/ChunkHandler.php:540
+#: Uploader/ChunkHandler.php:543
#, php-format
msgctxt "chunk-uploader"
msgid "Target directory \"%s\" is not writable."
diff --git a/src/Middleware/AbstractMiddleware.php b/src/Middleware/AbstractMiddleware.php
index efba074..506d390 100644
--- a/src/Middleware/AbstractMiddleware.php
+++ b/src/Middleware/AbstractMiddleware.php
@@ -3,8 +3,8 @@
namespace ArrayAccess\TrayDigita\Middleware;
-use ArrayAccess\TrayDigita\Container\Container;
use ArrayAccess\TrayDigita\Container\ContainerWrapper;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Container\Interfaces\ContainerIndicateInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerIndicateInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
@@ -51,9 +51,9 @@ public function getManager(): ?ManagerInterface
}
/**
- * @return ContainerInterface|Container
+ * @return ContainerInterface|SystemContainerInterface
*/
- public function getContainer(): ContainerInterface|Container
+ public function getContainer(): ContainerInterface|SystemContainerInterface
{
return $this->container;
}
diff --git a/src/PossibleRoot.php b/src/PossibleRoot.php
index cd0b69d..eade98e 100644
--- a/src/PossibleRoot.php
+++ b/src/PossibleRoot.php
@@ -60,9 +60,9 @@ public static function getPossibleRootDirectory()
$config = json_decode(file_get_contents($composerJson), true);
$config = is_array($config) ? $config : [];
$config = isset($config['config']) ? $config['config'] : [];
- $vendorDir = isset($config['vendor-dir']) ? $config['vendor-dir'] : null;
- if ($vendorDir && file_exists("$root/$vendorDir/autoload.php")) {
- require "$root/$vendorDir/autoload.php";
+ $vendorDirectory = isset($config['vendor-dir']) ? $config['vendor-dir'] : null;
+ if ($vendorDirectory && file_exists("$root/$vendorDirectory/autoload.php")) {
+ require "$root/$vendorDirectory/autoload.php";
}
}
}
@@ -119,8 +119,8 @@ public static function getPossibleRootDirectory()
$config = is_array($config) ? $config : [];
$config = isset($config['config']) ? $config['config'] : [];
}
- $vendorDir = isset($config['vendor-dir']) ? $config['vendor-dir'] : null;
- if (!is_string($vendorDir) || ! is_dir("$root/$vendorDir")) {
+ $vendorDirectory = isset($config['vendor-dir']) ? $config['vendor-dir'] : null;
+ if (!is_string($vendorDirectory) || ! is_dir("$root/$vendorDirectory")) {
$root = dirname(TD_APP_DIRECTORY);
}
self::$composerJsonConfig[$composerJson] = $root;
diff --git a/src/Responder/FileResponder.php b/src/Responder/FileResponder.php
index 8c63d78..b5f9590 100644
--- a/src/Responder/FileResponder.php
+++ b/src/Responder/FileResponder.php
@@ -56,7 +56,7 @@ class FileResponder implements FileResponderInterface
const DEFAULT_MIMETYPE = 'application/octet-stream';
- protected string $fileName;
+ protected string $attachmentFileName;
protected int $size;
@@ -66,6 +66,8 @@ class FileResponder implements FileResponderInterface
protected bool $sendRealMimeType = true;
+ protected bool $sendContentLength = true;
+
protected bool $allowRange = true;
protected int $maxRanges = 100;
@@ -92,7 +94,7 @@ public function __construct(SplFileInfo|string $file)
$file = new SplFileInfo($file);
}
$this->file = $file;
- $this->fileName = $this->file->getBasename();
+ $this->attachmentFileName = $this->file->getBasename();
$this->size = $this->valid() ? $this->file->getSize() : 0;
}
@@ -136,14 +138,29 @@ public function isSendAsAttachment(): bool
return $this->sendAsAttachment;
}
- public function setFileName(string $fileName): void
+ public function isSendContentLength(): bool
{
- $this->fileName = $fileName;
+ return $this->sendContentLength;
+ }
+
+ public function sendContentLength(bool $enable): void
+ {
+ $this->sendContentLength = $enable;
+ }
+
+ public function setAttachmentFileName(string $fileName): void
+ {
+ $this->attachmentFileName = $fileName;
+ }
+
+ public function getAttachmentFileName(): string
+ {
+ return $this->attachmentFileName;
}
public function resetFileName(): void
{
- $this->fileName = $this->getFile()->getBasename();
+ $this->attachmentFileName = $this->getFile()->getBasename();
}
public function sendRealMimeType(bool $enable): void
@@ -174,14 +191,6 @@ public function getBoundary(): string
return $this->boundary ??= md5(RandomString::bytes(16));
}
- public function sendLastModified(): bool
- {
- return $this->sendHeader(
- 'Last-Modified',
- gmdate('Y-m-d H:i:s \G\M\T')
- );
- }
-
/**
* @return ?string
*/
@@ -202,42 +211,6 @@ public function getEtag(): ?string
return $this->eTag = sprintf('%x-%x', $time, $size);
}
- public function send(?ServerRequestInterface $request = null): never
- {
- $request ??= ServerRequest::fromGlobals(
- Decorator::service(ServerRequestFactoryInterface::class),
- Decorator::service(StreamFactoryInterface::class),
- );
- $method = strtoupper($request->getMethod());
- if (!in_array($method, self::ALLOWED_METHODS)) {
- $exceptions = new MethodNotAllowedException(
- $request
- );
- $exceptions->setAllowedMethods(self::ALLOWED_METHODS);
- throw $exceptions;
- }
- if (!$this->valid()) {
- throw new SourceFileFailException(
- $this->file->getPathname(),
- sprintf(
- 'File %s is not valid',
- $this->file
- )
- );
- }
- // remove all buffer
- $count = 5;
- while (--$count > 0 && ob_get_level() > 0) {
- ob_end_clean();
- }
- if (headers_sent()) {
- throw new HttpRuntimeException(
- 'Header already sent'
- );
- }
- $this->sendData($request);
- }
-
/**
* @param string $name
* @param string|int|float $value
@@ -267,12 +240,24 @@ private function sendHeader(
return true;
}
+ public function sendHeaderLastModified(): bool
+ {
+ if (!$this->isSendLastModifiedTime()) {
+ return false;
+ }
+
+ return $this->sendHeader(
+ 'Last-Modified',
+ gmdate('Y-m-d H:i:s \G\M\T')
+ );
+ }
+
/**
* @param string|array|null $cacheType
* @param int|null $maxAge
* @return bool
*/
- public function sendCacheHeader(
+ public function sendHeaderCache(
string|array|null $cacheType = null,
?int $maxAge = null
) : bool {
@@ -296,7 +281,7 @@ public function sendCacheHeader(
*
* @return bool
*/
- public function sendAcceptRanges(): bool
+ public function sendHeaderAcceptRanges(): bool
{
return $this->sendHeader(
'Accept-Ranges',
@@ -306,50 +291,116 @@ public function sendAcceptRanges(): bool
);
}
- public function sendContentLength(int $length): bool
+ public function sendHeaderContentLength(int $length): bool
{
+ if (!$this->isSendContentLength()) {
+ return false;
+ }
return $this->sendHeader('Content-Length', $length);
}
- public function sendEtag(): bool
+ public function sendHeaderEtag(): bool
{
$etag = $this->getEtag();
return $etag && $this->sendHeader('Etag', $etag);
}
- public function sendContentType(string $contentType, int $code = 0): bool
+ public function sendHeaderContentType($contentType, int $code = 0): bool
{
return $this->sendHeader('Content-Type', $contentType, $code);
}
- public function sendRangeNotSatisfy() : never
+ public function getDetermineMimeType(): ?string
+ {
+ if ($this->isSendRealMimeType()) {
+ $mimeType = MimeType::fileMimeType($this->file->getRealPath());
+ } else {
+ $mimeType = MimeType::mime($this->file->getExtension());
+ }
+ return $mimeType;
+ }
+
+ public function sendHeaderMimeType(): bool
+ {
+ $mimeType = $this->getDetermineMimeType();
+ return $mimeType && $this->sendHeader('Content-Type', $mimeType);
+ }
+
+ /**
+ * @return bool
+ */
+ public function sendHeaderAttachment() : bool
+ {
+ if (!$this->isSendAsAttachment()) {
+ return false;
+ }
+ return $this->sendHeader(
+ 'Content-Disposition',
+ sprintf(
+ 'attachment; filename="%s"',
+ rawurlencode($this->getAttachmentFileName())
+ )
+ );
+ }
+
+ public function displayRangeNotSatisfy() : never
{
- $this->sendContentType('text/html', 416);
+ $this->sendHeaderContentType('text/html', 416);
$this->sendHeader('Content-Range', 'bytes */'.$this->size);
$this->stopRequest();
}
- private function sendData(ServerRequestInterface $request) : never
+ public function send(?ServerRequestInterface $request = null): never
+ {
+ $request ??= ServerRequest::fromGlobals(
+ Decorator::service(ServerRequestFactoryInterface::class),
+ Decorator::service(StreamFactoryInterface::class),
+ );
+ $method = strtoupper($request->getMethod());
+ if (!in_array($method, self::ALLOWED_METHODS)) {
+ $exceptions = new MethodNotAllowedException(
+ $request
+ );
+ $exceptions->setAllowedMethods(self::ALLOWED_METHODS);
+ throw $exceptions;
+ }
+ if (!$this->valid()) {
+ throw new SourceFileFailException(
+ $this->file->getPathname(),
+ sprintf(
+ 'File %s is not valid',
+ $this->file
+ )
+ );
+ }
+ // remove all buffer
+ $count = 5;
+ while (--$count > 0 && ob_get_level() > 0) {
+ ob_end_clean();
+ }
+ if (headers_sent()) {
+ throw new HttpRuntimeException(
+ 'Header already sent'
+ );
+ }
+ $this->sendRequestData($request);
+ }
+
+ private function sendRequestData(ServerRequestInterface $request) : never
{
// remove x-powered-by php
header_remove('X-Powered-By');
$method = strtoupper($request->getMethod());
if ($method === 'OPTIONS') {
- $this->sendContentType('text/html');
+ $this->sendHeaderContentType('text/html');
// just allow options get head post only
- $this->sendAcceptRanges();
+ $this->sendHeaderAcceptRanges();
// 604800 is 1 week
- $this->sendCacheHeader(maxAge: 604800);
+ $this->sendHeaderCache(maxAge: 604800);
$this->sendHeader('Allow', implode(', ', self::ALLOWED_METHODS));
exit(0);
}
- // get mime types
- if ($this->isSendRealMimeType()) {
- $mimeType = MimeType::fileMimeType($this->file->getRealPath());
- } else {
- $mimeType = MimeType::mime($this->file->getExtension());
- }
$fileSize = $this->size;
$rangeHeader = trim($request->getHeaderLine('Range'));
@@ -364,6 +415,8 @@ private function sendData(ServerRequestInterface $request) : never
/**
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
*/
+ // get mime types
+ $mimeType = $this->getDetermineMimeType();
$rangeMimeType = $mimeType??self::DEFAULT_MIMETYPE;
$totalRanges = 0;
$maxRanges = $this->getMaxRanges();
@@ -384,7 +437,7 @@ private function sendData(ServerRequestInterface $request) : never
if (($start === '' && $end === '')) {
// stop
- $this->sendRangeNotSatisfy();
+ $this->displayRangeNotSatisfy();
}
$start = $start === '' ? 0 : $start;
@@ -399,7 +452,7 @@ private function sendData(ServerRequestInterface $request) : never
$headers = null;
$ranges = null;
// stop
- $this->sendRangeNotSatisfy();
+ $this->displayRangeNotSatisfy();
}
$start = (int) $start;
@@ -457,13 +510,8 @@ private function sendData(ServerRequestInterface $request) : never
// $this->sendAcceptRanges();
// if only 1 or empty ranges
if (($empty = empty($ranges)) || $totalRanges === 1) {
- if ($mimeType) {
- $this->sendContentType($mimeType);
- }
-
// send cache
// $this->sendCacheHeader(['public', 'must-revalidate'], maxAge: 604800);
-
$startingPoint = 0;
// if ranges
if (!$empty) {
@@ -477,14 +525,18 @@ private function sendData(ServerRequestInterface $request) : never
}
}
// set content length
- $this->sendContentLength($total);
-
- if ($this->isSendLastModifiedTime()) {
- $this->sendLastModified();
- }
+ $this->sendHeaderContentLength($total);
+ // send mimetype header
+ $this->sendHeaderMimeType();
+ // send etag
+ $this->sendHeaderEtag();
+ // send last modifier
+ $this->sendHeaderLastModified();
+ // send attachment header
+ $this->sendHeaderAttachment();
// set etag
- $this->sendEtag();
+ $this->sendHeaderEtag();
if ($method === 'HEAD') {
$this->stopRequest();
}
@@ -503,21 +555,23 @@ private function sendData(ServerRequestInterface $request) : never
}
if (!$this->isAllowRange()) {
- $this->sendRangeNotSatisfy();
+ $this->displayRangeNotSatisfy();
}
// get socket
$sock = $this->getSock();
// send boundary and status code -> partial content 206
- $this->sendContentType("multipart/byteranges; boundary=$boundary", 206);
+ $this->sendHeaderContentType("multipart/byteranges; boundary=$boundary", 206);
// send range total
- $this->sendContentLength($rangeTotal);
+ $this->sendHeaderContentLength($rangeTotal);
// send etag
- $this->sendEtag();
- if ($this->isSendLastModifiedTime()) {
- $this->sendLastModified();
- }
+ $this->sendHeaderEtag();
+ // send last modifier
+ $this->sendHeaderLastModified();
+ // send attachment header
+ $this->sendHeaderAttachment();
+
// no process if method header
if ($method === 'HEAD') {
$this->stopRequest();
diff --git a/src/Responder/Interfaces/FileResponderInterface.php b/src/Responder/Interfaces/FileResponderInterface.php
index ecf0e73..34c72d7 100644
--- a/src/Responder/Interfaces/FileResponderInterface.php
+++ b/src/Responder/Interfaces/FileResponderInterface.php
@@ -15,9 +15,18 @@ public function getFile() : SplFileInfo;
public function valid() : bool;
public function setAllowRange(bool $enable);
+
public function isAllowRange() : bool;
- public function setFileName(string $fileName);
+ public function setMaxRanges(int $ranges);
+ /**
+ * @return int
+ */
+ public function getMaxRanges() : int;
+
+ public function setAttachmentFileName(string $fileName);
+
+ public function getAttachmentFileName();
public function resetFileName();
@@ -32,12 +41,10 @@ public function isSendAsAttachment(): bool;
public function sendRealMimeType(bool $enable);
public function isSendRealMimeType(): bool;
- public function setMaxRanges(int $ranges);
- /**
- * @return int
- */
- public function getMaxRanges() : int;
+ public function sendContentLength(bool $enable);
+
+ public function isSendContentLength(): bool;
public function getBoundary(): string;
diff --git a/src/Routing/AbstractController.php b/src/Routing/AbstractController.php
index 903e046..89d335d 100644
--- a/src/Routing/AbstractController.php
+++ b/src/Routing/AbstractController.php
@@ -3,8 +3,8 @@
namespace ArrayAccess\TrayDigita\Routing;
-use ArrayAccess\TrayDigita\Container\Container;
use ArrayAccess\TrayDigita\Container\ContainerWrapper;
+use ArrayAccess\TrayDigita\Container\Interfaces\SystemContainerInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerAllocatorInterface;
use ArrayAccess\TrayDigita\Event\Interfaces\ManagerInterface;
use ArrayAccess\TrayDigita\Http\Code;
@@ -22,7 +22,6 @@
use ArrayAccess\TrayDigita\Util\Filter\ContainerHelper;
use ArrayAccess\TrayDigita\Util\Filter\DataType;
use JsonSerializable;
-use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
@@ -54,7 +53,7 @@ abstract class AbstractController implements ControllerInterface
private ?ResponseInterface $response = null;
- protected ?ContainerInterface $container = null;
+ protected ?SystemContainerInterface $container = null;
protected ?ManagerInterface $manager = null;
@@ -64,8 +63,9 @@ abstract class AbstractController implements ControllerInterface
final public function __construct(public readonly RouterInterface $router)
{
- $this->container = $this->router->getContainer();
- if ($this->container && $this instanceof ManagerAllocatorInterface) {
+ $container = $this->router->getContainer();
+ $this->container = $container ? ContainerWrapper::maybeContainerOrCreate($container) : null;
+ if ($this instanceof ManagerAllocatorInterface) {
$manager = ContainerHelper::use(ManagerInterface::class, $this->container);
if ($manager) {
$this->setManager($manager);
@@ -161,10 +161,10 @@ public function renderJson(
);
}
- public function getContainer(): ContainerInterface|Container|null
+ public function getContainer(): SystemContainerInterface|null
{
if (!$this->container && ($container = $this->router->getContainer())) {
- $this->container = $container;
+ $this->container = ContainerWrapper::maybeContainerOrCreate($container);
}
return $this->container;
}
diff --git a/src/Templates/Wrapper.php b/src/Templates/Wrapper.php
index 4589521..6f2d952 100644
--- a/src/Templates/Wrapper.php
+++ b/src/Templates/Wrapper.php
@@ -15,19 +15,19 @@ final class Wrapper
/**
* @param ViewInterface $view
- * @param string $publicDir
+ * @param string $publicDirectory
* @param string $templatesPath
*/
public function __construct(
public readonly ViewInterface $view,
- string $publicDir,
+ string $publicDirectory,
string $templatesPath = 'templates'
) {
$this->templatePath = ltrim(
DataNormalizer::normalizeDirectorySeparator($templatesPath, true),
DIRECTORY_SEPARATOR
);
- $this->publicDirectory = DataNormalizer::normalizeDirectorySeparator($publicDir, true);
+ $this->publicDirectory = DataNormalizer::normalizeDirectorySeparator($publicDirectory, true);
}
public function getView(): ViewInterface
diff --git a/src/Traits/Service/CallStackTraceTrait.php b/src/Traits/Service/CallStackTraceTrait.php
index 876abf3..cc8beab 100644
--- a/src/Traits/Service/CallStackTraceTrait.php
+++ b/src/Traits/Service/CallStackTraceTrait.php
@@ -13,7 +13,7 @@ trait CallStackTraceTrait
{
const MAX_CALLSTACK = 256;
- private array $callStackIncrement = [];
+ protected array $callStackIncrement = [];
private function getInternalCallStackName() : ?string
{
diff --git a/src/Uploader/Chunk.php b/src/Uploader/Chunk.php
index 14b0aaa..0f1cda5 100644
--- a/src/Uploader/Chunk.php
+++ b/src/Uploader/Chunk.php
@@ -89,18 +89,18 @@ class Chunk implements ManagerAllocatorInterface, ContainerIndicateInterface
public function __construct(
protected ContainerInterface $container,
- ?string $storageDir = null
+ ?string $storageDirectory = null
) {
- if ($storageDir === null) {
+ if ($storageDirectory === null) {
$config = ContainerHelper::service(Config::class);
$path = $config?->get('path');
$storageDirectory = $path instanceof Config
? $path->get('storage')
: null;
- if (is_string($storageDirectory)
- && is_dir($storageDirectory)
+ if (!is_string($storageDirectory)
+ || !is_dir($storageDirectory)
) {
- $storageDir = $storageDirectory;
+ $storageDirectory = null;
}
}
$manager = ContainerHelper::use(
@@ -112,10 +112,10 @@ public function __construct(
}
$this->partialExtension = 'partial';
$this->partialMetaExtension = $this->partialExtension . '.meta';
- $storageDir = $storageDir??sys_get_temp_dir();
- $this->assertDirectory($storageDir);
- $storageDir = (realpath($storageDir)??$storageDir);
- $this->uploadCacheStorageDirectory = $storageDir
+ $storageDirectory = $storageDirectory??sys_get_temp_dir();
+ $this->assertDirectory($storageDirectory);
+ $storageDirectory = (realpath($storageDirectory)??$storageDirectory);
+ $this->uploadCacheStorageDirectory = $storageDirectory
. DIRECTORY_SEPARATOR
. self::SUFFIX_STORAGE_DIRECTORY;
$this->maxUploadFileSize = Consolidation::getMaxUploadSize();
diff --git a/src/Util/Filter/Consolidation.php b/src/Util/Filter/Consolidation.php
index 4b59796..5f48486 100644
--- a/src/Util/Filter/Consolidation.php
+++ b/src/Util/Filter/Consolidation.php
@@ -425,7 +425,7 @@ public static function namespace(string|object $fullClassName) : string|false
public static function isValidClassName(string $className) : bool
{
return (bool) preg_match(
- '~^\\\?[A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*(\\\[A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*)*$~',
+ '~^\\\?[A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*(?:\\\[A-Z-a-z_\x80-\xff]+[A-Z-a-z_0-9\x80-\xff]*)*$~',
$className
);
}
diff --git a/src/Util/Parser/PhpClassParserSerial.php b/src/Util/Parser/PhpClassParserSerial.php
index d8b846b..3974470 100644
--- a/src/Util/Parser/PhpClassParserSerial.php
+++ b/src/Util/Parser/PhpClassParserSerial.php
@@ -43,12 +43,13 @@ private function __construct(string $source)
public static function fromSource(string $source): PhpClassParserSerial
{
$source = trim($source);
- if ($source || !preg_match('~^\s*<\?php~i', $source)) {
+ if (!$source || !preg_match('~^<\?php~i', $source)) {
unset($source);
throw new UnsupportedArgumentException(
'The source maybe is not php class file',
);
}
+
return new self($source);
}
diff --git a/src/View/Engines/TwigEngine.php b/src/View/Engines/TwigEngine.php
index de640d4..05296f3 100644
--- a/src/View/Engines/TwigEngine.php
+++ b/src/View/Engines/TwigEngine.php
@@ -131,7 +131,7 @@ public function clearVariableCache(): void
}
$loader = $this->twig?->getLoader();
- $viewsDir = $this->getFilteredViewsDir();
+ $viewsDirectory = $this->getFilteredViewsDir();
parent::clearVariableCache();
if ($loader instanceof FilesystemLoader) {
$paths = $loader->getPaths();
@@ -144,7 +144,7 @@ public function clearVariableCache(): void
if ($templateRule && str_starts_with($path, $templateRule)) {
continue;
}
- if (!in_array($path, $viewsDir) && !in_array($path, $currentPaths)) {
+ if (!in_array($path, $viewsDirectory) && !in_array($path, $currentPaths)) {
$currentPaths[] = $path;
}
}
diff --git a/src/View/ErrorRenderer/HtmlTraceAbleErrorRenderer.php b/src/View/ErrorRenderer/HtmlTraceAbleErrorRenderer.php
index de29e6d..31b2c86 100644
--- a/src/View/ErrorRenderer/HtmlTraceAbleErrorRenderer.php
+++ b/src/View/ErrorRenderer/HtmlTraceAbleErrorRenderer.php
@@ -3,6 +3,7 @@
namespace ArrayAccess\TrayDigita\View\ErrorRenderer;
+use ArrayAccess\TrayDigita\Collection\Config;
use ArrayAccess\TrayDigita\Exceptions\Runtime\MaximumCallstackExceeded;
use ArrayAccess\TrayDigita\Http\Exceptions\HttpException;
use ArrayAccess\TrayDigita\Kernel\Interfaces\KernelInterface;
@@ -48,7 +49,12 @@ protected function format(
Throwable $exception,
bool $displayErrorDetails
): ?string {
- if ($displayErrorDetails) {
+ $config = ContainerHelper::getNull(
+ Config::class,
+ $this->getContainer()
+ )?->get('environment');
+ $isDebug = $config instanceof Config && $config->get('debug') === true;
+ if ($displayErrorDetails && $isDebug) {
try {
$kernel = ContainerHelper::use(KernelInterface::class, $this->getContainer());
$root = $kernel?->getRootDirectory()??PossibleRoot::getPossibleRootDirectory();
@@ -84,8 +90,8 @@ protected function format(
return $view->render(
$path,
[
- 'displayErrorDetails' => false,
- 'exception' => $exception
+ 'displayErrorDetails' => $displayErrorDetails,
+ 'exception' => $exception,
]
);
}
diff --git a/src/View/View.php b/src/View/View.php
index 11bc7bd..d9b5184 100644
--- a/src/View/View.php
+++ b/src/View/View.php
@@ -86,21 +86,21 @@ class View implements ViewInterface, ManagerAllocatorInterface
public function __construct(
protected ContainerInterface $container,
?ManagerInterface $manager = null,
- string|iterable $viewsDir = '',
+ string|iterable $viewsDirectory = '',
) {
$manager ??= ContainerHelper::service(ManagerInterface::class, $this->container);
$this->setManager($manager??Decorator::manager());
- if (empty($viewsDir)) {
+ if (empty($viewsDirectory)) {
$config = ContainerHelper::use(Config::class, $this->container);
$config = $config?->get('path')??null;
$config = $config instanceof Config ? $config : null;
$directory = $config?->get('view');
if ($directory) {
- $viewsDir = $directory;
+ $viewsDirectory = $directory;
}
}
- $this->setViewsDirectory($viewsDir);
+ $this->setViewsDirectory($viewsDirectory);
}
/**
diff --git a/src/Web.php b/src/Web.php
index 65afa30..09c51e8 100644
--- a/src/Web.php
+++ b/src/Web.php
@@ -53,7 +53,6 @@ final private function __construct()
* @return ResponseInterface|false
* @noinspection PhpMissingReturnTypeInspection
* @noinspection PhpIssetCanBeReplacedWithCoalesceInspection
- * @noinspection DuplicatedCode
*/
final public static function serve()
{
@@ -116,10 +115,10 @@ final public static function serve()
);
}
$publicFile = $publicFile ?: realpath(TD_INDEX_FILE);
- $publicDir = dirname($publicFile);
+ $publicDirectory = dirname($publicFile);
// HANDLE CLI-SERVER
if (php_sapi_name() === 'cli-server') {
- if ($_SERVER['DOCUMENT_ROOT'] !== $publicDir) {
+ if ($_SERVER['DOCUMENT_ROOT'] !== $publicDirectory) {
throw new RuntimeException(
"Builtin web server should be pointing into public root directory!"
);
@@ -141,7 +140,7 @@ final public static function serve()
|mp[34]|og[gvpa]|mpe?g|3gp|avi|mov|flac|flv|webm|wmv # media
)$~ix',
$requestUriNoQuery
- ) && is_file($publicDir . '/' . $requestUriNoQuery)) {
+ ) && is_file($publicDirectory . '/' . $requestUriNoQuery)) {
// serve the static assets with return : false
return $lastResult = false;
}
@@ -152,7 +151,7 @@ final public static function serve()
if (!defined('TD_APP_DIRECTORY')) {
// DEFINE : TD_APP_DIRECTORY
- define('TD_APP_DIRECTORY', dirname($publicDir) . DIRECTORY_SEPARATOR . 'app');
+ define('TD_APP_DIRECTORY', dirname($publicDirectory) . DIRECTORY_SEPARATOR . 'app');
}
/**
@@ -235,7 +234,10 @@ class_alias('Exception', 'Throwable');
) {
$config = ContainerHelper::use(Config::class, $kernel->getHttpKernel()->getContainer());
$config = $config->get('environment');
- $enable = $config instanceof Config && $config->get('displayErrorDetails') === true;
+ $enable = $config instanceof Config && (
+ $config->get('displayErrorDetails') === true
+ || $config->get('debug') === true
+ );
}
$additionalText = ! $enable ? "$message
" : <<$message