Implemented a new configurator.

The container generated by the configurator now needs to be initialized. This should be done after adding all directories and components.
This commit is contained in:
Abel Hoogeveen 2018-09-29 20:36:11 +02:00
parent a71a310ec4
commit 57517511a4
No known key found for this signature in database
GPG Key ID: 96C2234920BF4292
10 changed files with 292 additions and 133 deletions

View File

@ -76,152 +76,122 @@ class Configurator
*/
protected $directories = ['app' => []];
/**
* Plugins that can be loaded outside of a directory and through a classname.
*
* @var array of plugins
*/
protected $plugins = [];
/**
* Libraries that can be loaded outside of a directory and through a classname.
*
* @var array of plugins
*/
protected $libraries = [];
const COOKIE_SECRET = 'fuzeworks-debug';
/* ---------------- Core Directories--------------------- */
/**
* Sets path to temporary directory.
*
* @return Configurator
* @throws InvalidArgumentException
*/
public function setLogDirectory($path)
{
if (!is_dir($path))
throw new InvalidArgumentException("Could not set log directory. Directory does not exist", 1);
$this->parameters['logDir'] = $path;
return $this;
}
/**
* Sets path to temporary directory.
*
* @return Configurator
* @throws InvalidArgumentException
*/
public function setTempDirectory($path)
{
if (!is_dir($path))
throw new InvalidArgumentException("Could not set temp directory. Directory does not exist", 1);
$this->parameters['tempDir'] = $path;
return $this;
}
/**
* Add a directory to FuzeWorks
*
* @param string $directory
* @param string $category Optional. Defaults to 'app
* @return $this
*/
public function addDirectory(string $directory, string $category = 'app')
{
$this->directories[$category][] = $directory;
return $this;
}
/* ---------------- Components -------------------------- */
/**
* Registers a component that will be added to the Factory when the container is built
*
* @param iComponent $component
* @return Configurator
*/
public function addComponent(iComponent $component)
{
foreach ($component->getClasses() as $objectName => $className) {
$this->components[$objectName] = $className;
}
return $this;
}
/**
* Registers a plugin that will be loaded outside of a directory
*
* @param array Array with pluginName and pluginClass ('name' => 'classname')
*/
public function addPlugin(array $plugin)
{
foreach ($plugin as $key => $value) {
if ($plugin instanceof iPlugin)
$this->plugins[$key] = $value;
else
throw new InvalidArgumentException("Can not add plugin. '".$key."' is not an instance of iPlugin.", 1);
}
}
/**
* Registers a library that will be loaded outside of a directory
*
* @param array Array with libraryName and libraryClass ('name' => 'classname')
*/
public function addLibrary(array $library)
{
foreach ($library as $key => $value) {
$this->libraries[$key] = $value;
}
}
/* ---------------- App Directories --------------------- */
public function addAppDirectory(string $directory)
{
$this->directories['app'][] = $directory;
}
/*public function addConfigDirectory(string $directory)
{
$this->directories['config'][] = $directory;
}
public function addEventDirectory(string $directory)
{
$this->directories['events'][] = $directory;
}
public function addHelperDirectory(string $directory)
{
$this->directories['helpers'][] = $directory;
}
public function addLibraryDirectory(string $directory)
{
$this->directories['libraries'][] = $directory;
}
public function addPluginDirectory(string $directory)
{
$this->directories['plugins'][] = $directory;
}*/
// @todo How do we add these dynamically for components?
/* ---------------- Other Features ---------------------- */
/**
* Sets the default timezone.
* @return Configurator
* @throws InvalidArgumentException
*/
public function setTimeZone($timezone)
{
if (!date_default_timezone_set($timezone))
throw new InvalidArgumentException("Could not set timezone. Invalid timezone provided.", 1);
@ini_set('date.timezone', $timezone); // @ - function may be disabled
return $this;
}
/**
* Adds new parameters. Use to quickly set multiple parameters at once
* @param array $params
* @return Configurator
*/
public function setParameters(array $params)
{
foreach ($params as $key => $value) {
$this->parameters[$key] = $value;
}
return $this;
}
/* ---------------- Debug Mode -------------------------- */
/**
* Fully enable or disable debug mode using one variable
* @param bool $bool
* @return Configurator
*/
public function enableDebugMode(bool $bool = true)
{
$this->parameters['debugEnabled'] = $bool;
return $this;
}
/**
* Provide a string from where debug mode can be accessed.
* Provide a string from where debug mode can be accessed.
* Can be the following type of addresses:
* @todo
* @param string $address
* @return Configurator
* @throws InvalidArgumentException
*/
public function setDebugAddress($address = 'NONE')
{
@ -233,12 +203,12 @@ class Configurator
if (is_string($address) && $address == 'NONE')
{
$this->parameters['debugMatch'] = false;
return;
return $this;
}
elseif (is_string($address) && $address == 'ALL')
{
$this->parameters['debugMatch'] = true;
return;
return $this;
}
// Otherwise we run the regular tracy detectDebugMode
@ -258,16 +228,18 @@ class Configurator
$this->parameters['debugMatch'] = in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE);
return;
return $this;
}
/**
* Set the email to send logs to from Tracy
* @param string
* @return Configurator
*/
public function setDebugEmail($email): self
{
$this->parameters['debugEmail'] = $email;
return $this;
}
@ -282,10 +254,11 @@ class Configurator
/**
* Create the container which holds FuzeWorks.
*
* Due to the static nature of FuzeWorks, this is not yet possible.
* When issue #101 is completed, this should be resolved.
* Due to the static nature of FuzeWorks, this is not yet possible.
* When issue #101 is completed, this should be resolved.
*
* @return Factory
* @throws \Exception
*/
public function createContainer(): Factory
{
@ -296,7 +269,8 @@ class Configurator
// Then prepare the debugger
$debug = ($this->parameters['debugEnabled'] && $this->parameters['debugMatch'] ? true : false);
define('ENVIRONMENT', ($debug ? 'DEVELOPMENT' : 'PRODUCTION'));
if (!defined('ENVIRONMENT'))
define('ENVIRONMENT', ($debug ? 'DEVELOPMENT' : 'PRODUCTION'));
// And enable Tracy Debugger
if (class_exists('Tracy\Debugger', true))

View File

@ -102,28 +102,8 @@ class Core
ignore_user_abort(true);
register_shutdown_function(array('\FuzeWorks\Core', 'shutdown'));
// Load core functionality
$container = new Factory();
// Load the config file of the FuzeWorks core
$config = $container->config->get('core');
// Disable events if requested to do so
if (!$config->enable_events)
{
Events::disable();
}
// And load all the plugins
$container->plugins->loadHeaders();
// And fire the coreStartEvent
$event = Events::fireEvent('coreStartEvent');
if ($event->isCancelled()) {
exit;
}
return $container;
// Return the Factory
return new Factory();
}
/**

View File

@ -113,7 +113,6 @@ class Factory
/**
* Factory instance constructor. Should only really be called once
* @return void
*/
public function __construct()
{
@ -129,7 +128,7 @@ class Factory
$this->helpers = new Helpers();
$this->plugins = new Plugins();
return true;
return;
}
// @codeCoverageIgnoreEnd
@ -140,9 +139,42 @@ class Factory
$this->{$key} = $value;
}
return true;
return;
}
/**
* Finalizes the Factory and sends out a coreStartEvent
*
* @throws Exception\EventException
* @return Factory
*/
public function init()
{
// Load the config file of the FuzeWorks core
$cfg = $this->config->get('core');
// Disable events if requested to do so
if (!$cfg->enable_events)
{
Events::disable();
}
// Initialize all components
foreach ($this as $component)
{
if (method_exists($component, 'init'))
$component->init();
}
// Initialize all plugins
$this->plugins->loadHeadersFromPluginPaths();
// And fire the coreStartEvent
Events::fireEvent('coreStartEvent');
return $this;
}
/**
* Get a new instance of the Factory class.
*
@ -179,14 +211,15 @@ class Factory
self::$cloneInstances = false;
}
/**
* Create a new instance of one of the loaded classes.
* It reloads the class. It does NOT clone it.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @param string $namespace Optional namespace. Defaults to 'FuzeWorks\'
* @return Factory Instance
*/
/**
* Create a new instance of one of the loaded classes.
* It reloads the class. It does NOT clone it.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @param string $namespace Optional namespace. Defaults to 'FuzeWorks\'
* @return Factory Instance
* @throws FactoryException
*/
public function newInstance($className, $namespace = 'FuzeWorks\\'): self
{
// Determine the class to load
@ -212,13 +245,14 @@ class Factory
return $this;
}
/**
* Clone an instance of one of the loaded classes.
* It clones the class. It does NOT re-create it.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @return Factory Instance
*/
/**
* Clone an instance of one of the loaded classes.
* It clones the class. It does NOT re-create it.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @return Factory Instance
* @throws FactoryException
*/
public function cloneInstance($className): self
{
// Determine the class to load
@ -257,12 +291,13 @@ class Factory
return $this;
}
/**
* Remove an instance of one of the loaded classes.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @return Factory Factory Instance
*/
/**
* Remove an instance of one of the loaded classes.
*
* @param string $className The name of the loaded class, WITHOUT the namespace
* @return Factory Factory Instance
* @throws FactoryException
*/
public function removeInstance($className): self
{
// Determine the instance name
@ -279,4 +314,15 @@ class Factory
// Return itself
return $this;
}
/**
* Returns true if component is part of this Factory.
*
* @param $componentName
* @return bool
*/
public function instanceIsset($componentName)
{
return isset($this->{$componentName});
}
}

