Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
os: >-
['ubuntu-latest', 'windows-latest']
php: >-
['7.4', '8.0', '8.1']
['8.0', '8.1']
21 changes: 21 additions & 0 deletions .github/workflows/rector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
on:
pull_request:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'infection.json.dist'
- 'psalm.xml'

name: rector

jobs:
rector:
uses: yiisoft/actions/.github/workflows/rector.yml@master
with:
os: >-
['ubuntu-latest']
php: >-
['8.0']
2 changes: 1 addition & 1 deletion .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
os: >-
['ubuntu-latest']
php: >-
['7.4', '8.0', '8.1']
['8.0', '8.1']
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

## 1.0.2 under development

- no changes in this release.
- Enh #162: Raise minimum PHP version to 8.0 and refactor code (@xepozz, @vjik)

## 1.0.1 June 17, 2022

- Enh #159: Add support for `yiisoft/definitions` version `^2.0` (vjik)
- Enh #159: Add support for `yiisoft/definitions` version `^2.0` (@vjik)

## 1.0.0 December 11, 2021

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ with dependencies resolved by a [PSR-11](https://www.php-fig.org/psr/psr-11/) co

## Requirements

- PHP 7.4 or higher.
- PHP 8.0 or higher.

## Installation

The package could be installed with [composer](http://getcomposer.org/download/):

```shell
composer require yiisoft/definitions --prefer-dist
composer require yiisoft/definitions
```

## General usage
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
"source": "https://github.com/yiisoft/factory"
},
"require": {
"php": "^7.4|^8.0",
"php": "^8.0",
"psr/container": "^1.0|^2.0",
"yiisoft/definitions": "^1.0|^2.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"rector/rector": "^0.14.3",
"roave/infection-static-analysis-plugin": "^1.16",
"spatie/phpunit-watcher": "^1.23",
"vimeo/psalm": "^4.18",
Expand Down
22 changes: 22 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
]);

// register a single rule
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);

// define sets of rules
$rectorConfig->sets([
LevelSetList::UP_TO_PHP_80,
]);
};
37 changes: 11 additions & 26 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,33 @@

