generated from yiisoft/package-template
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
54 changed files
with
2,687 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# _____ Change Log | ||
# Yii Definitions Change Log | ||
|
||
## 1.0.0 under development | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Definitions; | ||
|
||
use Yiisoft\Definitions\Contract\DefinitionInterface; | ||
use Yiisoft\Definitions\Contract\DependencyResolverInterface; | ||
use Yiisoft\Definitions\Exception\InvalidConfigException; | ||
use Yiisoft\Definitions\Exception\NotFoundException; | ||
use Yiisoft\Definitions\Exception\NotInstantiableException; | ||
use Yiisoft\Definitions\Infrastructure\ArrayDefinitionBuilder; | ||
|
||
use function count; | ||
|
||
/** | ||
* Builds object by array config | ||
* | ||
* @psalm-type MethodOrPropertyItem = array{0:string,1:string,2:mixed} | ||
* @psalm-type ArrayDefinitionConfig = array{class:class-string,'__construct()'?:array}&array<string, mixed> | ||
*/ | ||
final class ArrayDefinition implements DefinitionInterface | ||
{ | ||
public const CLASS_NAME = 'class'; | ||
public const CONSTRUCTOR = '__construct()'; | ||
|
||
public const TYPE_PROPERTY = 'property'; | ||
public const TYPE_METHOD = 'method'; | ||
|
||
/** | ||
* @psalm-var class-string | ||
*/ | ||
private string $class; | ||
private array $constructorArguments; | ||
|
||
/** | ||
* @psalm-var array<string, MethodOrPropertyItem> | ||
*/ | ||
private array $methodsAndProperties; | ||
|
||
/** | ||
* @psalm-param class-string $class | ||
* @psalm-param array<string, MethodOrPropertyItem> $methodsAndProperties | ||
*/ | ||
private function __construct(string $class, array $constructorArguments, array $methodsAndProperties) | ||
{ | ||
$this->class = $class; | ||
$this->constructorArguments = $constructorArguments; | ||
$this->methodsAndProperties = $methodsAndProperties; | ||
} | ||
|
||
/** | ||
* @psalm-param ArrayDefinitionConfig $config | ||
*/ | ||
public static function fromConfig(array $config): self | ||
{ | ||
return new self( | ||
$config[self::CLASS_NAME], | ||
$config[self::CONSTRUCTOR] ?? [], | ||
self::getMethodsAndPropertiesFromConfig($config) | ||
); | ||
} | ||
|
||
/** | ||
* @psalm-param class-string $class | ||
* @psalm-param array<string, MethodOrPropertyItem> $methodsAndProperties | ||
*/ | ||
public static function fromPreparedData(string $class, array $constructorArguments = [], array $methodsAndProperties = []): self | ||
{ | ||
return new self($class, $constructorArguments, $methodsAndProperties); | ||
} | ||
|
||
/** | ||
* @psalm-param array<string, mixed> $config | ||
* | ||
* @psalm-return array<string, MethodOrPropertyItem> | ||
*/ | ||
private static function getMethodsAndPropertiesFromConfig(array $config): array | ||
{ | ||
$methodsAndProperties = []; | ||
|
||
/** @var mixed $value */ | ||
foreach ($config as $key => $value) { | ||
if ($key === self::CONSTRUCTOR) { | ||
continue; | ||
} | ||
|
||
if (count($methodArray = explode('()', $key)) === 2) { | ||
$methodsAndProperties[$key] = [self::TYPE_METHOD, $methodArray[0], $value]; | ||
} elseif (count($propertyArray = explode('$', $key)) === 2) { | ||
$methodsAndProperties[$key] = [self::TYPE_PROPERTY, $propertyArray[1], $value]; | ||
} | ||
} | ||
|
||
return $methodsAndProperties; | ||
} | ||
|
||
/** | ||
* @psalm-return class-string | ||
*/ | ||
public function getClass(): string | ||
{ | ||
return $this->class; | ||
} | ||
|
||
public function getConstructorArguments(): array | ||
{ | ||
return $this->constructorArguments; | ||
} | ||
|
||
/** | ||
* @psalm-return array<string, MethodOrPropertyItem> | ||
*/ | ||
public function getMethodsAndProperties(): array | ||
{ | ||
return $this->methodsAndProperties; | ||
} | ||
|
||
/** | ||
* @throws NotFoundException | ||
* @throws NotInstantiableException | ||
* @throws InvalidConfigException | ||
*/ | ||
public function resolve(DependencyResolverInterface $container): object | ||
{ | ||
return ArrayDefinitionBuilder::getInstance()->build($container, $this); | ||
} | ||
|
||
public function merge(self $other): self | ||
{ | ||
$new = clone $this; | ||
$new->class = $other->class; | ||
$new->constructorArguments = $this->mergeArguments($this->constructorArguments, $other->constructorArguments); | ||
|
||
$methodsAndProperties = $this->methodsAndProperties; | ||
foreach ($other->methodsAndProperties as $key => $item) { | ||
if ($item[0] === self::TYPE_PROPERTY) { | ||
$methodsAndProperties[$key] = $item; | ||
} elseif ($item[0] === self::TYPE_METHOD) { | ||
/** @psalm-suppress MixedArgument, MixedAssignment */ | ||
$arguments = isset($methodsAndProperties[$key]) | ||
? $this->mergeArguments($methodsAndProperties[$key][2], $item[2]) | ||
: $item[2]; | ||
$methodsAndProperties[$key] = [$item[0], $item[1], $arguments]; | ||
} | ||
} | ||
$new->methodsAndProperties = $methodsAndProperties; | ||
|
||
return $new; | ||
} | ||
|
||
private function mergeArguments(array $selfArguments, array $otherArguments): array | ||
{ | ||
/** @var mixed $argument */ | ||
foreach ($otherArguments as $name => $argument) { | ||
/** @var mixed */ | ||
$selfArguments[$name] = $argument; | ||
} | ||
|
||
return $selfArguments; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Definitions; | ||
|
||
use ReflectionMethod; | ||
use Yiisoft\Definitions\Contract\DefinitionInterface; | ||
use Yiisoft\Definitions\Contract\DependencyResolverInterface; | ||
|
||
use function is_array; | ||
use function is_object; | ||
|
||
final class CallableDefinition implements DefinitionInterface | ||
{ | ||
/** | ||
* @var array|callable | ||
* @psalm-var callable|array{0:class-string,1:string} | ||
*/ | ||
private $method; | ||
|
||
/** | ||
* @param array|callable $method | ||
* | ||
* @psalm-param callable|array{0:class-string,1:string} $method | ||
*/ | ||
public function __construct($method) | ||
{ | ||
$this->method = $method; | ||
} | ||
|
||
public function resolve(DependencyResolverInterface $container) | ||
{ | ||
$callable = $this->prepareCallable($this->method, $container); | ||
|
||
/** @psalm-suppress MixedMethodCall */ | ||
return $container->invoke($callable); | ||
} | ||
|
||
/** | ||
* @param array|callable $callable | ||
* | ||
* @psalm-param callable|array{0:class-string,1:string} $callable | ||
*/ | ||
private function prepareCallable($callable, DependencyResolverInterface $container): callable | ||
{ | ||
if (is_array($callable) && !is_object($callable[0])) { | ||
$reflection = new ReflectionMethod($callable[0], $callable[1]); | ||
if (!$reflection->isStatic()) { | ||
/** @var mixed */ | ||
$callable[0] = $container->get($callable[0]); | ||
} | ||
} | ||
|
||
return $callable; | ||
} | ||
} |
Oops, something went wrong.