238 lines
8.7 KiB
PHP
238 lines
8.7 KiB
PHP
<?php
|
|
|
|
|
|
namespace Luracast\Restler;
|
|
|
|
/**
|
|
* Scope resolution class, manages instantiation and acts as a dependency
|
|
* injection container
|
|
*
|
|
* @category Framework
|
|
* @package Restler
|
|
* @author R.Arul Kumaran <arul@luracast.com>
|
|
* @copyright 2010 Luracast
|
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
* @link http://luracast.com/products/restler/
|
|
*
|
|
*/
|
|
class Scope
|
|
{
|
|
public static $classAliases = array(
|
|
|
|
//Core
|
|
'Restler' => 'Luracast\Restler\Restler',
|
|
|
|
//Format classes
|
|
'AmfFormat' => 'Luracast\Restler\Format\AmfFormat',
|
|
'JsFormat' => 'Luracast\Restler\Format\JsFormat',
|
|
'JsonFormat' => 'Luracast\Restler\Format\JsonFormat',
|
|
'HtmlFormat' => 'Luracast\Restler\Format\HtmlFormat',
|
|
'PlistFormat' => 'Luracast\Restler\Format\PlistFormat',
|
|
'UploadFormat' => 'Luracast\Restler\Format\UploadFormat',
|
|
'UrlEncodedFormat' => 'Luracast\Restler\Format\UrlEncodedFormat',
|
|
'XmlFormat' => 'Luracast\Restler\Format\XmlFormat',
|
|
'YamlFormat' => 'Luracast\Restler\Format\YamlFormat',
|
|
'CsvFormat' => 'Luracast\Restler\Format\CsvFormat',
|
|
'TsvFormat' => 'Luracast\Restler\Format\TsvFormat',
|
|
|
|
//Filter classes
|
|
'RateLimit' => 'Luracast\Restler\Filter\RateLimit',
|
|
|
|
//UI classes
|
|
'Forms' => 'Luracast\Restler\UI\Forms',
|
|
'Nav' => 'Luracast\Restler\UI\Nav',
|
|
'Emmet' => 'Luracast\Restler\UI\Emmet',
|
|
'T' => 'Luracast\Restler\UI\Tags',
|
|
|
|
//API classes
|
|
'Resources' => 'Luracast\Restler\Resources',
|
|
'Explorer' => 'Luracast\Restler\Explorer\v2\Explorer',
|
|
'Explorer1' => 'Luracast\Restler\Explorer\v1\Explorer',
|
|
'Explorer2' => 'Luracast\Restler\Explorer\v2\Explorer',
|
|
|
|
//Cache classes
|
|
'HumanReadableCache' => 'Luracast\Restler\HumanReadableCache',
|
|
'ApcCache' => 'Luracast\Restler\ApcCache',
|
|
'MemcacheCache' => 'Luracast\Restler\MemcacheCache',
|
|
|
|
//Utility classes
|
|
'Object' => 'Luracast\Restler\Data\Obj',
|
|
'Text' => 'Luracast\Restler\Data\Text',
|
|
'Arr' => 'Luracast\Restler\Data\Arr',
|
|
|
|
//Exception
|
|
'RestException' => 'Luracast\Restler\RestException'
|
|
);
|
|
/**
|
|
* @var null|Callable adding a resolver function that accepts
|
|
* the class name as the parameter and returns an instance of the class
|
|
* as a singleton. Allows the use of your favourite DI container
|
|
*/
|
|
public static $resolver = null;
|
|
public static $properties = array();
|
|
protected static $instances = array();
|
|
protected static $registry = array();
|
|
|
|
/**
|
|
* @param string $name
|
|
* @param callable $function
|
|
* @param bool $singleton
|
|
*/
|
|
public static function register($name, $function, $singleton = true)
|
|
{
|
|
static::$registry[$name] = (object)compact('function', 'singleton');
|
|
}
|
|
|
|
public static function set($name, $instance)
|
|
{
|
|
static::$instances[$name] = (object)array('instance' => $instance);
|
|
}
|
|
|
|
public static function get($name)
|
|
{
|
|
$r = null;
|
|
$initialized = false;
|
|
$properties = array();
|
|
if (array_key_exists($name, static::$instances)) {
|
|
$initialized = true;
|
|
$r = static::$instances[$name]->instance;
|
|
} elseif (!empty(static::$registry[$name])) {
|
|
$function = static::$registry[$name]->function;
|
|
$r = $function();
|
|
if (static::$registry[$name]->singleton) {
|
|
static::$instances[$name] = (object)array('instance' => $r);
|
|
}
|
|
} elseif (is_callable(static::$resolver) && false === stristr($name, 'Luracast\Restler')) {
|
|
$fullName = $name;
|
|
if (isset(static::$classAliases[$name])) {
|
|
$fullName = static::$classAliases[$name];
|
|
}
|
|
/** @var Callable $function */
|
|
$function = static::$resolver;
|
|
$r = $function($fullName);
|
|
static::$instances[$name] = (object)array('instance' => $r);
|
|
static::$instances[$name]->initPending = true;
|
|
} else {
|
|
$fullName = $name;
|
|
if (isset(static::$classAliases[$name])) {
|
|
$fullName = static::$classAliases[$name];
|
|
}
|
|
if (class_exists($fullName)) {
|
|
$shortName = Util::getShortName($name);
|
|
$r = new $fullName();
|
|
static::$instances[$name] = (object)array('instance' => $r);
|
|
if ($name != 'Restler') {
|
|
/** @var Restler restler */
|
|
$r->restler = static::get('Restler');
|
|
$m = Util::nestedValue($r->restler, 'apiMethodInfo', 'metadata');
|
|
if ($m) {
|
|
$properties = Util::nestedValue(
|
|
$m, 'class', $fullName,
|
|
CommentParser::$embeddedDataName
|
|
) ?: (Util::nestedValue(
|
|
$m, 'class', $shortName,
|
|
CommentParser::$embeddedDataName
|
|
) ?: array());
|
|
} else {
|
|
static::$instances[$name]->initPending = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (
|
|
$r instanceof iUseAuthentication &&
|
|
$r->restler && $r->restler->_authVerified &&
|
|
!isset(static::$instances[$name]->authVerified)
|
|
) {
|
|
static::$instances[$name]->authVerified = true;
|
|
$r->__setAuthenticationStatus($r->restler->_authenticated);
|
|
}
|
|
if (isset(static::$instances[$name]->initPending)) {
|
|
$m = Util::nestedValue($r->restler, 'apiMethodInfo', 'metadata');
|
|
$fullName = $name;
|
|
if (class_exists($name)) {
|
|
$shortName = Util::getShortName($name);
|
|
} else {
|
|
$shortName = $name;
|
|
if (isset(static::$classAliases[$name])) {
|
|
$fullName = static::$classAliases[$name];
|
|
}
|
|
}
|
|
if ($m) {
|
|
$properties = Util::nestedValue(
|
|
$m, 'class', $fullName,
|
|
CommentParser::$embeddedDataName
|
|
) ?: (Util::nestedValue(
|
|
$m, 'class', $shortName,
|
|
CommentParser::$embeddedDataName
|
|
) ?: array());
|
|
unset(static::$instances[$name]->initPending);
|
|
$initialized = false;
|
|
}
|
|
}
|
|
if (!$initialized && is_object($r)) {
|
|
$properties += static::$properties;
|
|
$objectVars = get_object_vars($r);
|
|
$className = get_class($r);
|
|
foreach ($properties as $property => $value) {
|
|
if (property_exists($className, $property)) {
|
|
//if not a static property
|
|
array_key_exists($property, $objectVars)
|
|
? $r->{$property} = $value
|
|
: $r::$$property = $value;
|
|
}
|
|
}
|
|
}
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* Get fully qualified class name for the given scope
|
|
*
|
|
* @param string $className
|
|
* @param array $scope local scope
|
|
*
|
|
* @return string|boolean returns the class name or false
|
|
*/
|
|
public static function resolve($className, array $scope)
|
|
{
|
|
if (empty($className) || !is_string($className)) {
|
|
return false;
|
|
}
|
|
|
|
if (self::isPrimitiveDataType($className)) {
|
|
return false;
|
|
}
|
|
|
|
$divider = '\\';
|
|
if ($className[0] == $divider) {
|
|
$qualified = trim($className, $divider);
|
|
} elseif (array_key_exists($className, $scope)) {
|
|
$qualified = $scope[$className];
|
|
} else {
|
|
$qualified = $scope['*'] . $className;
|
|
}
|
|
if (class_exists($qualified)) {
|
|
return $qualified;
|
|
}
|
|
if (isset(static::$classAliases[$className])) {
|
|
$qualified = static::$classAliases[$className];
|
|
if (class_exists($qualified)) {
|
|
return $qualified;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param string $stringName
|
|
*
|
|
* @return boolean
|
|
*/
|
|
private static function isPrimitiveDataType($stringName)
|
|
{
|
|
$primitiveDataTypes = array('Array', 'array', 'bool', 'boolean', 'float', 'int', 'integer', 'string');
|
|
return in_array($stringName, $primitiveDataTypes);
|
|
}
|
|
}
|