/**
* Factory allows creating objects passing arguments runtime.
* A factory will try to use a PSR-11 compliant container to get dependencies,
* but will fall back to manual instantiation
* if the container cannot provide a required dependency.
* A factory will try to use a PSR-11 compliant container to get dependencies, but will fall back to manual
* instantiation if the container cannot provide a required dependency.
*/
final class Factory
{
private FactoryInternalContainer $internalContainer;

/**
* @var bool $validate If definitions should be validated when set.
*/
private bool $validate;

/**
* Factory constructor.
*
* @param ContainerInterface $container Container to use for resolving dependencies.
* @param array $definitions Definitions to create objects with.
* @psalm-param array<string, mixed> $definitions
*
* @param array<string, mixed> $definitions Definitions to create objects with.
* @param bool $validate If definitions should be validated when set.
*
* @throws InvalidConfigException
*/
public function __construct(
ContainerInterface $container,
array $definitions = [],
bool $validate = true
private bool $validate = true
) {
$this->validate = $validate;
$this->validateDefinitions($definitions);
$this->internalContainer = new FactoryInternalContainer($container, $definitions);
}

/**
* @param array $definitions Definitions to create objects with.
* @psalm-param array<string, mixed> $definitions
* @param array<string, mixed> $definitions Definitions to create objects with.
*
* @throws InvalidConfigException
*
* @return self
*/
public function withDefinitions(array $definitions): self
{
Expand Down Expand Up @@ -134,7 +120,7 @@ private function validateDefinitions(array $definitions): void
* @psalm-return ($config is class-string ? T : mixed)
* @psalm-suppress MixedReturnStatement
*/
public function create($config)
public function create(mixed $config): mixed
{
if ($this->validate) {
DefinitionValidator::validate($config);
Expand All @@ -156,18 +142,17 @@ public function create($config)
}

/**
* @param mixed $config
*
* @throws InvalidConfigException
*/
private function createDefinition($config): DefinitionInterface
private function createDefinition(mixed $config): DefinitionInterface
{
$definition = Normalizer::normalize($config);

if (
($definition instanceof ArrayDefinition) &&
$this->internalContainer->hasDefinition($definition->getClass()) &&
($containerDefinition = $this->internalContainer->getDefinition($definition->getClass())) instanceof ArrayDefinition
($definition instanceof ArrayDefinition)
&& $this->internalContainer->hasDefinition($definition->getClass())
&& ($containerDefinition = $this->internalContainer->getDefinition($definition->getClass()))
instanceof ArrayDefinition
) {
$definition = $this->mergeDefinitions(
$containerDefinition,
Expand Down
62 changes: 18 additions & 44 deletions src/FactoryInternalContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,27 @@
final class FactoryInternalContainer implements ContainerInterface
{
/**
* @var ContainerInterface Container to use for resolving dependencies.
*/
private ContainerInterface $container;

/**
* @var array Definitions to create objects with.
* @psalm-var array<string, mixed>
*/
private array $definitions;

/**
* @var DefinitionInterface[] Object created from definitions indexed by their types.
* @psalm-var array<string, DefinitionInterface>
* @var array<string, DefinitionInterface> Object created from definitions indexed by their types.
*/
private array $definitionInstances = [];

/**
* @var array Used to collect IDs instantiated during build to detect circular references.
*
* @psalm-var array<string,1>
* @var array<string,1> Used to collect IDs instantiated during build to detect circular references.
*/
private array $creatingIds = [];

/**
* @param ContainerInterface $container Container to use for resolving dependencies.
* @param array $definitions Definitions to create objects with.
* @psalm-param array<string, mixed> $definitions
* @param array<string, mixed> $definitions Definitions to create objects with.
*/
public function __construct(ContainerInterface $container, array $definitions = [])
{
$this->container = $container;
$this->definitions = $definitions;
public function __construct(
private ContainerInterface $container,
private array $definitions = []
) {
}

/**
* @param array $definitions Definitions to create objects with.
* @psalm-param array<string, mixed> $definitions
*
* @return self
* @param array<string, mixed> $definitions Definitions to create objects with.
*/
public function withDefinitions(array $definitions): self
{
Expand All @@ -80,11 +62,8 @@ public function withDefinitions(array $definitions): self
* @inheritDoc
*
* @param string $id
*
* @return mixed|object
* @psalm-suppress InvalidThrow
*/
public function get($id)
public function get($id): mixed
{
if ($this->hasDefinition($id)) {
return $this->build($id);
Expand All @@ -102,10 +81,7 @@ public function has($id): bool
return $this->hasDefinition($id) || $this->container->has($id);
}

/**
* @return mixed
*/
public function create(DefinitionInterface $definition)
public function create(DefinitionInterface $definition): mixed
{
if ($definition instanceof ArrayDefinition) {
$this->creatingIds[$definition->getClass()] = 1;
Expand Down Expand Up @@ -170,23 +146,21 @@ public function hasDefinition(string $id): bool
}

/**
* @param string $id
*
* @throws CircularReferenceException
* @throws InvalidConfigException
* @throws NotFoundException
* @throws NotInstantiableException
*
* @return mixed|object
*/
private function build(string $id)
private function build(string $id): mixed
{
if (isset($this->creatingIds[$id])) {
throw new CircularReferenceException(sprintf(
'Circular reference to "%s" detected while creating: %s.',
$id,
implode(', ', array_keys($this->creatingIds))
));
throw new CircularReferenceException(
sprintf(
'Circular reference to "%s" detected while creating: %s.',
$id,
implode(', ', array_keys($this->creatingIds))
)
);
}

$definition = $this->getDefinition($id);
Expand Down
8 changes: 3 additions & 5 deletions src/NotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@
*/
final class NotFoundException extends Exception implements NotFoundExceptionInterface
{
private string $id;

/**
* @param string $id ID of the definition or name of the class that was not found.
*/
public function __construct(string $id)
{
$this->id = $id;
public function __construct(
private string $id
) {
parent::__construct(sprintf('No definition or class found or resolvable for %s.', $id));
}

Expand Down
6 changes: 1 addition & 5 deletions tests/Support/Car.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
final class Car
{
public ?ColorInterface $color = null;
private EngineInterface $engine;
private array $moreEngines;

public function __construct(EngineInterface $engine, array $moreEngines = [])
public function __construct(private EngineInterface $engine, private array $moreEngines = [])
{
$this->engine = $engine;
$this->moreEngines = $moreEngines;
}

public function getEngine(): EngineInterface
Expand Down
5 changes: 1 addition & 4 deletions tests/Support/Circular/CircularA.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@

final class CircularA
{
public ?CircularB $b;

public function __construct(?CircularB $b = null)
public function __construct(public ?CircularB $b = null)
{
$this->b = $b;
}
}
5 changes: 1 addition & 4 deletions tests/Support/Circular/CircularB.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@

final class CircularB
{
public ?CircularA $a;

public function __construct(?CircularA $a = null)
public function __construct(public ?CircularA $a = null)
{
$this->a = $a;
}
}
5 changes: 1 addition & 4 deletions tests/Support/Cube.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@

final class Cube
{
private ColorInterface $color;

public function __construct(ColorInterface $color)
public function __construct(private ColorInterface $color)
{
$this->color = $color;
}

public function getColor(): ColorInterface
Expand Down
5 changes: 1 addition & 4 deletions tests/Support/EngineMarkOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ final class EngineMarkOne implements EngineInterface
{
public const NAME = 'Mark One';

private int $number;

public function __construct(int $number = 0)
public function __construct(private int $number = 0)
{
$this->number = $number;
}

public function getName(): string
Expand Down
5 changes: 1 addition & 4 deletions tests/Support/ExcessiveConstructorParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@

final class ExcessiveConstructorParameters
{
private $parameter;

private array $allParameters;

public function __construct($parameter)
public function __construct(private $parameter)
{
$this->parameter = $parameter;
$this->allParameters = func_get_args();
}

Expand Down
Loading