Mark V
1: <?php
2: namespace MOC\V\Core\AutoLoader\Vendor\Multiton;
3:
4: /**
5: * Class NamespaceLoader
6: *
7: * @package MOC\V\Core\AutoLoader\Vendor\Multiton
8: */
9: class NamespaceLoader
10: {
11:
12: /** @var bool|null $Cacheable */
13: private static $Cacheable = null;
14:
15: /** @var null|string $Namespace */
16: private $Namespace = null;
17: /** @var null|string $Path */
18: private $Path = null;
19: /** @var string $Separator */
20: private $Separator = '\\';
21: /** @var string $Extension */
22: private $Extension = '.php';
23: /** @var string $Prefix */
24: private $Prefix = 'MOC\V';
25: /** @var string $Hash */
26: private $Hash = '';
27:
28: /**
29: * @param string $Namespace
30: * @param string $Path
31: * @param string|null $Prefix
32: */
33: public function __construct($Namespace, $Path, $Prefix = null)
34: {
35:
36: $this->Namespace = $Namespace;
37: $this->Path = $Path;
38: if (null !== $Prefix) {
39: $this->Prefix = $Prefix;
40: }
41: $this->Hash = $this->getLoaderHash();
42: if (self::$Cacheable === null) {
43: if (function_exists('apc_fetch')) {
44: self::$Cacheable = true;
45: } else {
46: self::$Cacheable = false;
47: }
48: }
49: }
50:
51: /**
52: * @return string
53: */
54: public function getLoaderHash()
55: {
56:
57: if (empty( $this->Hash )) {
58: return sha1(
59: serialize(
60: get_object_vars($this)
61: )
62: );
63: } else {
64: return $this->Hash;
65: }
66: }
67:
68: /**
69: * @param string $ClassName
70: *
71: * @return bool
72: */
73: public function loadClass($ClassName)
74: {
75:
76: if ($this->checkExists($ClassName)) {
77: return true;
78: }
79:
80: if (self::$Cacheable) {
81: $Hash = md5($this->Namespace.$this->Path.$this->Separator.$this->Extension.$this->Prefix);
82: // @codeCoverageIgnoreStart
83: if (false === ( $Result = apc_fetch($Hash.'#'.$ClassName) )) {
84: $Result = $this->checkCanLoadClass($ClassName);
85: apc_store($Hash.'#'.$ClassName, ( $Result ? 1 : 0 ));
86: }
87: if (!$Result) {
88: return false;
89: }
90: } else {
91: // @codeCoverageIgnoreEnd
92: if (!$this->checkCanLoadClass($ClassName)) {
93: return false;
94: }
95: }
96:
97: /** @noinspection PhpIncludeInspection */
98: require( $this->Path.DIRECTORY_SEPARATOR
99: .trim(str_replace(array($this->Prefix.$this->Separator, $this->Separator),
100: array('', DIRECTORY_SEPARATOR), $ClassName), DIRECTORY_SEPARATOR)
101: .$this->Extension
102: );
103: return $this->checkExists($ClassName);
104: }
105:
106: /**
107: * @param string $Name
108: * @param bool $Load
109: *
110: * @return bool
111: */
112: private function checkExists($Name, $Load = false)
113: {
114:
115: return interface_exists($Name, $Load)
116: || class_exists($Name, $Load)/*|| ( function_exists( 'trait_exists' ) && trait_exists( $Name, $Load ) )*/
117: ;
118: }
119:
120: /**
121: * @param string $ClassName
122: *
123: * @return bool
124: */
125: public function checkCanLoadClass($ClassName)
126: {
127:
128: if ($this->Namespace !== null && strpos($ClassName, $this->Namespace.$this->Separator) !== 0) {
129: return false;
130: }
131: $File = str_replace(
132: array($this->Prefix.$this->Separator, $this->Separator),
133: array('', DIRECTORY_SEPARATOR),
134: $ClassName
135: ).$this->Extension;
136: if ($this->Path !== null) {
137: return is_file($this->Path.DIRECTORY_SEPARATOR.$File);
138: }
139: // @codeCoverageIgnoreStart
140: return false;
141: // @codeCoverageIgnoreEnd
142: }
143: }
144:
145: