Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/App/Adapters/AppAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ abstract class AppAdapter implements AppInterface
*/
public function __construct()
{
Di::registerDependencies();

$this->loadCoreDependencies();
$this->loadComponentHelperFunctions();
$this->loadLibraryHelperFunctions();
$this->loadAppHelperFunctions();
Expand Down
18 changes: 8 additions & 10 deletions src/App/Adapters/WebAppAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,22 @@
* @author Arman Ag. <arman.ag@softberg.org>
* @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
* @link http://quantum.softberg.org/
* @since 2.9.7
* @since 2.9.8
*/

namespace Quantum\App\Adapters;

use Quantum\Libraries\Encryption\Exceptions\CryptorException;
use Quantum\Libraries\Database\Exceptions\DatabaseException;
use Quantum\Libraries\Session\Exceptions\SessionException;
use Quantum\Middleware\Exceptions\MiddlewareException;
use Quantum\Router\Exceptions\RouteControllerException;
use Quantum\Libraries\Csrf\Exceptions\CsrfException;
use Quantum\Libraries\Lang\Exceptions\LangException;
use Quantum\Renderer\Exceptions\RendererException;
use Quantum\App\Exceptions\StopExecutionException;
use Quantum\Environment\Exceptions\EnvException;
use Quantum\Module\Exceptions\ModuleException;
use Quantum\Config\Exceptions\ConfigException;
use Quantum\Router\Exceptions\RouteException;
use Quantum\Http\Exceptions\HttpException;
use Quantum\Middleware\MiddlewareManager;
use Quantum\App\Exceptions\BaseException;
use Quantum\Di\Exceptions\DiException;
Expand Down Expand Up @@ -78,22 +76,21 @@ public function __construct()
}

/**
* Starts the web app
* @return int|null
* @throws BaseException
* @throws ConfigException
* @throws RouteControllerException
* @throws CryptorException
* @throws CsrfException
* @throws DatabaseException
* @throws DebugBarException
* @throws DiException
* @throws HttpException
* @throws LangException
* @throws MiddlewareException
* @throws ModuleException
* @throws ReflectionException
* @throws RouteControllerException
* @throws RouteException
* @throws SessionException
* @throws RendererException
* @throws ModuleException
*/
public function start(): ?int
{
Expand All @@ -109,7 +106,8 @@ public function start(): ?int
$this->setupErrorHandler();
$this->initializeDebugger();

$this->loadModulesRoutes();
$this->loadModules();

$this->initializeRouter($this->request);

info(HookManager::getInstance()->getRegistered(), ['tab' => Debugger::HOOKS]);
Expand Down
7 changes: 7 additions & 0 deletions src/App/Config/dependencies.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

return [
\Quantum\Loader\Loader::class => \Quantum\Loader\Loader::class,
\Quantum\Http\Request::class => \Quantum\Http\Request::class,
\Quantum\Http\Response::class => \Quantum\Http\Response::class,
];
9 changes: 9 additions & 0 deletions src/App/Factories/AppFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ public static function create(string $type, string $baseDir): App
return self::$instances[$type];
}

/**
* @param string $type
* @return void
*/
public static function destroy(string $type)
{
unset(self::$instances[$type]);
}

/**
* @param string $type
* @param string $baseDir
Expand Down
9 changes: 9 additions & 0 deletions src/App/Traits/AppTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public static function getBaseDir(): string
return self::$baseDir;
}

protected function loadCoreDependencies()
{
$file = dirname(__DIR__) . DS . 'Config' . DS . 'dependencies.php';

$coreDependencies = (is_file($file) && is_array($deps = require $file)) ? $deps : [];

Di::registerDependencies($coreDependencies);
}

/**
* Loads component helper functions
* @throws DiException
Expand Down
11 changes: 9 additions & 2 deletions src/App/Traits/WebAppTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use Quantum\Http\Request;
use Quantum\Loader\Setup;
use ReflectionException;
use Quantum\Di\Di;

/**
* Trait WebAppTrait
Expand Down Expand Up @@ -63,12 +64,18 @@ private function initializeDebugger()
}

/**
* Load modules
* @throws ModuleException
* @throws RouteException
*/
private function loadModulesRoutes()
private function loadModules()
{
$modulesRoutes = ModuleLoader::getInstance()->loadModulesRoutes();
$moduleLoader = ModuleLoader::getInstance();

$modulesDependencies = $moduleLoader->loadModulesDependencies();
Di::registerDependencies($modulesDependencies);

$modulesRoutes = $moduleLoader->loadModulesRoutes();
Router::setRoutes($modulesRoutes);
}

Expand Down
35 changes: 3 additions & 32 deletions src/Di/Di.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use ReflectionParameter;
use ReflectionFunction;
use ReflectionMethod;
use Quantum\App\App;
use ReflectionClass;

/**
Expand All @@ -45,11 +44,11 @@ class Di
private static $resolving = [];

/**
* Loads dependency definitions
* Register dependencies
*/
public static function registerDependencies()
public static function registerDependencies(array $dependencies)
{
foreach (self::coreDependencies() + self::userDependencies() as $abstract => $concrete) {
foreach ($dependencies as $abstract => $concrete) {
if (!self::isRegistered($abstract)) {
self::register($concrete, $abstract);
}
Expand Down Expand Up @@ -272,32 +271,4 @@ private static function checkCircularDependency(string $abstract): void
throw DiException::circularDependency($chain);
}
}

/**
* Loads user defined dependencies
* @return array
*/
private static function userDependencies(): array
{
$userDependencies = App::getBaseDir() . DS . 'shared' . DS . 'config' . DS . 'dependencies.php';

if (!file_exists($userDependencies)) {
return [];
}

return (array)require_once $userDependencies;
}

/**
* Loads the core dependencies
* @return array
*/
private static function coreDependencies(): array
{
return [
\Quantum\Loader\Loader::class => \Quantum\Loader\Loader::class,
\Quantum\Http\Request::class => \Quantum\Http\Request::class,
\Quantum\Http\Response::class => \Quantum\Http\Response::class,
];
}
}
47 changes: 46 additions & 1 deletion src/Module/ModuleLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @author Arman Ag. <arman.ag@softberg.org>
* @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
* @link http://quantum.softberg.org/
* @since 2.9.7
* @since 2.9.8
*/

