Skip to content
Merged
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ The format is based on Keep a Changelog.
- Added adapter-based Lang provider support with `DeepL` and `Google Translate` adapters plus shared remote request/caching infrastructure (#533)

### Changed
- **BREAKING:** Removed `Quantum\Loader` and moved its responsibilities to their owning packages (#535):
- Moved `Setup` to `Quantum\Config\Setup`; required config failures now use `ConfigException`, and optional imports use `Config::importIfExists()`.
- Config paths resolve from the application base directory, independent of the process working directory.
- `Environment::load()` no longer accepts `Setup`, reads only `shared/config/env.php`, and reports missing files with `EnvException`.
- App boot now loads component, app, and module helpers directly.
- Corrected cache adapter deserialization exception handling and `ModelCollection` key type declarations (#570)
- Refactored `HttpClient` internals behind explicit `CurlAdapter` and `MultiCurlAdapter` wrappers while preserving the existing facade methods and keeping `php-curl-class` as the underlying transport for this phase (#534)
- Replaced the single-request `HttpClient` `CurlAdapter` execution path with native PHP cURL (#566)
Expand Down
3 changes: 1 addition & 2 deletions src/App/Adapters/WebAppAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
namespace Quantum\App\Adapters;

use Quantum\Middleware\Exceptions\MiddlewareException;
use Quantum\Loader\Exceptions\LoaderException;
use Quantum\Config\Exceptions\ConfigException;
use Quantum\App\Stages\SetupErrorHandlerStage;
use Quantum\Router\Exceptions\RouteException;
Expand Down Expand Up @@ -63,7 +62,7 @@ public function __construct(AppContext $context)

/**
* Starts the web app
* @throws MiddlewareException|LangException|RouteException|CsrfException|ConfigException|DiException|BaseException|LoaderException|ReflectionException
* @throws MiddlewareException|LangException|RouteException|CsrfException|ConfigException|DiException|BaseException|ReflectionException
*/
public function start(): ?int
{
Expand Down
5 changes: 2 additions & 3 deletions src/App/Stages/LoadAppConfigStage.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@

use Quantum\App\Contracts\BootStageInterface;
use Quantum\Config\Exceptions\ConfigException;
use Quantum\Loader\Exceptions\LoaderException;
use Quantum\Di\Exceptions\DiException;
use Quantum\App\AppContext;
use Quantum\Loader\Setup;
use Quantum\Config\Setup;
use ReflectionException;

/**
Expand All @@ -25,7 +24,7 @@
class LoadAppConfigStage implements BootStageInterface
{
/**
* @throws LoaderException|ConfigException|DiException|ReflectionException
* @throws ConfigException|DiException|ReflectionException
*/
public function process(AppContext $context): void
{
Expand Down
6 changes: 2 additions & 4 deletions src/App/Stages/LoadEnvironmentStage.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
use Quantum\Di\Exceptions\DiException;
use Quantum\Environment\Environment;
use Quantum\App\AppContext;
use Quantum\Loader\Setup;
use ReflectionException;
use Quantum\Di\Di;

/**
Expand All @@ -27,13 +25,13 @@
class LoadEnvironmentStage implements BootStageInterface
{
/**
* @throws EnvException|DiException|BaseException|ReflectionException
* @throws EnvException|DiException|BaseException
*/
public function process(AppContext $context): void
{
$environment = new Environment();

$environment->load(new Setup('config', 'env'));
$environment->load();

Di::set(Environment::class, $environment);
}
Expand Down
44 changes: 22 additions & 22 deletions src/App/Stages/LoadHelpersStage.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,23 @@
namespace Quantum\App\Stages;

use Quantum\App\Contracts\BootStageInterface;
use Quantum\Di\Exceptions\DiException;
use Quantum\App\AppContext;
use Quantum\Loader\Loader;
use ReflectionException;
use Quantum\App\App;
use Quantum\Di\Di;

/**
* Class LoadHelpersStage
* @package Quantum\App
*/
class LoadHelpersStage implements BootStageInterface
{
/**
* @throws DiException|ReflectionException
*/
public function process(AppContext $context): void
{
if (!Di::isRegistered(Loader::class)) {
Di::register(Loader::class);
}

$loader = Di::get(Loader::class);

$this->loadComponentHelpers($loader);
$this->loadAppHelpers($loader);
$this->loadModuleHelpers($loader);
$this->loadComponentHelpers();
$this->loadAppHelpers();
$this->loadModuleHelpers();
}

private function loadComponentHelpers(Loader $loader): void
private function loadComponentHelpers(): void
{
$srcDir = dirname(__DIR__, 2);

Expand All @@ -49,18 +36,31 @@ private function loadComponentHelpers(Loader $loader): void
foreach (is_array($componentDirs) ? $componentDirs : [] as $componentDir) {
$helperPath = $componentDir . DS . 'Helpers';
if (is_dir($helperPath)) {
$loader->loadDir($helperPath);
$this->loadHelperFiles($helperPath);
}
}
}

private function loadAppHelpers(Loader $loader): void
private function loadAppHelpers(): void
{
$this->loadHelperFiles(App::getBaseDir() . DS . 'helpers');
}

private function loadModuleHelpers(): void
{
$loader->loadDir(App::getBaseDir() . DS . 'helpers');
$this->loadHelperFiles(App::getBaseDir() . DS . 'modules' . DS . '*' . DS . 'helpers');
}

private function loadModuleHelpers(Loader $loader): void
private function loadHelperFiles(string $dir): void
{
$loader->loadDir(App::getBaseDir() . DS . 'modules' . DS . '*' . DS . 'helpers');
$files = glob($dir . DS . '*.php');

if (!is_array($files)) {
return;
}

foreach ($files as $filename) {
require_once $filename;
}
}
}
11 changes: 5 additions & 6 deletions src/App/Traits/WebAppTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
namespace Quantum\App\Traits;

use Quantum\Config\Exceptions\ConfigException;
use Quantum\Loader\Exceptions\LoaderException;
use Quantum\Router\Exceptions\RouteException;
use Quantum\Lang\Exceptions\LangException;
use Quantum\App\Exceptions\BaseException;
Expand All @@ -23,7 +22,7 @@
use Quantum\Router\RouteFinder;
use Quantum\Debugger\Debugger;
use Quantum\Http\Response;
use Quantum\Loader\Setup;
use Quantum\Config\Setup;
use ReflectionException;
use Quantum\Di\Di;
use Exception;
Expand Down Expand Up @@ -54,7 +53,7 @@ private function resolveRoute(): ?MatchedRoute

/**
* Resolve lang config and current locale before controller hooks run.
* @throws LangException|ConfigException|LoaderException|DiException|ReflectionException
* @throws LangException|ConfigException|DiException|ReflectionException
*/
private function loadLanguage(): void
{
Expand All @@ -74,7 +73,7 @@ private function logDebugInfo(): void
}

/**
* @throws ConfigException|DiException|ReflectionException|LoaderException
* @throws ConfigException|DiException|ReflectionException
*/
private function setupViewCache(): ViewCache
{
Expand All @@ -92,7 +91,7 @@ private function setupViewCache(): ViewCache
}

/**
* @throws ConfigException|LoaderException|DiException|ReflectionException
* @throws ConfigException|DiException|ReflectionException
*/
private function handleCors(Response $response): void
{
Expand All @@ -106,7 +105,7 @@ private function handleCors(Response $response): void
}

/**
* @throws ConfigException|LoaderException|DiException|ReflectionException|Exception
* @throws ConfigException|DiException|ReflectionException|Exception
*/
private function sendResponse(Response $response): void
{
Expand Down
2 changes: 1 addition & 1 deletion src/Auth/Factories/AuthFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
use Quantum\Service\Service;
use Quantum\Hasher\Hasher;
use Quantum\Jwt\JwtToken;
use Quantum\Loader\Setup;
use Quantum\Config\Setup;
use ReflectionException;
use Quantum\Auth\Auth;
use Quantum\Di\Di;
Expand Down
17 changes: 13 additions & 4 deletions src/Cache/Adapters/RedisAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,19 @@ public function has($key): bool
*/
public function set($key, $value, $ttl = null): bool
{
return (bool) $this->redis->set(
$this->keyHash($key),
serialize($value),
$this->normalizeTtl($ttl)
$ttl = $this->normalizeTtl($ttl);
$key = $this->keyHash($key);

if ($ttl <= 0) {
$this->redis->del($key);

return true;
}

return (bool) $this->redis->setex(
$key,
$ttl,
serialize($value)
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Cache/Factories/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Quantum\Di\Exceptions\DiException;
use Psr\SimpleCache\CacheInterface;
use Quantum\Cache\Enums\CacheType;
use Quantum\Loader\Setup;
use Quantum\Config\Setup;
use ReflectionException;
use Quantum\Cache\Cache;
use Quantum\Di\Di;
Expand Down
2 changes: 1 addition & 1 deletion src/Captcha/Factories/CaptchaFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Quantum\Captcha\Enums\CaptchaType;
use Quantum\HttpClient\HttpClient;
use Quantum\Captcha\Captcha;
use Quantum\Loader\Setup;
use Quantum\Config\Setup;
use ReflectionException;
use Quantum\Di\Di;

Expand Down
67 changes: 54 additions & 13 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,9 @@
namespace Quantum\Config;

use Quantum\Config\Exceptions\ConfigException;
use Quantum\Loader\Exceptions\LoaderException;
use Quantum\Config\Contracts\ConfigInterface;
use Quantum\Di\Exceptions\DiException;
use Dflydev\DotAccessData\Data;
use Quantum\Loader\Loader;
use Quantum\Loader\Setup;
use ReflectionException;
use Quantum\Di\Di;
use Quantum\App\App;

/**
* Class Config
Expand All @@ -30,7 +25,7 @@ class Config implements ConfigInterface

/**
* @inheritDoc
* @throws DiException|LoaderException|ReflectionException
* @throws ConfigException
*/
public function load(Setup $setup): void
{
Expand All @@ -44,8 +39,6 @@ public function load(Setup $setup): void
/**
* @inheritDoc
* @throws ConfigException
* @throws DiException
* @throws ReflectionException|LoaderException
*/
public function import(Setup $setup): void
{
Expand All @@ -64,6 +57,21 @@ public function import(Setup $setup): void
}
}

/**
* @inheritDoc
* @throws ConfigException
*/
public function importIfExists(Setup $setup): bool
{
if ($this->resolveFilePath($setup) === null) {
return false;
}

$this->import($setup);

return true;
}

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -122,14 +130,47 @@ public function flush(): void

/**
* @return array<string, mixed>
* @throws DiException|LoaderException|ReflectionException
* @throws ConfigException
*/
private function loadConfig(Setup $setup): array
{
if (!Di::isRegistered(Loader::class)) {
Di::register(Loader::class);
$filePath = $this->resolveFilePath($setup);

if ($filePath === null) {
throw new ConfigException(_message($setup->getExceptionMessage(), $setup->getFilename() ?? ''));
}

return require $filePath;
}

private function resolveFilePath(Setup $setup): ?string
{
$filePath = App::getBaseDir() . DS;

if ($setup->getModule()) {
$filePath = modules_dir() . DS . $setup->getModule() . DS;
}

if ($setup->getPathPrefix()) {
$filePath .= $setup->getPathPrefix() . DS;
}

$filePath .= $setup->getFilename() . '.php';

if (file_exists($filePath)) {
return $filePath;
}

if ($setup->getHierarchy()) {
$filePath = App::getBaseDir() . DS . 'shared' . DS
. strtolower($setup->getPathPrefix() ?? '') . DS
. $setup->getFilename() . '.php';

if (file_exists($filePath)) {
return $filePath;
}
}

return Di::get(Loader::class)->setup($setup)->load();
return null;
}
}
7 changes: 6 additions & 1 deletion src/Config/Contracts/ConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Quantum\Config\Contracts;

use Quantum\Loader\Setup;
use Quantum\Config\Setup;

/**
* Interface ConfigInterface
Expand Down Expand Up @@ -61,4 +61,9 @@ public function load(Setup $setup): void;
* Imports new config file
*/
public function import(Setup $setup): void;

/**
* Imports new config file when it exists
*/
public function importIfExists(Setup $setup): bool;
}
Loading
Loading