VisibilityViolator   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 98
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setHiddenProperty() 0 12 2
A callHiddenMethod() 0 9 1
A extractClassNameAndObject() 0 28 4
A getHiddenProperty() 0 13 2
1
<?php
2
namespace JClaveau\VisibilityViolator;
3
4
/**
5
 * This class provides tools to overpass visibility of methods, properties or
6
 * constants.
7
 *
8
 * It is meant to be used during tests.
9
 *
10
 * @todo constants
11
 */
12
class VisibilityViolator
13
{
14
    /**
15
     * @param  string|object $objectOrClassName  The name of the class or the instance
16
     * @return array
17
     */
18 16
    private static function extractClassNameAndObject($objectOrClassName)
19
    {
20 16
        if (is_object($objectOrClassName)) {
21 7
            $object    = $objectOrClassName;
22 7
            $className = get_class($objectOrClassName);
23
        }
24 10
        elseif (is_string($objectOrClassName)) {
0 ignored issues
show
introduced by
The condition is_string($objectOrClassName) is always true.
Loading history...
25 10
            if (!class_exists($objectOrClassName)) {
26 1
                throw new \InvalidArgumentException(
27 1
                    "The provided class name corresponds to no defined class: '$objectOrClassName'"
28
                );
29
            }
30
            else {
31 10
                $className = $objectOrClassName;
32
            }
33
34 10
            $object = null;
35
        }
36
        else {
37 1
            throw new \InvalidArgumentException(
38
                "\$objectOrClassName must be an instance or a class name including its namespace"
39 1
                ." instead of ".var_export($objectOrClassName, true)
40
            );
41
        }
42
43
        return [
44 16
            $className,
45 16
            $object
46
        ];
47
    }
48
49
    /**
50
     * Retruns the value of a private or protected property from a static class
51
     * or an object.
52
     *
53
     * @param  string|object $objectOrClassName  The name of the class or the instance
54
     * @param  string        $name               The name of the property
55
     * @return mixed                             The value of the property
56
     */
57 8
    public static function getHiddenProperty($objectOrClassName, $name)
58
    {
59 8
        list($className, $object) = self::extractClassNameAndObject($objectOrClassName);
60
61 8
        $reflectionClass    = new \ReflectionClass($className);
62 8
        $reflectionProperty = $reflectionClass->getProperty($name);
63 8
        $reflectionProperty->setAccessible(true);
64
65 8
        $value = $object
66 4
               ? $reflectionProperty->getValue($object)
67 8
               : $reflectionProperty->getValue();
68
69 8
        return $value;
70
    }
71
72
    /**
73
     * Sets the value of a private or protected property.
74
     *
75
     * @param string|object $objectOrClassName  The name of the class or the instance
76
     * @param string        $name               The name of the private property
77
     * @param mixed         $value              The new value
78
     */
79 4
    public static function setHiddenProperty($objectOrClassName, $name, $value)
80
    {
81 4
        list($className, $object) = self::extractClassNameAndObject($objectOrClassName);
82
83 4
        $reflectionClass    = new \ReflectionClass($className);
84 4
        $reflectionProperty = $reflectionClass->getProperty($name);
85 4
        $reflectionProperty->setAccessible(true);
86
87 4
        if ($object)
88 2
            $reflectionProperty->setValue($object, $value);
89
        else
90 2
            $reflectionProperty->setValue($value);
91 4
    }
92
93
    /**
94
     * Calls a private method of the owner.
95
     *
96
     * @param  string|object $objectOrClassName The name of the class or the instance
97
     * @param  string        $name              The name of the method
98
     * @param  array         $arguments         An array of arguments for the method call
99
     * @return mixed                            The returned value of the method
100
     */
101 8
    public static function callHiddenMethod($objectOrClassName, $name, array $arguments=[])
102
    {
103 8
        list($className, $object) = self::extractClassNameAndObject($objectOrClassName);
104
105 8
        $reflectionClass  = new \ReflectionClass($className);
106 8
        $reflectionMethod = $reflectionClass->getMethod($name);
107 8
        $reflectionMethod->setAccessible(true);
108
109 8
        return $reflectionMethod->invokeArgs($object, $arguments);
110
    }
111
112
    /**/
113
}
114