FactoryRenderer   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 59
rs 10
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A renderMethods() 0 11 1
A __invoke() 0 24 2
1
<?php
2
3
/*
4
 * This file is part of the olvlvl/symfony-dependency-injection-proxy package.
5
 *
6
 * (c) Olivier Laviale <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace olvlvl\SymfonyDependencyInjectionProxy;
13
14
use ReflectionClass;
15
use ReflectionException;
16
use ReflectionMethod;
17
18
use function array_map;
19
use function implode;
20
21
use const PHP_VERSION_ID;
22
23
class FactoryRenderer
24
{
25
    /**
26
     * @var MethodRenderer
27
     */
28
    private $methodRenderer;
29
30
    public function __construct(MethodRenderer $methodRenderer)
31
    {
32
        $this->methodRenderer = $methodRenderer;
33
    }
34
35
    /**
36
     * @phpstan-param class-string $interface
37
     *
38
     * @throws ReflectionException
39
     */
40
    public function __invoke(string $interface, string $factoryCode): string
41
    {
42
        $methods = $this->renderMethods(
43
            (new ReflectionClass($interface))->getMethods(),
44
            PHP_VERSION_ID >= 70400
45
                ? '($this->service ??= ($this->factory)())'
46
                : '($this->service ?: $this->service = ($this->factory)())'
47
        );
48
49
        return <<<PHPTPL
50
            new class(
51
                function () {
52
                    return $factoryCode;
53
                }
54
            ) implements \\$interface
55
            {
56
                private \$factory, \$service;
57
58
                public function __construct(callable \$factory)
59
                {
60
                    \$this->factory = \$factory;
61
                }
62
63
$methods
64
            };
65
PHPTPL;
66
    }
67
68
    /**
69
     * @param ReflectionMethod[] $methods
70
     */
71
    private function renderMethods(array $methods, string $getterCode): string
72
    {
73
        $renderMethod = $this->methodRenderer;
74
75
        return implode(
76
            "\n",
77
            array_map(
78
                function (ReflectionMethod $method) use ($renderMethod, $getterCode) {
79
                    return $renderMethod($method, $getterCode);
80
                },
81
                $methods
82
            )
83
        );
84
    }
85
}
86