Completed
Pull Request — master (#359)
by Jefersson
06:36
created

generateUnsetClassPrivatePropertiesBlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 16
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 13
nc 1
nop 3
crap 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
declare(strict_types=1);
20
21
namespace ProxyManager\ProxyGenerator\Util;
22
23
/**
24
 * Generates code necessary to unset all the given properties from a particular given instance string name
25
 *
26
 * @author Marco Pivetta <[email protected]>
27
 * @license MIT
28
 */
29
final class UnsetPropertiesGenerator
30
{
31
    private static $closureTemplate = <<<'PHP'
32
\Closure::bind(function (\%s $instance) {
33
    %s
34
}, $%s, %s)->__invoke($%s);
35
PHP;
36
37 4
    public static function generateSnippet(Properties $properties, string $instanceName) : string
38
    {
39 4
        return self::generateUnsetAccessiblePropertiesCode($properties, $instanceName)
40 4
            . self::generateUnsetPrivatePropertiesCode($properties, $instanceName);
41
    }
42
43 4
    private static function generateUnsetAccessiblePropertiesCode(Properties $properties, string $instanceName) : string
44
    {
45 4
        $accessibleProperties = $properties->getAccessibleProperties();
46
47 4
        if (! $accessibleProperties) {
48 2
            return '';
49
        }
50
51 2
        return  self::generateUnsetStatement($accessibleProperties, $instanceName) . "\n\n";
52
    }
53
54 4
    private static function generateUnsetPrivatePropertiesCode(Properties $properties, string $instanceName) : string
55
    {
56 4
        $groups = $properties->getGroupedPrivateProperties();
57
58 4
        if (! $groups) {
59 1
            return '';
60
        }
61
62 3
        $unsetClosureCalls = [];
63
64
        /* @var $privateProperties \ReflectionProperty[] */
65 3
        foreach ($groups as $privateProperties) {
66
            /* @var $firstProperty \ReflectionProperty */
67 3
            $firstProperty  = reset($privateProperties);
68
69 3
            $unsetClosureCalls[] = self::generateUnsetClassPrivatePropertiesBlock(
70 3
                $firstProperty->getDeclaringClass(),
71
                $privateProperties,
72
                $instanceName
73
            );
74
        }
75
76 3
        return implode("\n\n", $unsetClosureCalls) . "\n\n";
77
    }
78
79 3
    private static function generateUnsetClassPrivatePropertiesBlock(
80
        \ReflectionClass $declaringClass,
81
        array $properties,
82
        string $instanceName
83
    ) : string {
84 3
        $declaringClassName = $declaringClass->getName();
85
86 3
        return sprintf(
87 3
            self::$closureTemplate,
88
            $declaringClassName,
89 3
            self::generateUnsetStatement($properties, 'instance'),
90
            $instanceName,
91 3
            var_export($declaringClassName, true),
92
            $instanceName
93
        );
94
    }
95
96 3
    private static function generateUnsetStatement(array $properties, string $instanceName) : string
97
    {
98
        return 'unset('
99 3
            . implode(
100 3
                ', ',
101
                array_map(
102 3
                    function (\ReflectionProperty $property) use ($instanceName) : string {
103 3
                        return '$' . $instanceName . '->' . $property->getName();
104 3
                    },
105
                    $properties
106
                )
107
            )
108 3
            . ');';
109
    }
110
}
111