Completed
Pull Request — master (#277)
by Marco
04:04 queued 17s
created

generateUnsetPrivatePropertiesCode()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3
Metric Value
dl 0
loc 24
ccs 10
cts 10
cp 1
rs 8.9713
cc 3
eloc 12
nc 3
nop 2
crap 3
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
namespace ProxyManager\ProxyGenerator\Util;
20
21
/**
22
 * Generates code necessary to unset all the given properties from a particular given instance string name
23
 *
24
 * @author Marco Pivetta <[email protected]>
25
 * @license MIT
26
 */
27
final class UnsetPropertiesGenerator
28
{
29
    private static $closureTemplate = <<<'PHP'
30
\Closure::bind(function (\%s $%s) {
31
    %s
32
}, $%s, %s)->__invoke($%s);
33
PHP;
34
35 4
    public static function generateSnippet(Properties $properties, string $instanceName) : string
36
    {
37 4
        return self::generateUnsetAccessiblePropertiesCode($properties, $instanceName)
38 4
            . self::generateUnsetPrivatePropertiesCode($properties, $instanceName);
39
    }
40
41 4
    private static function generateUnsetAccessiblePropertiesCode(Properties $properties, string $instanceName) : string
42
    {
43 4
        $accessibleProperties = $properties->getAccessibleProperties();
44
45 4
        if (! $accessibleProperties) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $accessibleProperties of type ReflectionProperty[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
46 2
            return '';
47
        }
48
49 2
        return  self::generateUnsetStatement($accessibleProperties, $instanceName) . "\n\n";
50
    }
51
52 4
    private static function generateUnsetPrivatePropertiesCode(Properties $properties, string $instanceName) : string
53
    {
54 4
        $groups = $properties->getGroupedPrivateProperties();
55
56 4
        if (! $groups) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $groups of type ReflectionProperty[][] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
57 1
            return '';
58
        }
59
60 3
        $unsetClosureCalls = [];
61
62
        /* @var $privateProperties \ReflectionProperty[] */
63 3
        foreach ($groups as $privateProperties) {
64
            /* @var $firstProperty \ReflectionProperty */
65 3
            $firstProperty  = reset($privateProperties);
66
67 3
            $unsetClosureCalls[] = self::generateUnsetClassPrivatePropertiesBlock(
68 3
                $firstProperty->getDeclaringClass(),
69
                $privateProperties,
70
                $instanceName
71
            );
72
        }
73
74 3
        return implode("\n\n", $unsetClosureCalls) . "\n\n";
75
    }
76
77 3
    private static function generateUnsetClassPrivatePropertiesBlock(
78
        \ReflectionClass $declaringClass,
79
        array $properties,
80
        string $instanceName
81
    ) : string {
1 ignored issue
show
Coding Style introduced by
There must be a single space between the closing parenthesis and the opening brace of a multi-line function declaration
Loading history...
82 3
        $declaringClassName = $declaringClass->getName();
83
84 3
        return sprintf(
85 3
            self::$closureTemplate,
86
            $declaringClassName,
87
            $instanceName,
88 3
            self::generateUnsetStatement($properties, $instanceName),
89
            $instanceName,
90 3
            var_export($declaringClassName, true),
91
            $instanceName
92
        );
93
    }
94
95 3
    private static function generateUnsetStatement(array $properties, string $instanceName) : string
96
    {
97
        return 'unset('
98 3
            . implode(
99 3
                ', ',
100
                array_map(
101 3
                    function (\ReflectionProperty $property) use ($instanceName) {
102 3
                        return '$' . $instanceName . '->' . $property->getName();
103 3
                    },
104
                    $properties
105
                )
106
            )
107 3
            . ');';
108
    }
109
}
110