View File

@ -40,5 +40,5 @@ namespace FuzeWorks;
interface iComponent
{
public function getClasses();
public function getClasses(): array;
}

View File

@ -38,7 +38,7 @@ require_once(dirname(__DIR__) . '/vendor/autoload.php');
$configurator = new FuzeWorks\Configurator();
// Set directories
$configurator->addAppDirectory(dirname(__FILE__) . '/application');
$configurator->addDirectory(dirname(__FILE__) . '/application');
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->setLogDirectory(__DIR__ . '/temp');
@ -51,5 +51,6 @@ $configurator->setDebugAddress('ALL');
//$configurator->setDebugEmail('example@mail.com');
$container = $configurator->createContainer();
$container->init();
return $container;

View File

@ -0,0 +1,51 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.2.0
*
* @version Version 1.2.0
*/
namespace FuzeWorks\Component;
use FuzeWorks\iComponent;
class TestComponent implements iComponent
{
public function getClasses(): array
{
return ['test' => 'FuzeWorks\Component\Test'];
}
}
class Test
{
public $variable = 5;
}

View File

@ -0,0 +1,51 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, Techfuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.2.0
*
* @version Version 1.2.0
*/
namespace FuzeWorks\Component;
use FuzeWorks\iComponent;
class TestAddComponentFailComponent implements iComponent
{
public function getClasses(): array
{
return ['test' => 'FuzeWorks\Component\Test'];
}
}
class TestAddComponentFail
{
public $variable = 5;
}

