Passed
Push — master ( dff13b...dab0e7 )
by Jesse
03:04
created

Instantiator::newInstanceFromDeserialization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 6
nc 1
nop 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 Instantiator extends ReflectionClass implements ProvidesInstances
18
{
19
    /** @throws CannotInstantiateThis */
20
    public function __construct(string $class)
21
    {
22
        try {
23
            parent::__construct($class);
24
        } catch (ReflectionException $exception) {
25
            throw CannotFindTheClass::encountered($exception);
26
        }
27
        if ($this->isAbstract()) {
28
            throw ClassIsAbstract::cannotInstantiate($class);
29
        }
30
        if ($this->isInterface()) {
31
            throw ThatIsAnInterface::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 ProvidesInstances The instantiator for the class.
40
     * @throws CannotInstantiateThis
41
     */
42
    public static function forThe(string $class): ProvidesInstances
43
    {
44
        return new Instantiator($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