Browse Source
- Adding dice library - Adding dependency config - Removing Factories - Refactoring App\Mode constructor - Refactoring App\Router constructor - Refactoring BasePath for DI usage - Refactoring ConfigFileLoader constructor - Refactoring Profiler constructor - Adjust entrypoints (index, console, worker, ..) - Adding functional test for DI - Fix tests because of refactoringspull/7412/head
28 changed files with 565 additions and 310 deletions
@ -1,61 +0,0 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Factory; |
||||
|
||||
use Friendica\Core\Config\Cache; |
||||
use Friendica\Database; |
||||
use Friendica\Util\Logger\VoidLogger; |
||||
use Friendica\Util\Profiler; |
||||
use ParagonIE\HiddenString\HiddenString; |
||||
|
||||
class DBFactory |
||||
{ |
||||
/** |
||||
* Initialize the DBA connection |
||||
* |
||||
* @param Cache\ConfigCache $configCache The configuration cache |
||||
* @param Profiler $profiler The profiler |
||||
* @param array $server The $_SERVER variables |
||||
* |
||||
* @return Database\Database |
||||
* @throws \Exception if connection went bad |
||||
*/ |
||||
public static function init(Cache\ConfigCache $configCache, Profiler $profiler, array $server) |
||||
{ |
||||
$db_host = $configCache->get('database', 'hostname'); |
||||
$db_user = $configCache->get('database', 'username'); |
||||
$db_pass = $configCache->get('database', 'password'); |
||||
$db_data = $configCache->get('database', 'database'); |
||||
$charset = $configCache->get('database', 'charset'); |
||||
|
||||
// Use environment variables for mysql if they are set beforehand |
||||
if (!empty($server['MYSQL_HOST']) |
||||
&& !empty($server['MYSQL_USERNAME'] || !empty($server['MYSQL_USER'])) |
||||
&& $server['MYSQL_PASSWORD'] !== false |
||||
&& !empty($server['MYSQL_DATABASE'])) |
||||
{ |
||||
$db_host = $server['MYSQL_HOST']; |
||||
if (!empty($server['MYSQL_PORT'])) { |
||||
$db_host .= ':' . $server['MYSQL_PORT']; |
||||
} |
||||
if (!empty($server['MYSQL_USERNAME'])) { |
||||
$db_user = $server['MYSQL_USERNAME']; |
||||
} else { |
||||
$db_user = $server['MYSQL_USER']; |
||||
} |
||||
$db_pass = new HiddenString((string) $server['MYSQL_PASSWORD']); |
||||
$db_data = $server['MYSQL_DATABASE']; |
||||
} |
||||
|
||||
$database = new Database\Database($configCache, $profiler, new VoidLogger(), $db_host, $db_user, $db_pass, $db_data, $charset); |
||||
|
||||
if ($database->connected()) { |
||||
// Loads DB_UPDATE_VERSION constant |
||||
Database\DBStructure::definition($configCache->get('system', 'basepath'), false); |
||||
} |
||||
|
||||
unset($db_host, $db_user, $db_pass, $db_data, $charset); |
||||
|
||||
return $database; |
||||
} |
||||
} |
@ -1,26 +0,0 @@
|
||||
<?php |
||||
|
||||
namespace Friendica\Factory; |
||||
|
||||
use Friendica\Core\Config\Cache\ConfigCache; |
||||
use Friendica\Util\Profiler; |
||||
|
||||
class ProfilerFactory |
||||
{ |
||||
/** |
||||
* Creates a Profiler for the current execution |
||||
* |
||||
* @param ConfigCache $configCache The configuration cache |
||||
* |
||||
* @return Profiler |
||||
*/ |
||||
public static function create(ConfigCache $configCache) |
||||
{ |
||||
$enabled = $configCache->get('system', 'profiler'); |
||||
$enabled = isset($enabled) && $enabled !== '0'; |
||||
$renderTime = $configCache->get('rendertime', 'callstack'); |
||||
$renderTime = isset($renderTime) && $renderTime !== '0'; |
||||
|
||||
return new Profiler($enabled, $renderTime); |
||||
} |
||||
} |
@ -0,0 +1,125 @@
|
||||
<?php |
||||
|
||||
use Dice\Dice; |
||||
use Friendica\App; |
||||
use Friendica\Core\Config; |
||||
use Friendica\Database\Database; |
||||
use Friendica\Factory; |
||||
use Friendica\Util; |
||||
use Psr\Log\LoggerInterface; |
||||
|
||||
/** |
||||
* The configuration defines "complex" dependencies inside Friendica |
||||
* So this classes shouldn't be simple or their dependencies are already defined here. |
||||
* |
||||
* This kind of dependencies are NOT required to be defined here: |
||||
* - $a = new ClassA(new ClassB()); |
||||
* - $a = new ClassA(); |
||||
* - $a = new ClassA(Configuration $configuration); |
||||
* |
||||
* This kind of dependencies SHOULD be defined here: |
||||
* - $a = new ClassA(); |
||||
* $b = $a->create(); |
||||
* |
||||
* - $a = new ClassA($creationPassedVariable); |
||||
* |
||||
*/ |
||||
return [ |
||||
'$basepath' => [ |
||||
'instanceOf' => Util\BasePath::class, |
||||
'call' => [ |
||||
['getPath', [], Dice::CHAIN_CALL], |
||||
], |
||||
'constructParams' => [ |
||||
dirname(__FILE__, 2), |
||||
$_SERVER |
||||
] |
||||
], |
||||
Util\BasePath::class => [ |
||||
'shared' => true, |
||||
'constructParams' => [ |
||||
dirname(__FILE__, 2), |
||||
$_SERVER |
||||
] |
||||
], |
||||
Util\ConfigFileLoader::class => [ |
||||
'shared' => true, |
||||
'constructParams' => [ |
||||
[Dice::INSTANCE => '$basepath'], |
||||
], |
||||
], |
||||
Config\Cache\ConfigCache::class => [ |
||||
'instanceOf' => Factory\ConfigFactory::class, |
||||
'call' => [ |
||||
['createCache', [], Dice::CHAIN_CALL], |
||||
], |
||||
'shared' => true, |
||||
], |
||||
App\Mode::class => [ |
||||
'call' => [ |
||||
['determine', [], Dice::CHAIN_CALL], |
||||
], |
||||
// marks the result as shared for other creations, so there's just |
||||
// one instance for the whole execution |
||||
'shared' => true, |
||||
], |
||||
Config\Configuration::class => [ |
||||
'shared' => true, |
||||
'instanceOf' => Factory\ConfigFactory::class, |
||||
'call' => [ |
||||
['createConfig', [], Dice::CHAIN_CALL], |
||||
], |
||||
], |
||||
Config\PConfiguration::class => [ |
||||
'shared' => true, |
||||
'instanceOf' => Factory\ConfigFactory::class, |
||||
'call' => [ |
||||
['createPConfig', [], Dice::CHAIN_CALL], |
||||
] |
||||
], |
||||
Database::class => [ |
||||
'shared' => true, |
||||
'constructParams' => [ |
||||
[DICE::INSTANCE => \Psr\Log\NullLogger::class], |
||||
$_SERVER, |
||||
], |
||||
], |
||||
/** |
||||
* Creates the Util\BaseURL |
||||
* |
||||
* Same as: |
||||
* $baseURL = new Util\BaseURL($configuration, $_SERVER); |
||||
*/ |
||||
Util\BaseURL::class => [ |
||||
'shared' => true, |
||||
'constructParams' => [ |
||||
$_SERVER, |
||||
], |
||||
], |
||||
/** |
||||
* Create a Logger, which implements the LoggerInterface |
||||
* |
||||
* Same as: |
||||
* $loggerFactory = new Factory\LoggerFactory(); |
||||
* $logger = $loggerFactory->create($channel, $configuration, $profiler); |
||||
* |
||||
* Attention1: We can use DICE for detecting dependencies inside "chained" calls too |
||||
* Attention2: The variable "$channel" is passed inside the creation of the dependencies per: |
||||
* $app = $dice->create(App::class, [], ['$channel' => 'index']); |
||||
* and is automatically passed as an argument with the same name |
||||
*/ |
||||
LoggerInterface::class => [ |
||||
'shared' => true, |
||||
'instanceOf' => Factory\LoggerFactory::class, |
||||
'call' => [ |
||||
['create', [], Dice::CHAIN_CALL], |
||||
], |
||||
], |
||||
'$devLogger' => [ |
||||
'shared' => true, |
||||
'instanceOf' => Factory\LoggerFactory::class, |
||||
'call' => [ |
||||
['createDev', [], Dice::CHAIN_CALL], |
||||
] |
||||
] |
||||
]; |
@ -0,0 +1,136 @@
|
||||
<?php |
||||
|
||||
namespace functional; |
||||
|
||||
use Dice\Dice; |
||||
use Friendica\App; |
||||
use Friendica\Core\Config\Cache\ConfigCache; |
||||
use Friendica\Core\Config\Configuration; |
||||
use Friendica\Database\Database; |
||||
use Friendica\Test\Util\VFSTrait; |
||||
use Friendica\Util\BasePath; |
||||
use Friendica\Util\ConfigFileLoader; |
||||
use Friendica\Util\Profiler; |
||||
use PHPUnit\Framework\TestCase; |
||||
use Psr\Log\LoggerInterface; |
||||
|
||||
class dependencyCheck extends TestCase |
||||
{ |
||||
use VFSTrait; |
||||
|
||||
/** |
||||
* @var Dice |
||||
*/ |
||||
private $dice; |
||||
|
||||
protected function setUp() |
||||
{ |
||||
parent::setUp(); |
||||
|
||||
$this->setUpVfsDir(); |
||||
|
||||
$this->dice = new Dice(); |
||||
$this->dice = $this->dice->addRules(include __DIR__ . '/../../static/dependencies.config.php'); |
||||
} |
||||
|
||||
/** |
||||
* Test the creation of the BasePath |
||||
*/ |
||||
public function testBasePath() |
||||
{ |
||||
/** @var BasePath $basePath */ |
||||
$basePath = $this->dice->create(BasePath::class, [$this->root->url()]); |
||||
|
||||
$this->assertInstanceOf(BasePath::class, $basePath); |
||||
$this->assertEquals($this->root->url(), $basePath->getPath()); |
||||
} |
||||
|
||||
/** |
||||
* Test the initial config cache |
||||
* Should not need any other files |
||||
*/ |
||||
public function testConfigFileLoader() |
||||
{ |
||||
/** @var ConfigFileLoader $configFileLoader */ |
||||
$configFileLoader = $this->dice->create(ConfigFileLoader::class); |
||||
|
||||
$this->assertInstanceOf(ConfigFileLoader::class, $configFileLoader); |
||||
|
||||
$configCache = new ConfigCache(); |
||||
$configFileLoader->setupCache($configCache); |
||||
|
||||
$this->assertNotEmpty($configCache->getAll()); |
||||
$this->assertArrayHasKey('database', $configCache->getAll()); |
||||
$this->assertArrayHasKey('system', $configCache->getAll()); |
||||
} |
||||
|
||||
/** |
||||
* Test the construction of a profiler class with DI |
||||
*/ |
||||
public function testProfiler() |
||||
{ |
||||
/** @var Profiler $profiler */ |
||||
$profiler = $this->dice->create(Profiler::class); |
||||
|
||||
$this->assertInstanceOf(Profiler::class, $profiler); |
||||
|
||||
$configCache = new ConfigCache([ |
||||
'system' => [ |
||||
'profiler' => true, |
||||
], |
||||
'rendertime' => [ |
||||
'callstack' => true, |
||||
] |
||||
]); |
||||
|
||||
$profiler = $this->dice->create(Profiler::class, [$configCache]); |
||||
|
||||
$this->assertInstanceOf(Profiler::class, $profiler); |
||||
$this->assertTrue($profiler->isRendertime()); |
||||
} |
||||
|
||||
public function testDatabase() |
||||
{ |
||||
/** @var Database $database */ |
||||
$database = $this->dice->create(Database::class); |
||||
|
||||
$this->assertInstanceOf(Database::class, $database); |
||||
$this->assertTrue($database->connected()); |
||||
} |
||||
|
||||
public function testAppMode() |
||||
{ |
||||
/** @var App\Mode $mode */ |
||||
$mode = $this->dice->create(App\Mode::class); |
||||
|
||||
$this->assertInstanceOf(App\Mode::class, $mode); |
||||
|
||||
$this->assertTrue($mode->isNormal()); |
||||
} |
||||
|
||||
public function testConfiguration() |
||||
{ |
||||
/** @var Configuration $config */ |
||||
$config = $this->dice->create(Configuration::class); |
||||
|
||||
$this->assertInstanceOf(Configuration::class, $config); |
||||
|
||||
$this->assertNotEmpty($config->get('database', 'username')); |
||||
} |
||||
|
||||
public function testLogger() |
||||
{ |
||||
/** @var LoggerInterface $logger */ |
||||
$logger = $this->dice->create(LoggerInterface::class, ['test']); |
||||
|
||||
$this->assertInstanceOf(LoggerInterface::class, $logger); |
||||
} |
||||
|
||||
public function testDevLogger() |
||||
{ |
||||
/** @var LoggerInterface $logger */ |
||||
$logger = $this->dice->create('$devLogger', ['dev']); |
||||
|
||||
self::assertInstanceOf(LoggerInterface::class, $logger); |
||||
} |
||||
} |