Instantiator   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 9
c 4
b 1
f 0
lcom 1
cbo 0
dl 0
loc 71
ccs 23
cts 23
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A newInstance() 0 18 3
A getReflection() 0 18 4
A isCloneable() 0 7 2
1
<?php
2
/**
3
 * Instantiator.php
4
 *
5
 * @date 25.12.2015 13:50:09
6
 */
7
8
namespace Sufir\Hydrator;
9
10
use InvalidArgumentException;
11
use ReflectionClass;
12
13
/**
14
 * InstantiatorInterface
15
 *
16
 * Создание объектов (без использования конструктора).
17
 *
18
 * @author Sklyarov Alexey <[email protected]>
19
 * @package Sufir\Hydrator
20
 */
21
final class Instantiator implements InstantiatorInterface
22
{
23
    /**
24
     * @var ReflectionClass[]
25
     */
26
    private static $reflectionsCache = array();
27
    /**
28
     * @var object[] Объекты, которые могут быть клонированы
29
     */
30
    private static $prototypesCache = array();
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 14
    public function newInstance($className)
36
    {
37 14
        if (isset(self::$prototypesCache[$className])) {
38 6
            return clone self::$prototypesCache[$className];
39
        }
40
41 10
        $reflection = $this->getReflection($className);
42
43 7
        $object = $reflection->newInstanceWithoutConstructor();
44
45 7
        if ($this->isCloneable($reflection)) {
46 5
            self::$prototypesCache[$className] = clone $object;
47 5
        } else {
48 3
            self::$reflectionsCache[$className] = $reflection;
49
        }
50
51 7
        return $object;
52
    }
53
54
    /**
55
     *
56
     * @param string $className
57
     * @return ReflectionClass
58
     * @throws InvalidArgumentException
59
     */
60 10
    private function getReflection($className)
61
    {
62 10
        if (isset(self::$reflectionsCache[$className])) {
63 2
            return self::$reflectionsCache[$className];
64
        }
65
66 9
        if (!class_exists($className)) {
67 2
            throw new InvalidArgumentException("Class «{$className}» not found");
68
        }
69
70 7
        $reflection = new ReflectionClass($className);
71
72 7
        if ($reflection->isAbstract()) {
73 1
            throw new InvalidArgumentException("Cannot instantiate abstract class «{$className}»");
74
        }
75
76 6
        return $reflection;
77
    }
78
79
    /**
80
     *
81
     * @param ReflectionClass $reflection
82
     * @return boolean
83
     */
84 7
    private function isCloneable(ReflectionClass $reflection)
85
    {
86
        return (
87 7
            $reflection->isCloneable()
88 7
            && !$reflection->hasMethod('__clone')
89 7
        );
90
    }
91
}
92