Passed
Push — master ( cc479d...64f04b )
by Koldo
08:33
created

Builder::assertValidService()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 8
c 1
b 0
f 1
dl 0
loc 15
ccs 9
cts 9
cp 1
rs 10
cc 4
nc 5
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\Container;
6
7
use InvalidArgumentException;
8
use Psr\Container\ContainerInterface;
9
use ReflectionMethod;
10
11
class Builder
12
{
13 10
    public static function build(array $dependencies, bool $autowire = false): ContainerInterface
14
    {
15 10
        $self = new self();
16
17 10
        return new Container(
18 10
            $self->parseConfigFor($dependencies),
19
            $autowire
20
        );
21
    }
22
23 10
    private function parseConfigFor(array $dependencies): ContainerConfig
24
    {
25
        $containerConfig = [
26 10
            'config' => $dependencies,
27
            'parameters' => [],
28 10
            'delegators' => $dependencies['delegators'] ?? [],
29
        ];
30
31 10
        foreach ($dependencies['factories'] ?? [] as $name => $factory) {
32
            $containerConfig[$name] = static function (ContainerInterface $container) use ($factory) {
33 3
                if (is_array($factory)) {
34 1
                    $class = array_shift($factory);
35 1
                    $instance = new $class();
36 1
                    $method = new ReflectionMethod($class, '__invoke');
37 1
                    return $method->invokeArgs($instance, array_merge([$container], $factory));
38
                }
39
40 2
                if (is_callable($factory)) {
41 1
                    return $factory($container);
42
                }
43
44 1
                if (class_exists($factory)) {
45 1
                    return (new $factory())($container);
46
                }
47
48
                throw new InvalidArgumentException('Invalid factory type given.');
49
            };
50
        }
51
52 10
        foreach ($dependencies['services'] ?? [] as $name => $service) {
53 6
            $this->assertValidService($service);
54 3
            if (is_array($service)) {
55 1
                $containerConfig['parameters'][$name] = $service['arguments'] ?? [];
56 1
                $containerConfig[$name] = $service['class'];
57
            }
58
59 3
            if (is_string($service)) {
60 2
                $containerConfig[$name] = $service;
61
            }
62
        }
63
64 7
        return new ContainerConfig($containerConfig);
65
    }
66
67 6
    private function assertValidService($service): void
68
    {
69 6
        if (is_array($service)) {
70 3
            if (false === array_key_exists('class', $service)) {
71 1
                throw new InvalidArgumentException(
72 1
                    'Invalid Container Configuration, "class" parameter is required for configurable dependencies.'
73
                );
74
            }
75
76 2
            $service = $service['class'];
77
        }
78
79 5
        if (false === is_string($service)) {
80 2
            throw new InvalidArgumentException(
81 2
                'Invalid Container Configuration, Service "class", Simple or autowired dependencies must have a string value.'
82
            );
83
        }
84 3
    }
85
}
86