Passed
Push — master ( 89c1c1...48858c )
by Jesse
07:23
created

ObjectInstantiator::forThe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\Instantiator;
5
6
use ReflectionClass;
7
use ReflectionException;
8
use function sprintf;
9
use function strlen;
10
use Throwable;
11
12
/**
13
 * Simple Instantiator.
14
 *
15
 * @author Stratadox
16
 */
17
final class ObjectInstantiator extends ReflectionClass implements Instantiator
18
{
19
    /** @throws InstantiationFailure */
20
    private function __construct(string $class)
21
    {
22
        try {
23
            parent::__construct($class);
24
        } catch (ReflectionException $exception) {
25
            throw NoSuchClass::encountered($exception);
26
        }
27
        if ($this->isAbstract()) {
28
            throw NoConcreteClass::cannotInstantiate($class);
29
        }
30
        if ($this->isInterface()) {
31
            throw NotAClass::cannotInstantiate($class);
32
        }
33
    }
34
35
    /**
36
     * Produces a new instantiator.
37
     *
38
     * @param string $class      The class to create the instantiator for.
39
     * @return Instantiator The instantiator for the class.
40
     * @throws InstantiationFailure
41
     */
42
    public static function forThe(string $class): Instantiator
43
    {
44
        return new ObjectInstantiator($class);
45
    }
46
47
    /** @inheritdoc */
48
    public function instance(): object
49
    {
50
        try {
51
            return $this->newInstanceWithoutConstructor();
52
        } catch (Throwable $exception) {
53
            return $this->newInstanceFromDeserialization();
54
        }
55
    }
56
57
    /** @inheritdoc */
58
    public function class(): string
59
    {
60
        return $this->getName();
61
    }
62
63
    private function newInstanceFromDeserialization(): object
64
    {
65
        $class = $this->getName();
66
        return unserialize(sprintf(
67
            'O:%d:"%s":0:{}',
68
            strlen($class),
69
            $class
70
        ), ['allowed_classes' => [$class]]);
71
    }
72
}
73