Constructor   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 5
dl 0
loc 67
ccs 35
cts 35
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A generateMethod() 0 23 3
A generateOriginalConstructorCall() 0 17 2
A getConstructor() 0 19 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProxyManager\ProxyGenerator\ValueHolder\MethodGenerator;
6
7
use Laminas\Code\Generator\Exception\InvalidArgumentException;
8
use Laminas\Code\Generator\PropertyGenerator;
9
use Laminas\Code\Reflection\MethodReflection;
10
use Laminas\Code\Reflection\ParameterReflection;
11
use ProxyManager\Generator\MethodGenerator;
12
use ProxyManager\ProxyGenerator\Util\Properties;
13
use ProxyManager\ProxyGenerator\Util\UnsetPropertiesGenerator;
14
use ReflectionClass;
15
use ReflectionMethod;
16
use function array_filter;
17
use function array_map;
18
use function implode;
19
use function reset;
20
use function var_export;
21
22
/**
23
 * The `__construct` implementation for lazy loading proxies
24
 */
25
class Constructor extends MethodGenerator
26
{
27
    /**
28
     * @throws InvalidArgumentException
29
     */
30 4
    public static function generateMethod(ReflectionClass $originalClass, PropertyGenerator $valueHolder) : self
31
    {
32 4
        $originalConstructor = self::getConstructor($originalClass);
33
34
        /** @var self $constructor */
35 4
        $constructor = $originalConstructor
36 1
            ? self::fromReflectionWithoutBodyAndDocBlock($originalConstructor)
37 4
            : new self('__construct');
38
39 4
        $constructor->setBody(
40
            'static $reflection;' . "\n\n"
41 4
            . 'if (! $this->' . $valueHolder->getName() . ') {' . "\n"
42 4
            . '    $reflection = $reflection ?: new \ReflectionClass('
43 4
            . var_export($originalClass->getName(), true)
44 4
            . ");\n"
45 4
            . '    $this->' . $valueHolder->getName() . ' = $reflection->newInstanceWithoutConstructor();' . "\n"
46 4
            . UnsetPropertiesGenerator::generateSnippet(Properties::fromReflectionClass($originalClass), 'this')
47 4
            . '}'
48 4
            . ($originalConstructor ? self::generateOriginalConstructorCall($originalConstructor, $valueHolder) : '')
49
        );
50
51 4
        return $constructor;
52
    }
53
54 1
    private static function generateOriginalConstructorCall(
55
        MethodReflection $originalConstructor,
56
        PropertyGenerator $valueHolder
57
    ) : string {
58
        return "\n\n"
59 1
            . '$this->' . $valueHolder->getName() . '->' . $originalConstructor->getName() . '('
60 1
            . implode(
61 1
                ', ',
62 1
                array_map(
63
                    static function (ParameterReflection $parameter) : string {
64 1
                        return ($parameter->isVariadic() ? '...' : '') . '$' . $parameter->getName();
0 ignored issues
show
Bug introduced by
The method isVariadic() does not seem to exist on object<Laminas\Code\Refl...on\ParameterReflection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
65 1
                    },
66 1
                    $originalConstructor->getParameters()
67
                )
68
            )
69 1
            . ');';
70
    }
71
72 4
    private static function getConstructor(ReflectionClass $class) : ?MethodReflection
73
    {
74 4
        $constructors = array_map(
75
            static function (ReflectionMethod $method) : MethodReflection {
76 1
                return new MethodReflection(
77 1
                    $method->getDeclaringClass()->getName(),
78 1
                    $method->getName()
79
                );
80 4
            },
81 4
            array_filter(
82 4
                $class->getMethods(),
83
                static function (ReflectionMethod $method) : bool {
84 1
                    return $method->isConstructor();
85 4
                }
86
            )
87
        );
88
89 4
        return reset($constructors) ?: null;
90
    }
91
}
92