/app/code/local/Balance/Lib/Model/Di/InstanceManager.php
https://bitbucket.org/dereksangshi2000/balance_lib · PHP · 350 lines · 241 code · 27 blank · 82 comment · 24 complexity · fccccf926f41cc01001640b5f31af808 MD5 · raw file
- <?php
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- class Balance_Lib_Model_Di_InstanceManager
- {
- protected $_fallbackLevelLimit = 1;
-
- protected $_definitionList = null;
-
- protected $_class = null;
-
- protected $_params = array();
-
- protected $_callbacks = array();
-
- public function __construct($class = null, $params = null, $callbacks = null, $difinitionList = null)
- {
- if (isset($class))
- {
- $this->setClass($class);
- }
- if (isset($params))
- {
- $this->setParams($params);
- }
- if (isset($difinitionList))
- {
- $this->setDefinitionList($difinitionList);
- }
- if (isset($callbacks))
- {
- $this->setCallbacks($callbacks);
- }
- }
-
- public function setCallbacks($callbacks)
- {
- $this->_callbacks = $callbacks;
- }
-
- public function getCallbacks()
- {
- if (empty($this->_callbacks))
- {
- $this->_loadCallbacksInDefinitionList();
- }
- return $this->_callbacks;
- }
-
- protected function _loadCallbacksInDefinitionList()
- {
- $this->_callbacks = $this->getDefinition($this->getClass(), 'callbacks');
- }
-
- public function hasDefinition($class)
- {
- return (array_key_exists($class, $this->_definitionList) && !empty($this->_definitionList[$class]));
- }
-
- /**
- * Get definition of the class.
- *
- * @param string $class Name (or alias) of the class.
- * @param string $property Property of the class ('params' or 'callbacks').
- * @return mixed
- */
- public function getDefinition($class, $property = null)
- {
- if (!isset($property))
- {
- return $this->_definitionList[$class];
- }
- else
- {
- switch ($property)
- {
- case 'params':
- {
- return $this->_definitionList[$class]['params'];
- }
- case 'callbacks':
- {
- return $this->_definitionList[$class]['callbacks'];
- }
- default:
- {
- return $this->_definitionList[$class];
- }
- }
- }
-
- }
-
- /**
- * Get dependency instance.
- *
- * @param string $dependencyClass Class name.
- * @param array $params OPTIONAL Params for construct.
- * @param array $callbacks OPTIONAL Callbacks.
- * @param array $definitionList Definition list provided.
- * @return type
- */
- protected function _getDependencyInstance($dependencyClass, $params = array(), $callbacks = array(), $definitionList = array())
- {
- $Instance = new Balance_Lib_Model_Di_InstanceManager($dependencyClass, $params, $callbacks, $definitionList);
- return $Instance->createInstance();
- }
-
- /**
- * Fix the dependencies.
- * 1) Fix the dependencies of 'params' in definition list.
- * 2) Fix the dependencies of 'callbacks' in definition list.
- *
- * @param array $elements The array to fix (It could be 'params' or 'callbacks').
- * @return array Fixed array (which might contain dependency instances as defined).
- */
- protected function _fixDependencis($elements)
- {
- if (is_array($elements))
- {
- foreach ($elements as $key => $val)
- {
- // Key is marked as dependency.
- $dependencyClass = $this->_getDependencyClass($key);
- if (!empty($dependencyClass))
- {
- if ($this->hasDefinition($dependencyClass))
- {
- $definition = $this->getDefinition($dependencyClass);
- $params = isset($val['params']) ? $val['params'] : (isset($definition['params']) ? $definition['params'] : array());
- $callbacks = isset($val['callbacks']) ? $val['callbacks'] : (isset($definition['callbacks']) ? $definition['callbacks'] : array());
- // $Instance = new Balance_Lib_Model_Di_InstanceManager($dependencyClass, $params, $callbacks, $this->getDefinitionList());
- // $elements[$key] = $Instance->createInstance();
- $elements[$key] = $this->_getDependencyInstance($dependencyClass, $params, $callbacks, $this->getDefinitionList());
- }
- else
- {
- /**
- * @todo Throw exception ('Dependency defition not found') .
- */
- throw new Exception(sprintf('Dependency class %s defition not found', $dependencyClass));
- }
- }
- // Value is marked as dependency.
- $dependencyClass = $this->_getDependencyClass($val);
- if (!empty($dependencyClass))
- {
- if ($this->hasDefinition($dependencyClass))
- {
- $definition = $this->getDefinition($dependencyClass);
- $params = isset($definition['params']) ? $definition['params'] : array();
- $callbacks = isset($definition['callbacks']) ? $definition['callbacks'] : array();
- // $Instance = new Balance_Lib_Model_Di_InstanceManager($dependencyClass, $params, $callbacks, $this->getDefinitionList());
- // $elements[$key] = $Instance->createInstance();
- $elements[$key] = $this->_getDependencyInstance($dependencyClass, $params, $callbacks, $this->getDefinitionList());
- }
- else
- {
- /**
- * @todo Throw exception ('Dependency defition not found') .
- */
- throw new Exception(sprintf('Dependency class %s defition not found', $dependencyClass));
- }
- }
- }
- return $elements;
- }
- }
-
- /**
- * Get dependency class.
- * If the given value is marked as a dependency class, then the format in the defition list should look like this: '_d::NAME_OR_ALIAS_OF_THE_CLASS'
- *
- * @param string $ele The element to evaluate.
- * @return mixed Return the class name (or alias) if it's a dependency class, or false otherwise.
- */
- protected function _getDependencyClass($ele)
- {
- if (preg_match("/^_d::(.+)/", $ele, $matches))
- {
- return $matches[1];
- }
- return false;
- }
-
-
- public function setDefinitionList($difinitionList)
- {
- $this->_definitionList = $difinitionList;
- }
-
- public function getDefinitionList()
- {
- return $this->_definitionList;
- }
-
- public function setClass($class)
- {
- $this->_class = $class;
- }
-
- public function getClass()
- {
- return $this->_class;
- }
-
- public function setParams($params)
- {
- $this->_params = $params;
- }
-
- public function getParams()
- {
- return $this->_params;
- }
-
- public function createInstance()
- {
- $instance = $this->_createInstanceByClass($this->getClass(), $this->getParams());
- $this->_processCallbacks($instance);
- if (!is_object($instance))
- {
- /**
- * @todo Throw exception (No instance created).
- */
- throw new Exception('No instance created for class: '.$this->getClass());
- }
- return $instance;
- }
-
- /**
- * Process callback functions.
- *
- * @param object $instance The instance for the callback functions.
- * @return mixed
- */
- protected function _processCallbacks($instance)
- {
- $callbacks = $this->getCallbacks();
- if (empty($callbacks))
- {
- return;
- }
- if (!is_array($callbacks))
- {
- $callbacks = array($callbacks);
- }
-
- // Run callback functions.
- foreach ($callbacks as $callback)
- {
- if (!isset($callback['method']))
- {
- /**
- * @todo Throw exception ('No method definied for callback')
- */
- continue;
- }
- if (method_exists($instance, $callback['method']))
- {
- $callback['params'] = isset($callback['params']) ? $callback['params'] : array();
- $params = $this->_fixDependencis($callback['params']);
- call_user_func_array(array($instance, $callback['method']), $params);
- }
- }
- }
-
- /**
- * Create instacne based on class.
- * If the given class not found, try the fallbacks until the fallback limit is reached.
- *
- * @param string $class Name (or alias) of the class.
- * @param array $params OPTIONAL Parameters for __construct()
- * @param integer $fallbackLevel Fallback levels.
- * @return null|\class
- */
- protected function _createInstanceByClass($class, $params = array(), $fallbackLevel = 0)
- {
- if (!class_exists($class, true))
- {
- if ($fallbackLevel > $this->_fallbackLevelLimit)
- {
- return null;
- }
- $fallbackLevel++;
- return $this->_createInstanceByClass($this->_getFallbackClass($class, $fallbackLevel), $params, $fallbackLevel);
- }
- $params = $this->_fixDependencis($params);
- $params = array_values($params);
- /**
- * Most of time, the construct needs 3 params at most.
- */
- switch (count($params))
- {
- case 0:
- {
- return new $class();
- }
- case 1:
- {
- return new $class($params[0]);
- }
- case 2:
- {
- return new $class($params[0], $params[1]);
- }
- case 3:
- {
- return new $class($params[0], $params[1], $params[2]);
- }
- default:
- {
- $ref = new ReflectionClass($class);
- return $ref->newInstanceArgs($params);
- }
- }
- }
-
- /**
- * Get the fallback class name.
- *
- * @param string $class Alias of the class.
- * @param integer $fallbackLevel Fallback level.
- * @return string Name of the class.
- */
- protected function _getFallbackClass($class, $fallbackLevel = 1)
- {
- /**
- * @todo More fall backs could be put here.
- */
- switch ($fallbackLevel)
- {
- case 1:
- {
- $prefix = 'Balance_Lib_Model_';
- break;
- }
- default:
- {
- $prefix = 'Balance_Lib_Model_';
- break;
- }
- }
- return $prefix.str_replace(' ', '_', ucwords(str_replace('_', ' ', $class)));
- }
- }
- ?>