@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The base class which simply sets the registry object.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Bootstrap
|
||||
*/
|
||||
abstract class Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Registry_Object
|
||||
*/
|
||||
protected $_registry;
|
||||
|
||||
/**
|
||||
* The contructor method.
|
||||
*
|
||||
* Stores in object injected registry object.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry Injected registry object.
|
||||
*/
|
||||
public function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
$this->_registry = $registry;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Exceptions occuring during bootstrap
|
||||
*
|
||||
* @author Time.ly Network Inc.
|
||||
* @since 2.0
|
||||
*
|
||||
* @package AI1EC
|
||||
* @subpackage AI1EC.Exception
|
||||
*/
|
||||
class Ai1ec_Bootstrap_Exception extends Ai1ec_Exception {
|
||||
|
||||
public function get_html_message() {
|
||||
return '<p>Failure in All-in-One Event Calendar core:<br />' .
|
||||
$this->getMessage() . '</p>';
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,525 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Autoloader Class
|
||||
*
|
||||
* This class is responsible for loading all the requested class of the
|
||||
* system
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Loader
|
||||
*/
|
||||
class Ai1ec_Loader {
|
||||
|
||||
/**
|
||||
* @var string Used to specify new instances every time.
|
||||
*/
|
||||
CONST NEWINST = 'n';
|
||||
|
||||
/**
|
||||
* @var string Used to specify to treat as singleton.
|
||||
*/
|
||||
CONST GLOBALINST = 'g';
|
||||
|
||||
/**
|
||||
* @var array Map of files to be included
|
||||
*/
|
||||
protected $_paths = array();
|
||||
|
||||
/**
|
||||
* @var bool Set to true when internal state is changed
|
||||
*/
|
||||
protected $_modified = false;
|
||||
|
||||
/**
|
||||
* @var array Map of files already included
|
||||
*/
|
||||
protected $_included_files = array();
|
||||
|
||||
/**
|
||||
* @var string The prefix used for the classes
|
||||
*/
|
||||
protected $_prefix = null;
|
||||
|
||||
/**
|
||||
* @var string Base path to plugins core directory
|
||||
*/
|
||||
protected $_base_path = null;
|
||||
|
||||
/**
|
||||
* @var array Registered folders.
|
||||
*/
|
||||
protected $_registered = array();
|
||||
|
||||
/**
|
||||
* load method
|
||||
*
|
||||
* Load given class, via `require`, into memory
|
||||
*
|
||||
* @param string $class Name of class, which needs to be loaded
|
||||
*
|
||||
* @return Ai1ec_Loader Instance of self for chaining
|
||||
*/
|
||||
public function load( $class ) {
|
||||
if ( isset( $this->_paths[$class] ) ) {
|
||||
$this->include_file( $this->_paths[$class]['f'] );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which actually includes required file.
|
||||
*
|
||||
* The PHP language construct used is `require` and not a `require_once`,
|
||||
* as this is internal method, which shall guard itself against incidents
|
||||
* that may occur during loading classes more than once.
|
||||
* During include additional callbacks may be fired to include related
|
||||
* files, i.e. speed-up further requires.
|
||||
*
|
||||
* @param string $file Name of file to include
|
||||
*
|
||||
* @return Ai1ec_Loader Instance of self for chaining
|
||||
*/
|
||||
public function include_file( $file ) {
|
||||
if ( ! isset( $this->_included_files[$file] ) ) {
|
||||
$this->_included_files[$file] = true;
|
||||
require $file;
|
||||
}
|
||||
return $this->_included_files[$file];
|
||||
}
|
||||
|
||||
/**
|
||||
* collect_classes method
|
||||
*
|
||||
* Method to extract classes list from filesystem.
|
||||
* Returned array contains names of class, as keys, and file entites as
|
||||
* value, where *entities* means either a file name
|
||||
* - {@see self::match_file()} for more.
|
||||
*
|
||||
* @return array Map of classes and corresponding file entites
|
||||
*/
|
||||
public function collect_classes( $path = null, $folder_name = AI1EC_PLUGIN_NAME ) {
|
||||
// extension inject theit own base path
|
||||
$path = ( null === $path ) ? $this->_base_path : $path;
|
||||
$names = $this->_locate_all_files( $path, $folder_name );
|
||||
$names = $this->_process_reflections( $names );
|
||||
$this->_cache( $path, $names );
|
||||
$this->_paths = array_merge( $this->_paths, $names );
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/write cached classes map.
|
||||
*
|
||||
* If no entries are provided - acts as cache reader.
|
||||
*
|
||||
* @param array $entries Entries to write [optional=null]
|
||||
*
|
||||
* @return bool|array False on failure, true on success in writer
|
||||
* mode, cached entry in reader mode on success
|
||||
*/
|
||||
protected function _cache( $path, array $entries = null ) {
|
||||
$cache_file = $this->_get_cache_file_path( $path );
|
||||
if ( $entries ) {
|
||||
if (
|
||||
is_file( $cache_file ) &&
|
||||
! is_writable( $cache_file ) ||
|
||||
! is_writable( dirname( $cache_file ) )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
ksort( $entries, SORT_STRING );
|
||||
$content = array(
|
||||
'0registered' => $this->_registered,
|
||||
'1class_map' => $entries,
|
||||
);
|
||||
$content = var_export( $content, true );
|
||||
$content = $this->_sanitize_paths( $content, $path );
|
||||
$content = '<?php return ' . $content . ';';
|
||||
$this->_modified = false;
|
||||
if (
|
||||
false === file_put_contents( $cache_file, $content, LOCK_EX )
|
||||
) { // LOCK_EX is not supported on all hosts (streams)
|
||||
return (bool)file_put_contents( $cache_file, $content );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ( ! is_file( $cache_file ) ) {
|
||||
return false;
|
||||
}
|
||||
$cached = ( require $cache_file );
|
||||
$this->_registered[$cache_file] = true;
|
||||
return $cached['1class_map'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the way classes must be instanciated.
|
||||
*
|
||||
* Retrieves from annotations the way classes must be retrieved.
|
||||
* Possible values are
|
||||
* - new: a new instance is instantiated every time
|
||||
* - global: treat as singleton
|
||||
* - classname.method: a factory is used, specify it in that order
|
||||
* The default if nothing is specified is global.
|
||||
*
|
||||
* @param ReflectionClass $class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _get_instantiator( ReflectionClass $class ) {
|
||||
$doc = $class->getDocComment();
|
||||
preg_match_all(
|
||||
'#^\s\*\s@instantiator\s+(.*)$#im',
|
||||
$doc,
|
||||
$annotations
|
||||
);
|
||||
$instantiator = '';
|
||||
if ( isset( $annotations[1][0] ) ) {
|
||||
$instantiator = rtrim( $annotations[1][0] );
|
||||
}
|
||||
return $this->_convert_instantiator_for_map( $instantiator );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the registry must be injected in the constructor.
|
||||
* By convention the registry will always be the first parameter.
|
||||
*
|
||||
* @param ReflectionClass $class The class to check
|
||||
*
|
||||
* @return boolean true if the registry must be injected, false if not.
|
||||
*/
|
||||
protected function _inject_registry( ReflectionClass $class ) {
|
||||
$contructor = $class->getConstructor();
|
||||
if ( null !== $contructor ) {
|
||||
foreach ( $contructor->getParameters() as $param ) {
|
||||
$param_class = $param->getClass();
|
||||
if ( $param_class instanceof ReflectionClass ) {
|
||||
$name = $param_class->getName();
|
||||
if ( 'Ai1ec_Registry_Object' === $name ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the classmap with Reflection informations.
|
||||
*
|
||||
* @param array $names The class map.
|
||||
*
|
||||
* @return array The classmap with instantiator.
|
||||
*/
|
||||
protected function _process_reflections( array $names ) {
|
||||
$this->_paths = array_merge( $this->_paths, $names );
|
||||
spl_autoload_register( array( $this, 'load' ) );
|
||||
foreach ( $names as $classname => &$data ) {
|
||||
try {
|
||||
$class = new ReflectionClass( $data['c'] );
|
||||
$data['i'] = $this->_get_instantiator( $class );
|
||||
if ( $this->_inject_registry( $class ) ) {
|
||||
$data['r'] = 'y';
|
||||
}
|
||||
} catch ( ReflectionException $excpt ) { // unreachable class
|
||||
$data['i'] = self::NEWINST;
|
||||
}
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the long form to the short form where applicable.
|
||||
*
|
||||
* @param string $instantiator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _convert_instantiator_for_map( $instantiator ) {
|
||||
if ( empty( $instantiator ) || 'global' === $instantiator ) {
|
||||
return self::GLOBALINST;
|
||||
}
|
||||
if ( 'new' === $instantiator ) {
|
||||
return self::NEWINST;
|
||||
}
|
||||
return $instantiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* _locate_all_files method
|
||||
*
|
||||
* Scan file system, given path, recursively, to search for files and
|
||||
* extract `class` names from them.
|
||||
*
|
||||
* @param string $path File system path to scan
|
||||
*
|
||||
* @return array Map of classes and corresponding files
|
||||
*/
|
||||
protected function _locate_all_files( $path, $folder_name ) {
|
||||
$class_list = array();
|
||||
$directory = opendir( $path );
|
||||
while ( false !== ( $entry = readdir( $directory ) ) ) {
|
||||
if ( is_null( $entry ) || '.' === $entry{0} || 'tests' === $entry || strpos( strtolower( $entry ), 'icalcreator' ) !== false ) {
|
||||
continue;
|
||||
}
|
||||
$local_path = $path . DIRECTORY_SEPARATOR . $entry;
|
||||
$base_path = substr( $local_path, strlen( $this->_base_path ) );
|
||||
|
||||
if ( is_dir( $local_path ) ) {
|
||||
$class_list += $this->_locate_all_files( $local_path, $folder_name );
|
||||
} else {
|
||||
$class_list += $this->_extract_classes( $local_path, $folder_name );
|
||||
}
|
||||
}
|
||||
closedir( $directory );
|
||||
return $class_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* _extract_classes method
|
||||
*
|
||||
* Extract names of classes from given file.
|
||||
* So far only files ending in `.php` are processed and regular expression
|
||||
* is used instead of `token_get_all` to increase parsing speed.
|
||||
*
|
||||
* @param string $file Name of file to scan
|
||||
*
|
||||
* @return array List of classes in file
|
||||
*/
|
||||
protected function _extract_classes( $file, $folder_name ) {
|
||||
$class_list = array();
|
||||
if ( '.php' === strrchr( $file, '.' ) ) {
|
||||
$tokens = token_get_all( file_get_contents( $file ) );
|
||||
for ( $i = 2, $count = count( $tokens ); $i < $count; $i++ ) {
|
||||
if (
|
||||
T_CLASS === $tokens[$i - 2][0] ||
|
||||
T_INTERFACE === $tokens[$i - 2][0] &&
|
||||
T_WHITESPACE === $tokens[$i - 1][0] &&
|
||||
T_STRING === $tokens[$i][0]
|
||||
) {
|
||||
$names = $this->_generate_loader_names(
|
||||
$tokens[$i][1],
|
||||
$file,
|
||||
$folder_name
|
||||
);
|
||||
foreach ( $names as $name ) {
|
||||
$class_list[$name] = array(
|
||||
'f' => $file,
|
||||
'c' => $tokens[$i][1],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return $class_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate path name abbreviation.
|
||||
*
|
||||
* @param string $name Path name particle.
|
||||
*
|
||||
* @return string Abbreviated path name.
|
||||
*/
|
||||
public function path_name_shortening( $name ) {
|
||||
return strtoupper( $name[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* _sanitize_paths method
|
||||
*
|
||||
* Sanitize paths before writing to cache file.
|
||||
* Make sure, that constants and absolute paths are used independently
|
||||
* of system used, thus making file cross-platform generatable.
|
||||
*
|
||||
* @param string $content Output to be written to cache file.
|
||||
* @param string $base_path Base path to use if not default.
|
||||
*
|
||||
* @return string Modified content, with paths replaced
|
||||
*/
|
||||
protected function _sanitize_paths(
|
||||
$content,
|
||||
$base_path = null
|
||||
) {
|
||||
$local_ds = '/';
|
||||
$ai1ec_path = $this->_base_path;
|
||||
$const_name = 'AI1EC_PATH';
|
||||
if ( null !== $base_path ) {
|
||||
$ai1ec_path = $base_path;
|
||||
$const_name = implode( array_map(
|
||||
array( $this, 'path_name_shortening' ),
|
||||
explode( '-', basename( $base_path ) )
|
||||
) ) . '_PATH';
|
||||
$const_name = str_replace( 'AIOEC', 'AI1EC', $const_name );
|
||||
}
|
||||
if ( '\\' === DIRECTORY_SEPARATOR ) {
|
||||
$local_ds = '\\\\';
|
||||
$ai1ec_path = str_replace( '\\', '\\\\', $ai1ec_path );
|
||||
}
|
||||
$content = str_replace(
|
||||
'\'' . $ai1ec_path . $local_ds,
|
||||
$const_name . ' . DIRECTORY_SEPARATOR . \'',
|
||||
$content
|
||||
);
|
||||
$content = str_replace(
|
||||
$local_ds,
|
||||
'\' . DIRECTORY_SEPARATOR . \'',
|
||||
$content
|
||||
);
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all the alternatives name that the loaded recognize.
|
||||
*
|
||||
* For example:
|
||||
* The class Ai1ec_Html_Helper can be loaded as
|
||||
* - html.helper ( the path to the file )
|
||||
* - Ai1ec_Html_Helper ( needed by Autoload )
|
||||
*
|
||||
* @param $class string the original name of the class.
|
||||
* @param $file string the file
|
||||
*
|
||||
* @return array An array of strings with the availables names.
|
||||
*/
|
||||
protected function _generate_loader_names( $class, $file, $folder_name ) {
|
||||
$names = array( $class );
|
||||
// Remove the extension.
|
||||
$file = substr( $file, 0, strrpos( $file , '.' ) );
|
||||
$file = strtr( $file, array( '//' => '/' ) );
|
||||
// Get just the meaningful data.
|
||||
$relative_path_position = strrpos( // offset of base directory
|
||||
$file,
|
||||
DIRECTORY_SEPARATOR . $folder_name . DIRECTORY_SEPARATOR
|
||||
);
|
||||
$file = substr(
|
||||
$file,
|
||||
strpos( // cut to app|lib|vendor|...
|
||||
$file,
|
||||
DIRECTORY_SEPARATOR,
|
||||
$relative_path_position + strlen( $folder_name ) + 2
|
||||
)
|
||||
);
|
||||
$names[] = str_replace(
|
||||
DIRECTORY_SEPARATOR,
|
||||
'.',
|
||||
trim( $file, DIRECTORY_SEPARATOR )
|
||||
);
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the key to the actual class name if any
|
||||
*
|
||||
* @param $key string Key requested to initialize
|
||||
*
|
||||
* @return array|null Array of the class, or null if none is found
|
||||
*/
|
||||
public function resolve_class_name( $key ) {
|
||||
if ( ! isset( $this->_paths[$key] ) ) {
|
||||
return null;
|
||||
}
|
||||
return $this->_paths[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cache if object was modified
|
||||
*
|
||||
* @return void Destructor does not return
|
||||
*/
|
||||
public function __destruct() {
|
||||
if ( $this->_modified ) {
|
||||
$this->_cache( $this->_paths );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper to detect internal extension file path.
|
||||
*
|
||||
* @param string $path Absolute path to extension base directory.
|
||||
*
|
||||
* @return bool Success loading extension classes.
|
||||
*/
|
||||
public function register_extension_map( $path ) {
|
||||
return $this->register_map( $this->_get_cache_file_path( $path ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register external class map to use in loading sequence
|
||||
*
|
||||
* @param string $file Path to class map
|
||||
*
|
||||
* @return bool Success loading it
|
||||
*/
|
||||
public function register_map( $file ) {
|
||||
if (
|
||||
isset( $this->_registered[$file] ) && (
|
||||
! defined( 'AI1EC_DEBUG' ) ||
|
||||
! AI1EC_DEBUG
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if ( ! is_file( $file ) ) {
|
||||
return false;
|
||||
}
|
||||
$entries = ( require $file );
|
||||
foreach ( $entries['1class_map'] as $class_name => $properties ) {
|
||||
$this->_paths[$class_name] = $properties;
|
||||
}
|
||||
$this->_registered[$file] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initialize the loader creating the map of available classes, if the
|
||||
* AI1EC_DEBUG constants is true the list is regenerated
|
||||
*
|
||||
* @throws Exception if the map is invalid
|
||||
*
|
||||
* @return void Constructor does not return
|
||||
*/
|
||||
public function __construct( $base_path ) {
|
||||
$this->_base_path = $base_path;
|
||||
$this->_prefix = explode( '_', __CLASS__ );
|
||||
$this->_prefix = $this->_prefix[0];
|
||||
$class_map = $this->_cache( $base_path );
|
||||
if (
|
||||
! is_array( $class_map ) ||
|
||||
defined( 'AI1EC_DEBUG' ) && AI1EC_DEBUG
|
||||
) {
|
||||
if ( ! defined( 'AI1EC_DEBUG' ) || ! AI1EC_DEBUG ) {
|
||||
// using generic `Ai1ec_Exception` as others are, potentially,
|
||||
// not resolved at this time.
|
||||
throw new Ai1ec_Exception(
|
||||
'Generated class map is invalid: ' .
|
||||
var_export( $class_map, true ) .
|
||||
'. Please delete lib/bootstrap/loader-map.php (if it exists), make ' .
|
||||
'sure lib/bootstrap/ is writable by the web server, and enable ' .
|
||||
'debug mode by setting AI1EC_DEBUG to true (then back to false ' .
|
||||
'when done).'
|
||||
);
|
||||
}
|
||||
$class_map = $this->collect_classes();
|
||||
}
|
||||
$this->_paths = $class_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get cache file path given path to plugin.
|
||||
*
|
||||
* @param string $path Path to plugin directory.
|
||||
*
|
||||
* @return string Absolute path to loader cache file.
|
||||
*/
|
||||
protected function _get_cache_file_path( $path ) {
|
||||
return $path . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR .
|
||||
'bootstrap' . DIRECTORY_SEPARATOR . 'loader-map.php';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Application Registry: handles application wide variables.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Object
|
||||
*/
|
||||
class Ai1ec_Registry_Application implements Ai1ec_Registry {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Registry_Object
|
||||
*/
|
||||
protected $_registry;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_environment = array();
|
||||
|
||||
/**
|
||||
* The contructor method.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry
|
||||
*/
|
||||
function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
$this->_registry = $registry;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Ai1ec_Registry::get()
|
||||
*/
|
||||
public function get( $key ) {
|
||||
if ( ! isset ( $this->_environment[$key] ) ) {
|
||||
return false;
|
||||
}
|
||||
return $this->_environment[$key];
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Ai1ec_Registry::set()
|
||||
*/
|
||||
public function set( $key, $value ) {
|
||||
$this->_environment[$key] = $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The basic registry interface.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Object
|
||||
*/
|
||||
interface Ai1ec_Registry {
|
||||
|
||||
/**
|
||||
* Retrieves the key from the registry
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed the value associated to the key.
|
||||
*/
|
||||
public function get( $key );
|
||||
|
||||
/**
|
||||
* Set the key into the registry.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set( $key, $value );
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Object Registry: get instance of requested and optionally registered object.
|
||||
*
|
||||
* Object (instance of a class) is generater, or returned from internal cache
|
||||
* if it was requested and instantiated before.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Object
|
||||
*/
|
||||
class Ai1ec_Registry_Object implements Ai1ec_Registry {
|
||||
|
||||
/**
|
||||
* @var array The internal objects cache
|
||||
*/
|
||||
private $_objects = array();
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Loader The Ai1ec_Loader instance used by the registry
|
||||
*/
|
||||
private $_loader = null;
|
||||
|
||||
/**
|
||||
* Get the loader ( used by extensions )
|
||||
*
|
||||
* @return Ai1ec_Loader
|
||||
*/
|
||||
public function get_loader() {
|
||||
return $this->_loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method prepares environment for easier extension integration.
|
||||
*
|
||||
* NOTICE: only extensions, that follow internal guideliness for
|
||||
* files and methods organization must call this hook.
|
||||
*
|
||||
* Absolute path to extensions directory is autodetected, if not
|
||||
* provided, appending plugins name to path to plugins dir.
|
||||
*
|
||||
* @param string $name Name of the extension.
|
||||
* @param string $path Absolute path to extension directory.
|
||||
*
|
||||
* @return Ai1ec_Registry_Object Instance of self for chaining.
|
||||
*/
|
||||
public function extension_acknowledge( $name, $path = null ) {
|
||||
if ( null === $path ) {
|
||||
$path = AI1EC_EXTENSIONS_BASEDIR . $name;
|
||||
}
|
||||
if ( AI1EC_DEBUG ) {
|
||||
$this->_loader->collect_classes( $path, $name );
|
||||
}
|
||||
$this->get( 'theme.loader' )->register_extension(
|
||||
$path,
|
||||
plugins_url( $name )
|
||||
);
|
||||
$this->_loader->register_extension_map( $path );
|
||||
do_action( 'ai1ec_extension_loaded', $path, $name );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class instance.
|
||||
*
|
||||
* Return an instance for the requested key, this method has an internal
|
||||
* cache.
|
||||
*
|
||||
* @param string $key Name of previously registered object or parseable
|
||||
* class name
|
||||
*
|
||||
* @return object Instance of the requested class
|
||||
*/
|
||||
public function get( $key ) {
|
||||
$class_data = $this->_loader->resolve_class_name( $key );
|
||||
if ( ! $class_data ) {
|
||||
throw new Ai1ec_Bootstrap_Exception(
|
||||
'Unable to resolve class for "' . $key . '"'
|
||||
);
|
||||
}
|
||||
$class_name = $class_data['c'];
|
||||
if (
|
||||
'Ai1ec_Event' === $class_name &&
|
||||
$this->get( 'compatibility.check' )->use_backward_compatibility()
|
||||
) {
|
||||
$class_name = 'Ai1ec_Event_Compatibility';
|
||||
}
|
||||
$instantiator = $class_data['i'];
|
||||
$args = array_slice( func_get_args(), 1 );
|
||||
if ( isset ( $class_data['r'] ) ) {
|
||||
array_unshift( $args, $this );
|
||||
}
|
||||
if ( Ai1ec_Loader::NEWINST === $instantiator ) {
|
||||
return $this->initiate(
|
||||
$class_name,
|
||||
$args
|
||||
);
|
||||
}
|
||||
if ( Ai1ec_Loader::GLOBALINST === $instantiator ) {
|
||||
if ( ! isset( $this->_objects[$class_name] ) ) {
|
||||
// Ask the loader to load the required files to avoid autoloader
|
||||
$this->_loader->load( $class_name );
|
||||
$this->_objects[$class_name] = $this->initiate(
|
||||
$class_name,
|
||||
$args
|
||||
);
|
||||
}
|
||||
return $this->_objects[$class_name];
|
||||
}
|
||||
// Ok it's a factory.
|
||||
$factory = explode( '.', $instantiator );
|
||||
return $this->dispatch(
|
||||
$factory[0],
|
||||
$factory[1],
|
||||
$args
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to set previously created globally accessible class instance.
|
||||
*
|
||||
* @param string $name Class name to be used.
|
||||
* @param object $object Actual instance of class above.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function inject_object( $name, $object ) {
|
||||
if ( ! is_object( $object ) || ! ( $object instanceof $name ) ) {
|
||||
throw new Ai1ec_Bootstrap_Exception(
|
||||
'Attempt to inject not an object / invalid object.'
|
||||
);
|
||||
}
|
||||
$this->_objects[$name] = $object;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Ai1ec_Registry::set()
|
||||
*/
|
||||
public function set( $key, $value ) {
|
||||
// The set method allows to inject classes from extensions into the registry.
|
||||
new Ai1ec_Bootstrap_Exception( 'Not implemented' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciate the class given the class names and arguments.
|
||||
*
|
||||
* @param string $class_name The name of the class to instanciate.
|
||||
* @param array $argv An array of aguments for construction.
|
||||
*
|
||||
* @return object A new instance of the requested class
|
||||
*/
|
||||
public function initiate( $class_name, array $argv = array() ) {
|
||||
switch ( count( $argv ) ) {
|
||||
case 0:
|
||||
return new $class_name();
|
||||
|
||||
case 1:
|
||||
return new $class_name( $argv[0] );
|
||||
|
||||
case 2:
|
||||
return new $class_name( $argv[0], $argv[1] );
|
||||
|
||||
case 3:
|
||||
return new $class_name( $argv[0], $argv[1], $argv[2] );
|
||||
|
||||
case 4:
|
||||
return new $class_name( $argv[0], $argv[1], $argv[2], $argv[3] );
|
||||
|
||||
case 5:
|
||||
return new $class_name( $argv[0], $argv[1], $argv[2], $argv[3], $argv[4] );
|
||||
}
|
||||
|
||||
$reflected = new ReflectionClass( $class_name );
|
||||
return $reflected->newInstanceArgs( $argv );
|
||||
}
|
||||
|
||||
/**
|
||||
* A call_user_func_array alternative.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function dispatch( $class, $method, $params = array() ) {
|
||||
if ( empty( $class ) ) {
|
||||
switch ( count( $params) ) {
|
||||
case 0:
|
||||
return $method();
|
||||
case 1:
|
||||
return $method( $params[0] );
|
||||
case 2:
|
||||
return $method( $params[0], $params[1] );
|
||||
case 3:
|
||||
return $method( $params[0], $params[1], $params[2] );
|
||||
default:
|
||||
return call_user_func_array( $method, $params );
|
||||
}
|
||||
} else {
|
||||
// get an instance of the class
|
||||
$class = $this->get( $class );
|
||||
switch ( count( $params) ) {
|
||||
case 0:
|
||||
return $class->{$method}();
|
||||
case 1:
|
||||
return $class->{$method}( $params[0] );
|
||||
case 2:
|
||||
return $class->{$method}( $params[0], $params[1] );
|
||||
case 3:
|
||||
return $class->{$method}( $params[0], $params[1], $params[2] );
|
||||
default:
|
||||
return call_user_func_array(
|
||||
array( $class, $method ),
|
||||
$params
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initialize the Registry
|
||||
*
|
||||
* @param Ai1ec_Loader $ai1ec_loader Instance of Ai1EC classes loader
|
||||
*
|
||||
* @return void Constructor does not return
|
||||
*/
|
||||
public function __construct( $ai1ec_loader ) {
|
||||
$this->_loader = $ai1ec_loader;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user