Imlemented the autoloader into libraries.

Libraries can now provide classes to be added to the autoloader, although this is not required.
This commit is contained in:
Abel Hoogeveen 2019-07-27 17:22:12 +02:00
parent 8b01dd2f84
commit 4e8bb7ede3
17 changed files with 345 additions and 15 deletions

View File

@ -86,6 +86,13 @@ class Core
*/
protected static $errorHandlers = [];
/**
* Array of all classMaps which can be autoloaded.
*
* @var array
*/
protected static $autoloadMap = [];
/**
* Initializes the core.
*
@ -251,8 +258,6 @@ class Core
}
}
protected static $autoloadMap = [];
/**
* @param string $nameSpacePrefix
* @param string $filePath
@ -292,6 +297,17 @@ class Core
}
}
/**
* Clears the autoloader to its original state.
*
* Not intended for use by developer. Only for use during testing
* @internal
*/
public static function clearAutoloader()
{
self::$autoloadMap = [];
}
/**
* Tests for file writability
*

View File

@ -37,7 +37,10 @@
namespace FuzeWorks;
use FuzeWorks\Exception\ConfigException;
use FuzeWorks\Exception\CoreException;
use FuzeWorks\Exception\LibraryException;
use ReflectionClass;
use ReflectionException;
class Libraries
{
@ -196,12 +199,27 @@ class Libraries
}
// Load the class object
/** @var iLibrary $classObject */
$classObject = new $libraryClass($parameters);
// @todo Check if library has all required methods (iLibrary)
// @todo Implement autoloading for libraries
// If not instance of iLibrary, refuse the library
if (!$classObject instanceof iLibrary)
throw new LibraryException("Could not initiate library. Library is not instance of iLibrary.");
// Check if the address is already reserved, if it is, we can presume that a new instance is requested.
// Add the library files to the autoloader
try {
$headerReflection = new ReflectionClass(get_class($classObject));
$filePath = dirname($headerReflection->getFileName()) . (!is_null($classObject->getSourceDirectory()) ? DS . $classObject->getSourceDirectory() : '' );
$prefix = $classObject->getClassesPrefix();
if (!is_null($filePath) && !is_null($prefix))
Core::addAutoloadMap($prefix, $filePath);
} catch (ReflectionException $e) {
throw new LibraryException("Could not initiate library. ReflectionClass threw exception.");
} catch (CoreException $e) {
throw new LibraryException("Could not initiate library. Failed to add to autoloader.");
}
// @todo Check if the address is already reserved, if it is, we can presume that a new instance is requested.
// Otherwise this code would not be reached
// Now load the class

View File

@ -0,0 +1,64 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2019 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 - 2019, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 0.0.1
*
* @version Version 1.2.0
*/
namespace FuzeWorks;
interface iLibrary
{
/**
* Should return the namespace prefix of the classes of this library.
*
* Used to autoload classes of this library.
* @see https://www.php-fig.org/psr/psr-4/
*
* Invoked upon `FuzeWorks\Libraries:get`. Autoloading library classes before that is not possible.
*
* @return string|null
*/
public function getClassesPrefix(): ?string;
/**
* Should return the directory where the classes of this library can be found.
*
* Only the source directory within the library should be returned, e.g:
* If the source directory is 'src' within the library directory, return 'src'
*
* @return string|null
*/
public function getSourceDirectory(): ?string;
}

View File

@ -48,22 +48,23 @@ use FuzeWorks\LoggerTracyBridge;
abstract class CoreTestAbstract extends TestCase
{
/**
* Remove all listeners before the next test starts.
*
* Reset the layout manager
* Reset multiple components to their original state before running the next test
*/
public function tearDown()
{
// Clear all events created by tests
Events::$listeners = array();
Events::$listeners = [];
// Reset all config files
Factory::getInstance()->config->discardConfigFiles();
Factory::getInstance('config')->discardConfigFiles();
// Re-enable events, in case they have been disabled
Events::enable();
// Remove Config overrides
Config::$configOverrides = [];
// Remove autoloader
Core::clearAutoloader();
}
}

View File

@ -64,6 +64,8 @@ class configuratorTest extends CoreTestAbstract
public function tearDown()
{
parent::tearDown();
Core::$tempDir = dirname(__DIR__) . '/temp';
Core::$logDir = dirname(__DIR__) . '/temp';
}

View File

@ -310,6 +310,8 @@ class factoryTest extends CoreTestAbstract
public function tearDown()
{
parent::tearDown();
$factory = Factory::getInstance();
if (isset($factory->mock))
$factory->removeInstance('mock');

View File

@ -195,8 +195,36 @@ class libraryTest extends CoreTestAbstract
$this->libraries->addLibraryClass('LibraryClassFail', '\Case\Not\Exist');
}
/**
* @depends testAddLibraryClass
* @covers ::initLibrary
*/
public function testAddLibraryWithAutoloader()
{
// First assert the extra class can't be autoloaded
$this->assertFalse(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass', true));
// Load the library and test the instance type
$this->assertInstanceOf('Application\Library\TestAddLibraryWithAutoloader', $this->libraries->get('TestAddLibraryWithAutoloader'));
// Afterwards test if the loader has been correctly added
$this->assertTrue(class_exists('FuzeWorks\Test\TestAddLibraryWithAutoloader\SomeExtraClass', true));
}
/**
* @depends testAddLibraryWithAutoloader
* @covers ::initLibrary
* @expectedException \FuzeWorks\Exception\LibraryException
*/
public function testAddBadAutoloader()
{
$this->assertInstanceOf('Application\Library\TestAddBadAutoloader', $this->libraries->get('TestAddBadAutoloader'));
}
public function tearDown()
{
parent::tearDown();
Factory::getInstance()->config->getConfig('error')->revert();
}

View File

@ -213,6 +213,8 @@ class loggerTest extends CoreTestAbstract
public function tearDown()
{
parent::tearDown();
Logger::disable();
Logger::$logs = array();
}

View File

@ -198,6 +198,8 @@ class pluginTest extends CoreTestAbstract
public function tearDown()
{
parent::tearDown();
$factory = Factory::getInstance();
$factory->config->plugins->revert();
}

View File

@ -0,0 +1,52 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2019 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 - 2019, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 0.0.1
*
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestAddBadAutoloader implements iLibrary
{
public function getClassesPrefix(): ?string
{
return "";
}
public function getSourceDirectory(): ?string
{
return "non_existent";
}
}

View File

@ -34,7 +34,16 @@
* @version Version 1.2.0
*/
namespace Custom\Spaces;
use FuzeWorks\iLibrary;
class TestAddLibraryClass {
class TestAddLibraryClass implements iLibrary {
public function getClassesPrefix(): ?string
{
return null;
}
public function getSourceDirectory(): ?string
{
return null;
}
}

View File

@ -0,0 +1,43 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2019 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 - 2019, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 0.0.1
*
* @version Version 1.2.0
*/
namespace FuzeWorks\Test\TestAddLibraryWithAutoloader;
class SomeExtraClass
{
}

View File

@ -0,0 +1,52 @@
<?php
/**
* FuzeWorks Framework Core.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2019 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 - 2019, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 0.0.1
*
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestAddLibraryWithAutoloader implements iLibrary
{
public function getClassesPrefix(): ?string
{
return "FuzeWorks\Test\TestAddLibraryWithAutoloader";
}
public function getSourceDirectory(): ?string
{
return "";
}
}

View File

@ -34,7 +34,16 @@
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestGetLibraryFromAltDirectory {
class TestGetLibraryFromAltDirectory implements iLibrary {
public function getClassesPrefix(): ?string
{
return null;
}
public function getSourceDirectory(): ?string
{
return null;
}
}

View File

@ -34,7 +34,17 @@
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestGetLibraryFromDirectory {
class TestGetLibraryFromDirectory implements iLibrary {
public function getClassesPrefix(): ?string
{
return null;
}
public function getSourceDirectory(): ?string
{
return null;
}
}

View File

@ -34,7 +34,16 @@
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestGetLibraryFromSubdirectory {
class TestGetLibraryFromSubdirectory implements iLibrary {
public function getClassesPrefix(): ?string
{
return null;
}
public function getSourceDirectory(): ?string
{
return null;
}
}

View File

@ -34,8 +34,9 @@
* @version Version 1.2.0
*/
namespace Application\Library;
use FuzeWorks\iLibrary;
class TestGetLibraryParametersFromConfig {
class TestGetLibraryParametersFromConfig implements iLibrary {
public $parameters;
@ -44,4 +45,14 @@ class TestGetLibraryParametersFromConfig {
$this->parameters = $parameters;
}
public function getClassesPrefix(): ?string
{
return null;
}
public function getSourceDirectory(): ?string
{
return null;
}
}