PHP Classes

File: lib/select.php

Recommend this page to a friend!
  Classes of Devis Lucato   Select   lib/select.php   Download  
File: lib/select.php
Role: Class source
Content type: text/plain
Description: class
Class: Select
Locate classes that provide named services
Author: By
Last change: Update of lib/select.php
Date: 3 months ago
Size: 12,003 bytes
 

Contents

Class file image Download
<?php /** * Copyright 2011 Devis Lucato <http://lucato.it> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Service locator interface */ require dirname(__FILE__) . '/iselect.php'; /** * Service locator exceptions */ class Select_Exception extends \Exception {} class Select_InvalidClass_Exception extends Select_Exception { } class Select_TooManyParameters_Exception extends Select_Exception { } class Select_MissingDependency_Exception extends Select_Exception { } class Select_UndefinedMethod_Exception extends Select_Exception { } class Select_InvalidParameters_Exception extends Select_Exception { } /** * Service locator container * * Allows to inject classes and components/services at run time to replace * behaviour and mock dependencies * * How-to extend the class with a custom namespace: * * class My_DI extends Select { * const DEFAULT_NAMESPACE = 'My_'; * static protected $_namespace = self::DEFAULT_NAMESPACE; * } * * class My_Mailer { * } * * My_DI::getClass('Mailer') returns 'My_Mailer' */ class Select implements iSelect { /** * @var string Default NS (copy and customise to extend the class) * @wtf http://j.mp/paamayim-nekudotayim */ const DEFAULT_NAMESPACE = ''; /** * @var string Class name space (copy without change to extend the class) */ static protected $_namespace = self::DEFAULT_NAMESPACE; /** * @var array Map name:class Class names replacements */ static protected $_classes = array(); /** * @var array Map name:object Dependent-on oObjects */ static protected $_dependencies = array(); /** * @var array Map name:object Singletons container */ static protected $_singletons = array(); /** * @var array Map name:class Class lookup cache */ static protected $_cachedClassLookups = array(); /** * Set a new class name space * * @param string $namespace Namespace */ static public function setNamespace($namespace) { static::$_namespace = $namespace; static::resetCache(); } /** * Restore the initial class name space */ static public function resetNamespace() { static::$_namespace = static::DEFAULT_NAMESPACE; static::resetCache(); } /** * Replace an original class with a new one * * @param string $classNoNS Original name, withouth namespace, * ie "Mail_Transport_Uploader" * instead of "Zend_Mail_Transport_Uploader" * @param string $replacement New class name, complete of namespace, * ie "SomeApp_SomeClass" */ static public function replaceClass($classNoNS, $replacement) { static::$_classes[$classNoNS] = $replacement; static::$_cachedClassLookups[$classNoNS] = $replacement; } /** * Remove cached lookups */ static public function resetCache() { static::$_cachedClassLookups = array(); } /** * Get class name * * @param string $classNoNS Original name, without namespace * * @return string class */ static public function getClass($classNoNS) { return static::_getClass($classNoNS, false); } /** * Restore original name for a class * * @param string $classNoNS Original name, without namespace */ static public function resetClass($classNoNS) { unset(static::$_classes[$classNoNS]); if (isset(static::$_cachedClassLookups[$classNoNS])) unset(static::$_cachedClassLookups[$classNoNS]); } /** * Remove all class replacements */ static public function resetClasses() { static::$_classes = array(); static::resetCache(); } /** * Remove all stored dependencies */ static public function resetDependencies() { static::$_dependencies = array(); static::$_singletons = array(); } /** * Restore the class to initial status */ static public function reset() { static::resetNamespace(); static::resetClasses(); static::resetDependencies(); } /** * Return a new object instance of the class * * @param string $classNoNS Name of the class, without namespace * * @throws Select_TooManyParameters_Exception * * @return <$classNoNS> New instance */ static public function create($classNoNS) { $parameters = func_get_args(); array_shift($parameters); return static::_create($classNoNS, $parameters); } /** * Magic getter/setter, allows getMailer/setMailer/setLogger/getLogger etc. * * @param string $name * @param array $arguments * * @throws Select_InvalidParameters_Exception * @throws Select_UndefinedMethod_Exception * * @return mixed */ static public function __callStatic($methodname, $arguments) { $prefix = substr($methodname, 0, 3); $name = strtoupper(substr($methodname, 3)); switch ($prefix) { case 'def': $count = count($arguments); switch ($count) { case 1: return static::_defineDependency($name, $arguments[0]); case 2: return static::_defineDependency($name, $arguments[0], $arguments[1]); case 3: return static::_defineDependency($name, $arguments[0], $arguments[1], $arguments[2]); } throw new Select_InvalidParameters_Exception("Invalid call to `$name`"); case 'ini': $count = count($arguments); switch ($count) { case 1: static::_defineDependency($name, $arguments[0]); break; case 2: static::_defineDependency($name, $arguments[0], $arguments[1]); break; case 3: static::_defineDependency($name, $arguments[0], $arguments[1], $arguments[2]); break; default: throw new Select_InvalidParameters_Exception("Invalid call to `$name`"); } return static::_getDependency($name); case 'set': if (count($arguments) != 1) throw new Select_InvalidParameters_Exception("Invalid call to `$name`"); return static::_storeDependency($name, $arguments[0]); case 'get': return static::_getDependency($name); } throw new Select_UndefinedMethod_Exception("Call to undefined method `$methodname`"); } // **************************************************************************************************** /** * Return a new object instance of the class * * @param string $classNoNS Name of the class, without namespace * @param array $p * * @throws Select_TooManyParameters_Exception * * @return <$classNoNS> New instance */ static protected function _create($classNoNS, $p) { $class = static::_getClass($classNoNS); $count = count($p); switch ($count) { case 0: return new $class(); case 1: return new $class($p[0]); case 2: return new $class($p[0], $p[1]); case 3: return new $class($p[0], $p[1], $p[2]); case 4: return new $class($p[0], $p[1], $p[2], $p[3]); case 5: return new $class($p[0], $p[1], $p[2], $p[3], $p[4]); case 6: return new $class($p[0], $p[1], $p[2], $p[3], $p[4], $p[5]); } throw new Select_TooManyParameters_Exception('Too many constructor parameters'); } /** * Store dependency definition with constructor parameters * * @param string $name * @param string $class * @param array $parameters * @param boolean $isSingleton */ static protected function _defineDependency($name, $class, $parameters = array(), $isSingleton = true) { static::$_dependencies[$name] = array('class' => $class, 'parameters' => $parameters, 'isSingleton' => $isSingleton); if (isset(static::$_singletons[$name])) unset(static::$_singletons[$name]); } /** * Store component/service dependency * * @param string $name * @param object $object */ static protected function _storeDependency($name, $object) { if (!is_object($object)) throw new Select_InvalidParameters_Exception('Dependency must be an object'); static::$_dependencies[$name]['class'] = null; static::$_dependencies[$name]['parameters'] = null; static::$_dependencies[$name]['isSingleton'] = true; static::$_singletons[$name] = $object; } /** * Return a component/service stored in the class * * @param string $name * * @throws Select_MissingDependency_Exception * * @return object */ static protected function _getDependency($name) { if (!isset(static::$_dependencies[$name])) throw new Select_MissingDependency_Exception("Dependency `$name` not found"); if (static::$_dependencies[$name]['isSingleton']) { if (!isset(static::$_singletons[$name])) { $class = static::getClass(static::$_dependencies[$name]['class']); $parameters = static::$_dependencies[$name]['parameters']; static::$_singletons[$name] = static::_create($class, $parameters); } return static::$_singletons[$name]; } $class = static::getClass(static::$_dependencies[$name]['class']); $parameters = static::$_dependencies[$name]['parameters']; return static::_create($class, $parameters); } /** * Return full class name * * @param string $classNoNS Name of the class, without namespace * * @throws Select_InvalidClass_Exception * * @return string Class name */ static protected function _getClass($classNoNS, $checkIfExists = true) { if (isset(static::$_classes[$classNoNS])) { $class = static::$_classes[$classNoNS]; } else { if (isset(static::$_cachedClassLookups[$classNoNS])) { $class =static::$_cachedClassLookups[$classNoNS]; } else { $classWNS = static::$_namespace . $classNoNS; if (class_exists($classWNS)) { $class = $classWNS; } elseif (class_exists($classNoNS)) { $class = $classNoNS; } elseif (!$checkIfExists) { $class = $classWNS; } else { $class = $classNoNS; } // @note speed up successive searches ~10% static::$_cachedClassLookups[$classNoNS] = $class; } } if ($checkIfExists && !class_exists($class)) { $classWNS = isset($classWNS) ? $classWNS : static::$_namespace . $classNoNS ; throw new Select_InvalidClass_Exception("Unable to find class `$class` [`$classWNS`]"); } return $class; } }