| 
<?php
 /**
 * CallableRepository.php - Jaxon callable object repository
 *
 * This class stores all the callable object already created.
 *
 * @package jaxon-core
 * @author Thierry Feuzeu <[email protected]>
 * @copyright 2019 Thierry Feuzeu <[email protected]>
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @link https://github.com/jaxon-php/jaxon-core
 */
 
 namespace Jaxon\Request\Support;
 
 use Jaxon\Request\Factory\CallableClass\Request as RequestFactory;
 
 use RecursiveDirectoryIterator;
 use RecursiveIteratorIterator;
 
 class CallableRepository
 {
 /**
 * The classes
 *
 * These are all the registered classes.
 *
 * @var array
 */
 protected $aClasses = [];
 
 /**
 * The namespaces
 *
 * These are all the namespaces found in registered directories.
 *
 * @var array
 */
 protected $aNamespaces = [];
 
 /**
 * The created callable objects.
 *
 * @var array
 */
 protected $aCallableObjects = [];
 
 /**
 * The options to be applied to callable objects.
 *
 * @var array
 */
 protected $aCallableOptions = [];
 
 /**
 * Get a given class options from specified directory options
 *
 * @param string        $sClassName         The class name
 * @param array         $aClassOptions      The default class options
 * @param array         $aDirectoryOptions  The directory options
 *
 * @return array
 */
 public function makeClassOptions($sClassName, array $aClassOptions, array $aDirectoryOptions)
 {
 $aOptions = $aClassOptions;
 if(key_exists('separator', $aDirectoryOptions))
 {
 $aOptions['separator'] = $aDirectoryOptions['separator'];
 }
 if(key_exists('protected', $aDirectoryOptions))
 {
 $aOptions['protected'] = $aDirectoryOptions['protected'];
 }
 if(key_exists('*', $aDirectoryOptions))
 {
 $aOptions = array_merge($aOptions, $aDirectoryOptions['*']);
 }
 if(key_exists($sClassName, $aDirectoryOptions))
 {
 $aOptions = array_merge($aOptions, $aDirectoryOptions[$sClassName]);
 }
 
 // This value will be used to compute hash
 if(!key_exists('timestamp', $aOptions))
 {
 $aOptions['timestamp'] = 0;
 }
 
 return $aOptions;
 }
 
 /**
 *
 * @param string        $sClassName         The class name
 * @param array         $aClassOptions      The default class options
 * @param array         $aDirectoryOptions  The directory options
 *
 * @return void
 */
 public function addClass($sClassName, array $aClassOptions, array $aDirectoryOptions = [])
 {
 $this->aClasses[$sClassName] = $this->makeClassOptions($sClassName, $aClassOptions, $aDirectoryOptions);
 }
 
 /**
 *
 * @param string        $sNamespace     The namespace
 * @param array|string  $aOptions       The associated options
 *
 * @return void
 */
 public function addNamespace($sNamespace, $aOptions)
 {
 $this->aNamespaces[$sNamespace] = $aOptions;
 }
 
 /**
 * Find the options associated with a registered class name
 *
 * @param string        $sClassName            The class name
 *
 * @return array|null
 */
 public function getClassOptions($sClassName)
 {
 if(!key_exists($sClassName, $this->aClasses))
 {
 // Class not found
 return null;
 }
 return $this->aClasses[$sClassName];
 }
 
 /**
 * Find a callable object by class name
 *
 * @param string        $sClassName            The class name of the callable object
 *
 * @return CallableObject|null
 */
 public function getCallableObject($sClassName)
 {
 return isset($this->aCallableObjects[$sClassName]) ? $this->aCallableObjects[$sClassName] : null;
 }
 
 /**
 * Create a new callable object
 *
 * @param string        $sClassName            The class name of the callable object
 * @param array         $aOptions              The callable object options
 *
 * @return CallableObject|null
 */
 public function createCallableObject($sClassName, array $aOptions)
 {
 // Make sure the registered class exists
 if(key_exists('include', $aOptions))
 {
 require_once($aOptions['include']);
 }
 if(!class_exists($sClassName))
 {
 return null;
 }
 
 // Create the callable object
 $xCallableObject = new CallableObject($sClassName);
 $this->aCallableOptions[$sClassName] = [];
 foreach($aOptions as $sName => $xValue)
 {
 if(in_array($sName, ['separator', 'namespace', 'protected']))
 {
 $xCallableObject->configure($sName, $xValue);
 }
 elseif(is_array($xValue) && $sName != 'include')
 {
 // These options are to be included in javascript code.
 $this->aCallableOptions[$sClassName][$sName] = $xValue;
 }
 }
 $this->aCallableObjects[$sClassName] = $xCallableObject;
 
 // Register the request factory for this callable object
 jaxon()->di()->setCallableClassRequestFactory($sClassName, $xCallableObject);
 
 return $xCallableObject;
 }
 
 /**
 * Get all registered classes
 *
 * @return array
 */
 public function getClasses()
 {
 return $this->aClasses;
 }
 
 /**
 * Get all registered namespaces
 *
 * @return array
 */
 public function getNamespaces()
 {
 return $this->aNamespaces;
 }
 
 /**
 * Get all registered callable objects
 *
 * @return array
 */
 public function getCallableObjects()
 {
 return $this->aCallableObjects;
 }
 
 /**
 * Get all registered callable objects options
 *
 * @return array
 */
 public function getCallableOptions()
 {
 return $this->aCallableOptions;
 }
 }
 
 |