Skip to content

Commit

Permalink
Started working on symfony container compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
SuRaMoN committed Jul 9, 2018
1 parent 61cea39 commit 267348d
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 93 deletions.
93 changes: 66 additions & 27 deletions src/AutoPimple/AutoPimple.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,54 @@

namespace AutoPimple;

use Exception;
use InvalidArgumentException;
use Pimple;
use ReflectionClass;
use ReflectionMethod;

/**
* Extension for pimple allowing auto-wiring
*/
class AutoPimple extends Pimple
{
protected $cacheFolder;
protected $cacheData = array();
protected $prefixMap;
protected $aliases = array();
/** @var string */
private $cacheFolder;

public function __construct(array $prefixMap = array(), array $values = array(), $cacheFolder = null)
/** @var array<string,string> */
private $cacheData = [];

/** @var array<string,string> */
private $prefixMap;

/** @var array<string,string> */
private $aliases = [];

public function __construct(array $prefixMap = [], array $values = [], $cacheFolder = null)
{
parent::__construct($values);
$this->cacheFolder = $cacheFolder;
if (null !== $cacheFolder && is_dir($cacheFolder)) {
$this->cacheData = @include("{$this->cacheFolder}/autopimple.php");
}
if (false === $this->cacheData) {
$this->cacheData = array();
$this->cacheData = [];
}
$this->prefixMap = array_merge(array('' => ''), $prefixMap);
$this->prefixMap = array_merge(['' => ''], $prefixMap);
}

public function extend($id, $callable)
/**
* {@inheritdoc}
*/
public function extend($id, $callable): ExtendedService
{
$hasDefinedService = array_key_exists($id, $this->values);
$baseService = $hasDefinedService ? $this->values[$id] : null;
return $this->values[$id] = new ExtendedService($id, $baseService, $callable, $hasDefinedService, $this);
}

/**
* {@inheritdoc}
*/
public static function share($callable)
{
if (! is_object($callable) || ! method_exists($callable, '__invoke')) {
Expand All @@ -51,6 +67,22 @@ public static function share($callable)
};
}

public function get(string $className)
{
$serviceName = StringUtil::underscore($className);
foreach ($this->prefixMap as $prefix => $newPrefix) {
if ('' != $prefix && strpos($serviceName, $prefix) === 0) {
$serviceName = $newPrefix . substr($serviceName, strlen($prefix));
break;
}
}
$service = $this->offsetGet($serviceName);
if (!$service instanceof $className) {
throw new Exception('Expected service of class "' . $className . '"');
}
return $service;
}

/**
* Creates a factory for a given classname and this factory will use auto-injection
*/
Expand Down Expand Up @@ -92,19 +124,20 @@ public function createFactory($factory)
return new Factory($factory);
}

