227 lines
8.0 KiB
PHP
227 lines
8.0 KiB
PHP
<?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.3.0
|
|
*/
|
|
|
|
namespace FuzeWorks;
|
|
|
|
use FuzeWorks\Exception\ConfigException;
|
|
use FuzeWorks\Exception\CoreException;
|
|
use FuzeWorks\Exception\LibraryException;
|
|
use ReflectionClass;
|
|
|
|
class Libraries
|
|
{
|
|
use ComponentPathsTrait;
|
|
|
|
/**
|
|
* Array of loaded library objects
|
|
*
|
|
* @var array Library objects
|
|
*/
|
|
protected array $libraryObjects = [];
|
|
|
|
/**
|
|
* Array of libraries with their classnames, so they can be easily loaded
|
|
*
|
|
* @var array Library classes
|
|
*/
|
|
protected array $libraryClasses = [];
|
|
|
|
/**
|
|
* FuzeWorks Factory object. For internal use.
|
|
*
|
|
* @var Factory
|
|
*/
|
|
protected $factory;
|
|
|
|
/**
|
|
* Libraries constructor.
|
|
*
|
|
* @codeCoverageIgnore
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->factory = Factory::getInstance();
|
|
}
|
|
|
|
/**
|
|
* Add a library to FuzeWorks by adding an object.
|
|
*
|
|
* @param string $libraryName
|
|
* @param object $libraryObject
|
|
*/
|
|
public function addLibraryObject(string $libraryName, object $libraryObject)
|
|
{
|
|
$this->libraryObjects[strtolower($libraryName)] = $libraryObject;
|
|
}
|
|
|
|
/**
|
|
* Add a library to FuzeWorks by adding its class name.
|
|
*
|
|
* @param string $libraryName
|
|
* @param string $libraryClass
|
|
* @throws LibraryException
|
|
*/
|
|
public function addLibraryClass(string $libraryName, string $libraryClass)
|
|
{
|
|
if (!class_exists($libraryClass, true))
|
|
throw new LibraryException("Could not add library class. '" . $libraryClass . "' could not be loaded.", 1);
|
|
|
|
$this->libraryClasses[strtolower($libraryName)] = $libraryClass;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a library.
|
|
*
|
|
* Loads a library from one of the following sources in the following order:
|
|
* - From the loaded libraries
|
|
* - From the known libraryClasses
|
|
* - From the provided alternate library directory
|
|
* - From the earlier provided libraryPaths
|
|
*
|
|
* @param string $libraryName
|
|
* @param array $parameters
|
|
* @param array $libraryPaths
|
|
* @return object
|
|
* @throws LibraryException
|
|
*/
|
|
public function get(string $libraryName, array $parameters = [], array $libraryPaths = [])
|
|
{
|
|
// Test for empty string
|
|
if (empty($libraryName))
|
|
{
|
|
throw new LibraryException("Could not load library. No name provided", 1);
|
|
}
|
|
|
|
// Test if the library already exists
|
|
$libraryNameLowerCase = strtolower($libraryName);
|
|
$libraryClassname = '\Application\Library\\' . ucfirst($libraryName);
|
|
$libraryFilename = ucfirst($libraryName);
|
|
if (isset($this->libraryObjects[$libraryNameLowerCase]))
|
|
return $this->libraryObjects[$libraryNameLowerCase];
|
|
|
|
// Library not found. First test if the libraryClass exists
|
|
if (isset($this->libraryClasses[$libraryNameLowerCase]))
|
|
return $this->initLibrary($libraryName, $this->libraryClasses[$libraryNameLowerCase], $parameters);
|
|
|
|
// Try and load from the alternate directory if provided
|
|
$libraryPaths = (empty($libraryPaths) ? $this->componentPaths : [3 => $libraryPaths]);
|
|
|
|
// Try and find the library in the libraryPaths
|
|
for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
|
|
{
|
|
if (!isset($libraryPaths[$i]))
|
|
continue;
|
|
|
|
foreach ($libraryPaths[$i] as $path)
|
|
{
|
|
// First look if a .php file exists in the libraryPath
|
|
$classFile = $path . DS . $libraryFilename . '.php';
|
|
if (file_exists($classFile))
|
|
{
|
|
require_once($classFile);
|
|
return $this->initLibrary($libraryName, $libraryClassname);
|
|
}
|
|
|
|
$classFile = $path . DS . $libraryFilename . DS . $libraryFilename . '.php';
|
|
if (file_exists($classFile))
|
|
{
|
|
require_once($classFile);
|
|
return $this->initLibrary($libraryName, $libraryClassname);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Throw exception if not found
|
|
throw new LibraryException("Could not load library. Library not found.", 1);
|
|
}
|
|
|
|
/**
|
|
* Library Initializer
|
|
*
|
|
* Instantiates and returns a library.
|
|
* Determines whether to use the parameters array or a config file
|
|
*
|
|
* @param string $libraryName
|
|
* @param string $libraryClass
|
|
* @param array $parameters
|
|
* @throws LibraryException
|
|
* @return object
|
|
*/
|
|
protected function initLibrary(string $libraryName, string $libraryClass, array $parameters = [])
|
|
{
|
|
// First check to see if the library is already loaded
|
|
if (!class_exists($libraryClass, true))
|
|
throw new LibraryException("Could not initiate library. Class not found", 1);
|
|
|
|
// Determine what parameters to use
|
|
if (empty($parameters))
|
|
{
|
|
try {
|
|
$parameters = $this->factory->config->getConfig(strtolower($libraryName))->toArray();
|
|
} catch (ConfigException $e) {
|
|
// No problem, just use an empty array instead
|
|
$parameters = array();
|
|
}
|
|
}
|
|
|
|
// Load the class object
|
|
/** @var iLibrary $classObject */
|
|
$classObject = new $libraryClass($parameters);
|
|
|
|
// 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.");
|
|
|
|
// 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 (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
|
|
$this->libraryObjects[strtolower($libraryName)] = $classObject;
|
|
$this->factory->logger->log("Loaded Library: ".$libraryName);
|
|
return $this->libraryObjects[strtolower($libraryName)];
|
|
}
|
|
} |