namespace Quantum\Module;
Expand All @@ -33,6 +33,11 @@
class ModuleLoader
{

/**
* @var array
*/
private static $moduleDependencies = [];

/**
* @var array
*/
Expand Down Expand Up @@ -101,6 +106,46 @@ public function loadModulesRoutes(): array
return $modulesRoutes;
}

/**
* @return array
* @throws ModuleException
*/
public function loadModulesDependencies(): array
{
if (empty(self::$moduleConfigs)) {
$this->loadModuleConfig();
}

$modulesDependencies = [];

foreach (self::$moduleConfigs as $module => $options) {
$modulesDependencies = array_merge($modulesDependencies, $this->getModuleDependencies($module));
}

return $modulesDependencies;
}

/**
* @param string $module
* @return array
*/
public function getModuleDependencies(string $module): array
{
if (!isset(self::$moduleDependencies[$module])) {
$file = modules_dir() . DS . $module . DS . 'config' . DS . 'dependencies.php';

if ($this->fs->exists($file)) {
$deps = $this->fs->require($file);

self::$moduleDependencies[$module] = is_array($deps) ? $deps : [];
} else {
self::$moduleDependencies[$module] = [];
}
}

return self::$moduleDependencies[$module];
}

/**
* @return array
* @throws ModuleException
Expand Down
13 changes: 13 additions & 0 deletions tests/Unit/App/Factories/AppFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ public function testAppFactoryReturnsSameInstance()

$this->assertSame($app1, $app2);
}

public function testAppFactoryDestroy()
{
$app1 = AppFactory::create(App::WEB, PROJECT_ROOT);

AppFactory::destroy(App::WEB);

$app2 = AppFactory::create(App::WEB, PROJECT_ROOT);

$this->assertInstanceOf(App::class, $app2);

$this->assertNotSame($app1, $app2);
}
}
19 changes: 19 additions & 0 deletions tests/Unit/AppTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Quantum\Loader\Setup;
use ReflectionClass;
use Quantum\App\App;
use Quantum\Di\Di;

abstract class AppTestCase extends TestCase
{
Expand All @@ -18,6 +19,10 @@ abstract class AppTestCase extends TestCase

public function setUp(): void
{
if (!file_exists(PROJECT_ROOT . DS . '.env.testing')) {
createEnvFile();
}

AppFactory::create(App::WEB, PROJECT_ROOT);

Config::getInstance()->flush();
Expand All @@ -29,9 +34,23 @@ public function setUp(): void
Config::getInstance()
->load(new Setup('config', 'config'));

$coreDependencies = [
\Quantum\Loader\Loader::class => \Quantum\Loader\Loader::class,
\Quantum\Http\Request::class => \Quantum\Http\Request::class,
\Quantum\Http\Response::class => \Quantum\Http\Response::class,
];

Di::registerDependencies($coreDependencies);

$this->fs = FileSystemFactory::get();
}

public function tearDown(): void
{
AppFactory::destroy(App::WEB);
Di::reset();
}

protected function setPrivateProperty($object, $property, $value): void
{
$reflection = new ReflectionClass($object);
Expand Down
5 changes: 0 additions & 5 deletions tests/Unit/Di/DiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ class DiTest extends AppTestCase
public function setUp(): void
{
parent::setUp();

Di::reset();
Di::registerDependencies();
}

public function testDiRegisterDependency()
Expand Down Expand Up @@ -240,8 +237,6 @@ public function testDiReset()
$this->assertEmpty($dependenciesProperty->getValue());

$this->assertEmpty($containerProperty->getValue());

Di::registerDependencies();
}
}
}
24 changes: 23 additions & 1 deletion tests/Unit/Module/ModuleLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function testGetInstance()
$this->assertInstanceOf(ModuleLoader::class, $this->moduleLoader);
}

public function testLoadModulesRoutesWithEnabledModules()
public function testLoadModulesRoutes()
{
$modulesRoutes = $this->moduleLoader->loadModulesRoutes();

Expand All @@ -39,4 +39,26 @@ public function testLoadModulesRoutesWithEnabledModules()

$this->assertCount(2, Router::getRoutes());
}

public function testLoadModulesDependencies()
{
$deps = $this->moduleLoader->loadModulesDependencies();

$this->assertIsArray($deps);

$this->assertArrayHasKey("Quantum\Libraries\Transformer\Contracts\TransformerInterface", $deps);
$this->assertSame("Quantum\Tests\_root\modules\Test\Transformers\PostTransformer", $deps["Quantum\Libraries\Transformer\Contracts\TransformerInterface"]);

$this->assertArrayHasKey("Quantum\Libraries\Storage\Contracts\TokenServiceInterface", $deps);
$this->assertSame("Quantum\Tests\_root\shared\Services\TokenService", $deps["Quantum\Libraries\Storage\Contracts\TokenServiceInterface"]);
}

public function testGetModuleConfigs()
{
$configs = $this->moduleLoader->getModuleConfigs();

$this->assertIsArray($configs);
$this->assertArrayHasKey('Test', $configs);
$this->assertArrayNotHasKey('Mame', $configs);
}
}
Loading