Passed
Pull Request — master (#102)
by Dmitriy
03:02
created

RepositoryContainer::makeRepositoryFactories()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 1
b 0
f 0
nc 9
nop 0
dl 0
loc 15
ccs 0
cts 11
cp 0
crap 30
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Factory;
6
7
use Closure;
8
use Cycle\ORM\ORMInterface;
9
use Cycle\ORM\RepositoryInterface;
10
use Cycle\ORM\SchemaInterface;
11
use Psr\Container\ContainerInterface;
12
use Yiisoft\Di\Container;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Di\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Yiisoft\Di\CompositeContainer;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Di\CompositeContainer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Yiisoft\Di\Contracts\ServiceProviderInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Di\Contracts\ServiceProviderInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
16
use Yiisoft\Factory\Exception\NotFoundException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Factory\Exception\NotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use function is_string;
18
19
final class RepositoryContainer implements ContainerInterface
20
{
21
    private ContainerInterface $rootContainer;
22
    private ORMInterface $orm;
23
    private array $roles = [];
24
    private array $instances;
25
    private bool $build = false;
26
27
    public function __construct(ContainerInterface $rootContainer)
28
    {
29
        $this->rootContainer = $rootContainer;
30
    }
31
32
33
    public function get($id)
34
    {
35
        if (isset($this->instances[$id])) {
36
            return $this->instances[$id];
37
        }
38
39
        if ($this->has($id)) {
40
            return $this->instances[$id] = $this->makeRepository($this->roles[$id]);
41
        }
42
43
        throw new NotFoundException("Repository $id doesn't exist.");
44
    }
45
46
    public function has($id): bool
47
    {
48
        if (!is_subclass_of($id, RepositoryInterface::class)) {
49
            return false;
50
        }
51
52
        if (!$this->build) {
53
            $this->makeRepositoryList();
54
            $this->build = true;
55
        }
56
57
        return isset($this->roles[$id]);
58
    }
59
60
    private function makeRepositoryList(): void
61
    {
62
        /** @var ORMInterface */
63
        $this->orm = $this->rootContainer->get(ORMInterface::class);
0 ignored issues
show
Bug introduced by
Accessing orm on the interface Cycle\ORM\ORMInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
64
        $schema = $this->orm->getSchema();
65
        $roles = [];
66
        foreach ($schema->getRoles() as $role) {
67
            $repository = $schema->define($role, SchemaInterface::REPOSITORY);
68
            if (is_string($repository)) {
69
                $roles[$repository][] = $role;
70
            }
71
        }
72
        foreach ($roles as $repo => $role) {
73
            if (count($role) === 1) {
74
                $this->roles[$repo] = current($role);
75
            }
76
        }
77
    }
78
79
    /**
80
     * @psalm-pure
81
     * @param ORMInterface $orm
82
     * @param string $role
83
     * @return Closure
84
     */
85
    private function makeRepository(string $role): RepositoryInterface
86
    {
87
        return $this->orm->getRepository($role);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->orm->getRepository($role) returns the type Cycle\ORM\RepositoryInterface which is incompatible with the documented return type Closure.
Loading history...
88
    }
89
}
90