Completed
Push — master ( 80bff0...2aa3b5 )
by Damian
08:40
created

ClassLoader::pushManifest()   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 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Manifest;
4
5
use SilverStripe\Core\ClassInfo;
6
use SilverStripe\Dev\Deprecation;
7
8
/**
9
 * A class that handles loading classes and interfaces from a class manifest
10
 * instance.
11
 */
12
class ClassLoader
13
{
14
15
    /**
16
     * @internal
17
     * @var ClassLoader
18
     */
19
    private static $instance;
20
21
    /**
22
     * @var array Map of 'instance' (ClassManifest) and other options.
23
     */
24
    protected $manifests = array();
25
26
    /**
27
     * @return ClassLoader
28
     */
29
    public static function inst()
30
    {
31
        return self::$instance ? self::$instance : self::$instance = new self();
32
    }
33
34
    /**
35
     * Returns the currently active class manifest instance that is used for
36
     * loading classes.
37
     *
38
     * @return ClassManifest
39
     */
40
    public function getManifest()
41
    {
42
        return $this->manifests[count($this->manifests) - 1]['instance'];
43
    }
44
45
    /**
46
     * Returns true if this class loader has a manifest.
47
     */
48
    public function hasManifest()
49
    {
50
        return (bool)$this->manifests;
51
    }
52
53
    /**
54
     * Pushes a class manifest instance onto the top of the stack.
55
     *
56
     * @param ClassManifest $manifest
57
     * @param bool $exclusive Marks the manifest as exclusive. If set to FALSE, will
58
     * look for classes in earlier manifests as well.
59
     */
60
    public function pushManifest(ClassManifest $manifest, $exclusive = true)
61
    {
62
        $this->manifests[] = array('exclusive' => $exclusive, 'instance' => $manifest);
63
    }
64
65
    /**
66
     * @return ClassManifest
67
     */
68
    public function popManifest()
69
    {
70
        $manifest = array_pop($this->manifests);
71
        return $manifest['instance'];
72
    }
73
74
    public function registerAutoloader()
75
    {
76
        spl_autoload_register(array($this, 'loadClass'));
77
    }
78
79
    /**
80
     * Loads a class or interface if it is present in the currently active
81
     * manifest.
82
     *
83
     * @param string $class
84
     * @return String
85
     */
86
    public function loadClass($class)
87
    {
88
        if ($path = $this->getItemPath($class)) {
89
            require_once $path;
90
        }
91
        return $path;
92
    }
93
94
    /**
95
     * Returns the path for a class or interface in the currently active manifest,
96
     * or any previous ones if later manifests aren't set to "exclusive".
97
     *
98
     * @param string $class
99
     * @return string|false
100
     */
101
    public function getItemPath($class)
102
    {
103
        foreach (array_reverse($this->manifests) as $manifest) {
104
            /** @var ClassManifest $manifestInst */
105
            $manifestInst = $manifest['instance'];
106
            if ($path = $manifestInst->getItemPath($class)) {
107
                return $path;
108
            }
109
            if ($manifest['exclusive']) {
110
                break;
111
            }
112
        }
113
        return false;
114
    }
115
116
    /**
117
     * Returns true if a class or interface name exists in the manifest.
118
     *
119
     * @param  string $class
120
     * @return bool
121
     */
122
    public function classExists($class)
123
    {
124
        Deprecation::notice('4.0', 'Use ClassInfo::exists.');
125
        return ClassInfo::exists($class);
126
    }
127
}
128