public function createServiceFactory($serviceId, array $arguments = array())
public function createServiceFactory($serviceId, array $arguments = [])
{
$self = $this;
return new Factory(function(array $arguments = array()) use ($self, $serviceId) {
return new Factory(function(array $arguments = []) use ($self, $serviceId) {
return $self->getModified($serviceId, $arguments);
});
}

public function alias($from, $to)
{
$pairKey = serialize(array($from, $to));
$pairKey = serialize([$from, $to]);
if ($from == $to || (array_key_exists($from, $this->values) && array_key_exists($pairKey, $this->aliases) &&
$this->values[$from] === $this->aliases[$pairKey])) {
$this->values[$from] === $this->aliases[$pairKey])
) {
return;
}
$self = $this;
Expand All @@ -116,7 +149,7 @@ public function serviceMethod($serviceId, $methodName)
$self = $this;
return function() use ($self, $serviceId, $methodName) {
$arguments = func_get_args();
return call_user_func_array(array($self->offsetGet($serviceId), $methodName), $arguments);
return call_user_func_array([$self->offsetGet($serviceId), $methodName], $arguments);
};
}

Expand All @@ -128,7 +161,7 @@ public function serviceMethod($serviceId, $methodName)
* getModified('a', array('c' => $otherC));
* The c parameter will be injected with the $otherC variable and b will be auto-injected like always
*/
public function getModified($id, array $modifiedInjectables = array())
public function getModified($id, array $modifiedInjectables = [])
{
list($prefixedId, $service) = $this->serviceFactoryAndNameFromPartialServiceId($id, $modifiedInjectables);
if (null === $prefixedId) {
Expand All @@ -138,6 +171,9 @@ public function getModified($id, array $modifiedInjectables = array())
return $isFactory ? $service($this) : $service;
}

/**
* {@inheritdoc}
*/
public function offsetExists($id)
{
list($prefixedId, $serviceFactory) = $this->serviceFactoryAndNameFromPartialServiceId($id);
Expand All @@ -151,12 +187,15 @@ public function offsetExists($id)
return true;
}

/**
* {@inheritdoc}
*/
public function offsetGet($id)
{
$this->offsetExists($id);
if (array_key_exists($id, $this->values) && $this->values[$id] instanceof ExtendedService) {
return $this->getExtendedService($this->values[$id]);
} else if (array_key_exists($id, $this->values) && $this->values[$id] instanceof AliasedService) {
} elseif (array_key_exists($id, $this->values) && $this->values[$id] instanceof AliasedService) {
return $this->offsetGet($this->values[$id]->getTarget());
} else {
return parent::offsetGet($id);
Expand All @@ -168,7 +207,7 @@ public function getExtendedService(ExtendedService $sharedService)
$id = $sharedService->getId();
$originalService = $this->values[$id];
$this->values[$id] = $sharedService;
while($this->values[$id] instanceof ExtendedService) {
while ($this->values[$id] instanceof ExtendedService) {
$extender = $this->values[$id]->getExtender();
if ($this->values[$id]->getHasDefinedService()) {
$this->values[$id] = $this->values[$id]->getBaseService();
Expand Down Expand Up @@ -196,17 +235,17 @@ protected function writeCache($key, $value)
}
}

protected function serviceFactoryAndNameFromPartialServiceId($id, array $modifiedInjectables = array())
protected function serviceFactoryAndNameFromPartialServiceId($id, array $modifiedInjectables = [])
{
if (count($modifiedInjectables) == 0) {
foreach ($this->prefixMap as $to => $froms) {
foreach ((array) $froms as $from) {
if ($to != '' && strpos($id, $to) !== 0) {
if ('' != $to && strpos($id, $to) !== 0) {
continue;
}
$prefixedId = $from . substr($id, strlen($to));
if (array_key_exists($prefixedId, $this->values)) {
return array($prefixedId, $this->values[$prefixedId]);
return [$prefixedId, $this->values[$prefixedId]];
}
}
}
Expand All @@ -223,15 +262,15 @@ protected function serviceFactoryAndNameFromPartialServiceId($id, array $modifie
}
$serviceFactory = $this->serviceFactoryFromFullServiceName($prefixedId, $modifiedInjectables);
if (null !== $serviceFactory) {
return array($prefixedId, $serviceFactory);
return [$prefixedId, $serviceFactory];
}
}
}

return array(null, null);
return [null, null];
}

protected function serviceFactoryFromFullServiceName($id, array $modifiedInjectables = array())
protected function serviceFactoryFromFullServiceName($id, array $modifiedInjectables = [])
{
if (parent::offsetExists($id) && count($modifiedInjectables) == 0) {
return $this->values[$id];
Expand All @@ -250,7 +289,7 @@ protected function serviceFactoryFromFullServiceName($id, array $modifiedInjecta
$this->writeCache("no_class:$id", true);
}

protected function serviceFactoryFromClassName($className, $serviceName = null, array $modifiedInjectables = array())
protected function serviceFactoryFromClassName($className, $serviceName = null, array $modifiedInjectables = [])
{
$serviceReflector = new ReflectionClass($className);
$serviceFactoryCallback = $this->serviceFactoryFromReflector($serviceReflector, $serviceName, $modifiedInjectables);
Expand All @@ -260,14 +299,14 @@ protected function serviceFactoryFromClassName($className, $serviceName = null,
return $serviceFactoryCallback;
}

protected function serviceFactoryFromReflector(ReflectionClass $serviceReflector, $serviceName = null, array $modifiedInjectables = array())
protected function serviceFactoryFromReflector(ReflectionClass $serviceReflector, $serviceName = null, array $modifiedInjectables = [])
{
if (! $serviceReflector->hasMethod('__construct')) {
$dependencies = array();
$dependencies = [];
} else {
$constructorReflector = $serviceReflector->getMethod('__construct');

$dependencies = array();
$dependencies = [];
foreach ($constructorReflector->getParameters() as $parameter) {
$underscoredParameterName = StringUtil::underscore(ucfirst($parameter->getName()));
if (array_key_exists($underscoredParameterName, $modifiedInjectables)) {
Expand Down
80 changes: 40 additions & 40 deletions src/AutoPimple/ExtendedService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,45 @@

namespace AutoPimple;

class ExtendedService
final class ExtendedService
{
protected $pimple;
protected $id;
protected $baseService;
protected $hasDefinedService;
protected $extender;

public function __construct($id, $baseService, $extender, $hasDefinedService, AutoPimple $pimple)
{
$this->pimple = $pimple;
$this->id = $id;
$this->baseService = $baseService;
$this->extender = $extender;
$this->hasDefinedService = $hasDefinedService;
}

public function __invoke()
{
return $this->pimple->getExtendedService($this);
}

public function getExtender()
{
return $this->extender;
}

public function getHasDefinedService()
{
return $this->hasDefinedService;
}

public function getBaseService()
{
return $this->baseService;
}

public function getId()
{
return $this->id;
}
private $pimple;
private $id;
private $baseService;
private $hasDefinedService;
private $extender;

public function __construct(string $id, $baseService, $extender, bool $hasDefinedService, AutoPimple $pimple)
{
$this->pimple = $pimple;
$this->id = $id;
$this->baseService = $baseService;
$this->extender = $extender;
$this->hasDefinedService = $hasDefinedService;
}

public function __invoke()
{
return $this->pimple->getExtendedService($this);
}

public function getExtender()
{
return $this->extender;
}

public function getHasDefinedService()
{
return $this->hasDefinedService;
}

public function getBaseService()
{
return $this->baseService;
}

public function getId()
{
return $this->id;
}
}
4 changes: 2 additions & 2 deletions src/AutoPimple/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace AutoPimple;

class Factory
final class Factory
{
protected $factoryCallback;
private $factoryCallback;

public function __construct($factory)
{
Expand Down
48 changes: 24 additions & 24 deletions src/AutoPimple/StringUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@

namespace AutoPimple;

class StringUtil
final class StringUtil
{
public static function camelize($name)
{
$name = preg_replace_callback('/(\.|__|_|-|^)(.)/', function ($m) {
$name = ('.' == $m[1] ? '\\' : '');
if ($m['1'] == '__') {
return $name . '_' . strtoupper($m[2]);
} else {
return $name . ('-' == $m[1] ? $m[2] : strtoupper($m[2]));
}
}, $name);
return $name;
}
public static function camelize($name)
{
$name = preg_replace_callback('/(\.|__|_|-|^)(.)/', function ($m) {
$name = ('.' == $m[1] ? '\\' : '');
if ($m['1'] == '__') {
return $name . '_' . strtoupper($m[2]);
} else {
return $name . ('-' == $m[1] ? $m[2] : strtoupper($m[2]));
}
}, $name);
return $name;
}

public static function underscore($name)
{
$name = str_replace('\\', '.', $name);
$name = preg_replace_callback('/(?<!^|\.)[A-Z]/', function ($m) {
return '_' . $m[0];
}, $name);
$name = preg_replace_callback('/(^|\.)([a-z])/', function ($m) {
return '-' . $m[2];
}, $name);
return strtolower($name);
}
public static function underscore($name)
{
$name = str_replace('\\', '.', $name);
$name = preg_replace_callback('/(?<!^|\.)[A-Z]/', function ($m) {
return '_' . $m[0];
}, $name);
$name = preg_replace_callback('/(^|\.)([a-z])/', function ($m) {
return '-' . $m[2];
}, $name);
return strtolower($name);
}
}

0 comments on commit 267348d

Please sign in to comment.