Test Failed
Pull Request — master (#37)
by Divine Niiquaye
03:19
created

PhpFileLoader::load()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 37
rs 8.6186
cc 7
nc 12
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of DivineNii opensource projects.
7
 *
8
 * PHP version 7.4 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2021 DivineNii (https://divinenii.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Rade\DI\Loader;
19
20
use Psr\Container\ContainerInterface;
21
use Rade\DI\{AbstractContainer, ContainerBuilder, DefinitionBuilder};
22
use Symfony\Component\Config\Resource\{FileExistenceResource, FileResource};
23
24
/**
25
 * PhpFileLoader loads service definitions from a PHP file.
26
 *
27
 * @experimental in 1.0
28
 *
29
 * @author Divine Niiquaye Ibok <[email protected]>
30
 */
31
class PhpFileLoader extends FileLoader
32
{
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function load($resource, string $type = null): void
37
    {
38
        $container = $this->builder->getContainer();
39
40
        $path = $this->locator->locate($resource);
41
        $this->setCurrentDir($dir = \dirname($path));
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type array; however, parameter $path of dirname() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

41
        $this->setCurrentDir($dir = \dirname(/** @scrutinizer ignore-type */ $path));
Loading history...
42
        $this->builder->directory($dir);
43
44
        if ($container instanceof ContainerBuilder) {
45
            $container->addResource(new FileExistenceResource($path));
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type array; however, parameter $resource of Symfony\Component\Config...Resource::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
            $container->addResource(new FileExistenceResource(/** @scrutinizer ignore-type */ $path));
Loading history...
46
            $container->addResource(new FileResource($path));
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type array; however, parameter $resource of Symfony\Component\Config...Resource::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
            $container->addResource(new FileResource(/** @scrutinizer ignore-type */ $path));
Loading history...
47
        }
48
49
        $ref = new \ReflectionFunction(include $path);
50
        $arguments = [];
51
52
        foreach ($ref->getParameters() as $offset => $parameter) {
53
            $reflectionType = $parameter->getType();
54
55
            if (!$reflectionType instanceof \ReflectionNamedType) {
56
                throw new \InvalidArgumentException(\sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s" or "%s").', $parameter->getName(), $path, DefinitionBuilder::class, AbstractContainer::class));
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
                throw new \InvalidArgumentException(\sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s" or "%s").', $parameter->getName(), /** @scrutinizer ignore-type */ $path, DefinitionBuilder::class, AbstractContainer::class));
Loading history...
57
            }
58
59
            $type = $reflectionType->getName();
60
61
            if (DefinitionBuilder::class === $type) {
62
                $arguments[$offset] = $this->builder;
63
            } elseif (\is_subclass_of($type, ContainerInterface::class)) {
64
                $arguments[$offset] = $container;
65
            } elseif (\is_subclass_of($type, FileLoader::class)) {
66
                $arguments[$offset] = $this;
67
            } else {
68
                throw new \InvalidArgumentException(\sprintf('Could not resolve argument "%s" for "%s".', $type . ' $' . $parameter->getName(), $path));
69
            }
70
        }
71
72
        $ref->invokeArgs($arguments);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function supports($resource, string $type = null): bool
79
    {
80
        if (!\is_string($resource)) {
81
            return false;
82
        }
83
84
        if (null === $type && 'php' === \pathinfo($resource, \PATHINFO_EXTENSION)) {
85
            return true;
86
        }
87
88
        return 'php' === $type;
89
    }
90
}
91