View File

@ -35,6 +35,7 @@
*/
use FuzeWorks\Configurator;
use FuzeWorks\iComponent;
/**
* Class ConfiguratorTest.
@ -44,11 +45,17 @@ use FuzeWorks\Configurator;
class configuratorTest extends CoreTestAbstract
{
/**
* @var Configurator
*/
protected $configurator;
public function setUp()
{
$this->configurator = new Configurator;
$this->configurator->setTempDirectory(dirname(__DIR__) . '/temp');
$this->configurator->setLogDirectory(dirname(__DIR__) . '/temp');
$this->configurator->setTimeZone('Europe/Amsterdam');
}
public function testGetConfiguratorClass()
@ -56,4 +63,38 @@ class configuratorTest extends CoreTestAbstract
$this->assertInstanceOf('FuzeWorks\Configurator', $this->configurator);
}
}
public function testCreateContainer()
{
$this->assertInstanceOf('FuzeWorks\Factory', $this->configurator->createContainer());
}
/**
* @depends testCreateContainer
*/
public function testAddComponent()
{
// Load the component
require_once 'tests'.DS.'components'.DS.'testAddComponent'.DS.'TestAddComponent.php';
$component = new FuzeWorks\Component\TestComponent();
$this->configurator->addComponent($component);
// Create container and test if component is added and has known properties
$container = $this->configurator->createContainer()->init();
$this->assertTrue(property_exists($container, 'test'));
$this->assertInstanceOf('FuzeWorks\Component\Test', $container->test);
$this->assertEquals(5, $container->test->variable);
}
/**
* @depends testAddComponent
*/
public function testAddComponentFail()
{
// Load the component
require_once 'tests'.DS.'components'.DS.'testAddComponent'.DS.'TestAddComponent.php';
$this->assertTrue(true);
}
}

View File

@ -233,6 +233,20 @@ class factoryTest extends CoreTestAbstract
$factory->removeInstance('fake');
}
public function testInstanceIsset()
{
// Load the factory
$factory = new Factory;
// Test if not set and add instance
$this->assertFalse($factory->instanceIsset('test'));
$factory->setInstance('test', 5);
// Test if isset and value
$this->assertTrue($factory->instanceIsset('test'));
$this->assertEquals(5, $factory->test);
}
public function tearDown()
{
Factory::disableCloneInstances();

View File

@ -33,7 +33,7 @@
*
* @version Version 1.2.0
*/
use FuzeWorks\Core;
use FuzeWorks\Factory;
use FuzeWorks\Events;
use FuzeWorks\EventPriority;
@ -51,7 +51,8 @@ class coreStartEventTest extends CoreTestAbstract
$mock->expects($this->once())->method('mockMethod');
Events::addListener(array($mock, 'mockMethod'), 'coreStartEvent', EventPriority::NORMAL);
Core::init();
$factory = new Factory;
$factory->init();
}
}