Create factory for plugins that resources can be registered with.
This commit is contained in:
parent
f88df400f0
commit
e1d8239e8a
5 changed files with 481 additions and 2 deletions
145
PHPCI/Plugin/Util/Factory.php
Normal file
145
PHPCI/Plugin/Util/Factory.php
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
namespace PHPCI\Plugin\Util;
|
||||
|
||||
|
||||
|
||||
class Factory {
|
||||
|
||||
const TYPE_Array = "array";
|
||||
const TYPE_Callable = "callable";
|
||||
|
||||
private $currentPluginOptions;
|
||||
|
||||
/**
|
||||
* @var \Pimple
|
||||
*/
|
||||
private $container;
|
||||
|
||||
function __construct(\Pimple $container = null)
|
||||
{
|
||||
if ($container) {
|
||||
$this->container = $container;
|
||||
}
|
||||
else {
|
||||
$this->container = new \Pimple();
|
||||
}
|
||||
|
||||
$self = $this;
|
||||
$this->registerResource(
|
||||
function() use ($self) {
|
||||
return $self->getLastOptions();
|
||||
},
|
||||
'options',
|
||||
'array'
|
||||
);
|
||||
}
|
||||
|
||||
public function getLastOptions() {
|
||||
return $this->currentPluginOptions;
|
||||
}
|
||||
|
||||
public function buildPlugin($className, array $options = array())
|
||||
{
|
||||
$this->currentPluginOptions = $options;
|
||||
|
||||
$reflectedPlugin = new \ReflectionClass($className);
|
||||
|
||||
$constructor = $reflectedPlugin->getConstructor();
|
||||
|
||||
if ($constructor) {
|
||||
$argsToUse = array();
|
||||
foreach($constructor->getParameters() as $param) {
|
||||
$argsToUse = $this->addArgFromParam($argsToUse, $param);
|
||||
}
|
||||
$plugin = $reflectedPlugin->newInstanceArgs($argsToUse);
|
||||
} else {
|
||||
$plugin = $reflectedPlugin->newInstance();
|
||||
}
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $loader
|
||||
* @param string|null $name
|
||||
* @param string|null $type
|
||||
* @throws \InvalidArgumentException
|
||||
* @internal param mixed $resource
|
||||
*/
|
||||
public function registerResource(callable $loader,
|
||||
$name = null,
|
||||
$type = null
|
||||
)
|
||||
{
|
||||
if ($name === null && $type === null) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Type or Name must be specified"
|
||||
);
|
||||
}
|
||||
|
||||
$resourceID = $this->getInternalID($type, $name);
|
||||
|
||||
$this->container[$resourceID] = $loader;
|
||||
}
|
||||
|
||||
private function getInternalID($type = null, $name = null)
|
||||
{
|
||||
$type = $type ? : "";
|
||||
$name = $name ? : "";
|
||||
return $type . "-" . $name;
|
||||
}
|
||||
|
||||
private function getResourceFor($type = null, $name = null)
|
||||
{
|
||||
$fullId = $this->getInternalID($type, $name);
|
||||
if (isset($this->container[$fullId])) {
|
||||
return $this->container[$fullId];
|
||||
}
|
||||
|
||||
$typeOnlyID = $this->getInternalID($type, null);
|
||||
if (isset($this->container[$typeOnlyID])) {
|
||||
return $this->container[$typeOnlyID];
|
||||
}
|
||||
|
||||
$nameOnlyID = $this->getInternalID(null, $name);
|
||||
if (isset($this->container[$nameOnlyID])) {
|
||||
return $this->container[$nameOnlyID];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getParamType(\ReflectionParameter $param)
|
||||
{
|
||||
$class = $param->getClass();
|
||||
if ($class) {
|
||||
return $class->getName();
|
||||
} elseif($param->isArray()) {
|
||||
return self::TYPE_Array;
|
||||
} elseif($param->isCallable()) {
|
||||
return self::TYPE_Callable;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function addArgFromParam($existingArgs, \ReflectionParameter $param)
|
||||
{
|
||||
$name = $param->getName();
|
||||
$type = $this->getParamType($param);
|
||||
$arg = $this->getResourceFor($type, $name);
|
||||
|
||||
if ($arg !== null) {
|
||||
$existingArgs[] = $arg;
|
||||
} elseif ($arg === null && $param->isOptional()) {
|
||||
$existingArgs[] = $param->getDefaultValue();
|
||||
} else {
|
||||
throw new \DomainException(
|
||||
"Unsatisfied dependency: " . $param->getName()
|
||||
);
|
||||
}
|
||||
|
||||
return $existingArgs;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue