Completed
Push — master ( 4ad6bd...3873e4 )
by Ingo
11:53
created

InjectorLoader::countManifests()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Injector;
4
5
use BadMethodCallException;
6
7
/**
8
 * Registers chained injectors
9
 */
10
class InjectorLoader
11
{
12
    /**
13
     * @internal
14
     * @var self
15
     */
16
    private static $instance;
17
18
    /**
19
     * @var Injector[] map of injector instances
20
     */
21
    protected $manifests = array();
22
23
    /**
24
     * @return self
25
     */
26
    public static function inst()
27
    {
28
        return self::$instance ? self::$instance : self::$instance = new static();
29
    }
30
31
    /**
32
     * Returns the currently active class manifest instance that is used for
33
     * loading classes.
34
     *
35
     * @return Injector
36
     */
37
    public function getManifest()
38
    {
39
        if ($this !== self::$instance) {
40
            throw new BadMethodCallException(
41
                "Non-current injector manifest cannot be accessed. Please call ->activate() first"
42
            );
43
        }
44
        if (empty($this->manifests)) {
45
            throw new BadMethodCallException("No injector manifests available");
46
        }
47
        return $this->manifests[count($this->manifests) - 1];
48
    }
49
50
    /**
51
     * Returns true if this class loader has a manifest.
52
     *
53
     * @return bool
54
     */
55
    public function hasManifest()
56
    {
57
        return (bool)$this->manifests;
58
    }
59
60
    /**
61
     * Pushes a class manifest instance onto the top of the stack.
62
     *
63
     * @param Injector $manifest
64
     */
65
    public function pushManifest(Injector $manifest)
66
    {
67
        $this->manifests[] = $manifest;
68
    }
69
70
    /**
71
     * @return Injector
72
     */
73
    public function popManifest()
74
    {
75
        return array_pop($this->manifests);
76
    }
77
78
    /**
79
     * Check number of manifests
80
     *
81
     * @return int
82
     */
83
    public function countManifests()
84
    {
85
        return count($this->manifests);
86
    }
87
88
    /**
89
     * Nest the config loader
90
     *
91
     * @return static
92
     */
93
    public function nest()
94
    {
95
        // Nest injector (note: Don't call getManifest()->nest() since that self-pushes a new manifest)
96
        $manifest = clone $this->getManifest();
97
98
        // Create new blank loader with new stack (top level nesting)
99
        $newLoader = new static;
100
        $newLoader->pushManifest($manifest);
101
102
        // Activate new loader
103
        $newLoader->activate();
104
        return $newLoader;
105
    }
106
107
    /**
108
     * Mark this instance as the current instance
109
     *
110
     * @return $this
111
     */
112
    public function activate()
113
    {
114
        static::$instance = $this;
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
115
        return $this;
116
    }
117
}
118