Completed
Push — master ( b3e34b...89b4ff )
by Alec
02:22
created

Picklock::errorMessage()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 1
nop 3
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Helpers\Objects;
4
5
/**
6
 * Class Picklock
7
 *
8
 * @link https://gitlab.com/m0rtis/picklock
9
 * @license Apache License 2.0
10
 * @author Anton Fomichev aka m0rtis - [email protected]
11
 *
12
 * @package AlecRabbit\Helpers\Objects
13
 * @author AlecRabbit
14
 *
15
 * @internal
16
 */
17
final class Picklock
18
{
19
    public const EXCEPTION_TEMPLATE = 'Class [%s] does not have `%s` %s';
20
    public const METHOD = 'method';
21
    public const PROPERTY = 'property';
22
23
    /**
24
     * Calls a private or protected method of an object.
25
     *
26
     * @psalm-suppress InvalidScope
27
     *
28
     * @param object $object
29
     * @param string $methodName
30
     * @param mixed ...$args
31
     *
32
     * @return mixed
33
     */
34 2
    public static function callMethod(object $object, string $methodName, ...$args)
35
    {
36
        $closure =
37
            /**
38
             * @param string $methodName
39
             * @param array $args
40
             * @return mixed
41
             */
42
            function (string $methodName, ...$args) {
43 2
                if (\method_exists($this, $methodName)) {
44 2
                    return $this->$methodName(...$args);
45
                }
46 2
                throw new \RuntimeException(
47 2
                    Picklock::errorMessage($this, $methodName, true)
48
                );
49 2
            };
50
        return
51 2
            $closure->call($object, $methodName, ...$args);
52
    }
53
54
    /**
55
     * Creates an error message.
56
     *
57
     * @param object $object
58
     * @param string $part
59
     * @param bool $forMethod
60
     *
61
     * @return string
62
     */
63 4
    public static function errorMessage(object $object, string $part, bool $forMethod): string
64
    {
65
        return
66 4
            sprintf(
67 4
                static::EXCEPTION_TEMPLATE,
68 4
                \get_class($object),
69 4
                $part,
70 4
                $forMethod ? static::METHOD : static::PROPERTY
71
            );
72
    }
73
74
    /**
75
     * Gets a value of a private or protected property of an object.
76
     *
77
     * @psalm-suppress InvalidScope
78
     *
79
     * @param object $object
80
     * @param string $propertyName
81
     *
82
     * @return mixed
83
     */
84 2
    public static function getValue(object $object, string $propertyName)
85
    {
86
        $closure =
87
            /**
88
             * @return mixed
89
             */
90
            function () use ($propertyName) {
91 2
                if (\property_exists($this, $propertyName)) {
92 2
                    return $this->$propertyName;
93
                }
94 2
                throw new \RuntimeException(
95 2
                    Picklock::errorMessage($this, $propertyName, false)
96
                );
97 2
            };
98
        return
99 2
            $closure->bindTo($object, $object)();
100
    }
101
}
102