Completed
Pull Request — master (#423)
by Marco
24:53
created

BindProxyProperties   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 5
lcom 0
cbo 4
dl 0
loc 63
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 56 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizer\MethodGenerator;
6
7
use ProxyManager\Exception\UnsupportedProxiedClassException;
8
use ProxyManager\Generator\MethodGenerator;
9
use ProxyManager\ProxyGenerator\Util\Properties;
10
use ReflectionClass;
11
use Zend\Code\Generator\ParameterGenerator;
12
use Zend\Code\Generator\PropertyGenerator;
13
use function implode;
14
use function var_export;
15
16
/**
17
 * The `bindProxyProperties` method implementation for access interceptor scope localizers
18
 *
19
 */
20
class BindProxyProperties extends MethodGenerator
21
{
22
    /**
23
     * Constructor
24
     *
25 4
     */
26
    public function __construct(
27
        ReflectionClass $originalClass,
28
        PropertyGenerator $prefixInterceptors,
29
        PropertyGenerator $suffixInterceptors
30 4
    ) {
31 4
        parent::__construct(
32
            'bindProxyProperties',
33 4
            [
34 4
                new ParameterGenerator('localizedObject', $originalClass->getName()),
35 4
                new ParameterGenerator('prefixInterceptors', 'array', []),
36
                new ParameterGenerator('suffixInterceptors', 'array', []),
37 4
            ],
38 4
            static::FLAG_PRIVATE,
39
            null,
40 4
            "@override constructor to setup interceptors\n\n"
41 4
            . '@param \\' . $originalClass->getName() . " \$localizedObject\n"
42 4
            . "@param \\Closure[] \$prefixInterceptors method interceptors to be used before method logic\n"
43
            . '@param \\Closure[] $suffixInterceptors method interceptors to be used before method logic'
44
        );
45 4
46
        $localizedProperties        = [];
47 4
        $properties                 = Properties::fromReflectionClass($originalClass);
48
        $nonReferenceableProperties = $properties
49 4
            ->onlyNonReferenceableProperties()
50 3
            ->onlyInstanceProperties();
51
52 3
        if (! $nonReferenceableProperties->empty()) {
53
            throw UnsupportedProxiedClassException::nonReferenceableLocalizedReflectionProperties(
54
                $originalClass,
55 4
                $nonReferenceableProperties
56 2
            );
57
        }
58 2
59 2
        $propertiesThatCanBeReferenced = $properties->onlyPropertiesThatCanBeUnset();
60 2
61 2
        foreach ($propertiesThatCanBeReferenced->getAccessibleProperties() as $property) {
62
            $propertyName = $property->getName();
63
64 4
            $localizedProperties[] = '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ';';
65 4
        }
66 4
67 4
        foreach ($propertiesThatCanBeReferenced->getPrivateProperties() as $property) {
68
            $propertyName = $property->getName();
69 4
70
            $localizedProperties[] = "\\Closure::bind(function () use (\$localizedObject) {\n    "
71
                . '$this->' . $propertyName . ' = & $localizedObject->' . $propertyName . ";\n"
72
                . '}, $this, ' . var_export($property->getDeclaringClass()->getName(), true)
73
                . ')->__invoke();';
74
        }
75
76
        $this->setBody(
77
            ($localizedProperties ? implode("\n\n", $localizedProperties) . "\n\n" : '')
78
            . '$this->' . $prefixInterceptors->getName() . " = \$prefixInterceptors;\n"
79
            . '$this->' . $suffixInterceptors->getName() . ' = $suffixInterceptors;'
80
        );
81
    }
82
}
83