1: <?php
2: /**
3: * PHP version 5
4: * @package generalDriver
5: * @author Christian Schiffler <c.schiffler@cyberspectrum.de>
6: * @author Stefan Heimes <stefan_heimes@hotmail.com>
7: * @author Tristan Lins <tristan.lins@bit3.de>
8: * @copyright The MetaModels team.
9: * @license LGPL.
10: * @filesource
11: */
12:
13: namespace DcGeneral\Contao\Compatibility;
14:
15: /**
16: * Class ClassLoader
17: *
18: * This class simply exists to provide the Contao 3 namespace based auto loading in Contao 2.11.
19: * It is heavily based upon code by Leo Feyer and only temporary.
20: *
21: * @package DcGeneral\Contao\Compatibility
22: */
23: class ClassLoader
24: {
25: /**
26: * Known namespaces.
27: *
28: * @var array
29: */
30: protected static $namespaces = array
31: (
32: 'Contao'
33: );
34:
35: /**
36: * Known classes.
37: *
38: * @var array
39: */
40: protected static $classes = array();
41:
42: /**
43: * Add a new namespace.
44: *
45: * @param string $name The namespace name.
46: *
47: * @return void
48: */
49: public static function addNamespace($name)
50: {
51: if (in_array($name, self::$namespaces))
52: {
53: return;
54: }
55:
56: array_unshift(self::$namespaces, $name);
57: }
58:
59:
60: /**
61: * Add multiple new namespaces.
62: *
63: * @param array $names An array of namespace names.
64: *
65: * @return void
66: */
67: public static function addNamespaces($names)
68: {
69: foreach ($names as $name)
70: {
71: self::addNamespace($name);
72: }
73: }
74:
75:
76: /**
77: * Return the namespaces as array.
78: *
79: * @return array An array of all namespaces.
80: */
81: public static function getNamespaces()
82: {
83: return self::$namespaces;
84: }
85:
86:
87: /**
88: * Add a new class with its file path.
89: *
90: * @param string $class The class name.
91: *
92: * @param string $file The path to the class file.
93: *
94: * @return void
95: */
96: public static function addClass($class, $file)
97: {
98: self::$classes[$class] = $file;
99:
100: // Tell the Contao 2.X auto loader cache that the class is available.
101: if (class_exists('Cache'))
102: {
103: \Cache::getInstance()->{'classFileExists-' . $class} = true;
104: }
105: \FileCache::getInstance('classes')->$class = true;
106: \FileCache::getInstance('autoload')->$class = $file;
107: }
108:
109:
110: /**
111: * Add multiple new classes with their file paths.
112: *
113: * @param array $classes An array of classes.
114: *
115: * @return void
116: */
117: public static function addClasses($classes)
118: {
119: foreach ($classes as $class => $file)
120: {
121: self::addClass($class, $file);
122: }
123: }
124:
125:
126: /**
127: * Return the classes as array.
128: *
129: * @return array An array of all classes.
130: */
131: public static function getClasses()
132: {
133: return self::$classes;
134: }
135:
136:
137: /**
138: * Autoload a class and create an alias in the global namespace.
139: *
140: * To preserve backwards compatibility with Contao 2 extensions, all core
141: * classes will be aliased into the global namespace.
142: *
143: * @param string $class The class name.
144: *
145: * @return void
146: */
147: public static function load($class)
148: {
149: if (class_exists($class, false) || interface_exists($class, false))
150: {
151: return;
152: }
153:
154: // The class file is set in the mapper.
155: if (isset(self::$classes[$class]))
156: {
157: if ($GLOBALS['TL_CONFIG']['debugMode'])
158: {
159: $GLOBALS['TL_DEBUG']['classes_set'][] = $class;
160: }
161:
162: require_once TL_ROOT . DIRECTORY_SEPARATOR . self::$classes[$class];
163: }
164:
165: // Find the class in the registered namespaces.
166: elseif (($namespaced = self::findClass($class)) != false)
167: {
168: if ($GLOBALS['TL_CONFIG']['debugMode'])
169: {
170: $GLOBALS['TL_DEBUG']['classes_aliased'][] = $class . ' <span style="color:#999">(' . $namespaced . ')</span>';
171: }
172:
173: require_once TL_ROOT . DIRECTORY_SEPARATOR . self::$classes[$namespaced];
174: class_alias($namespaced, $class);
175: }
176:
177: // Pass the request to other auto loaders (e.g. Swift).
178: }
179:
180:
181: /**
182: * Search the namespaces for a matching entry.
183: *
184: * @param string $class The class name.
185: *
186: * @return string The full path including the namespace.
187: */
188: protected static function findClass($class)
189: {
190: foreach (self::$namespaces as $namespace)
191: {
192: if (isset(self::$classes[$namespace . '\\' . $class]))
193: {
194: return $namespace . '\\' . $class;
195: }
196: }
197:
198: return '';
199: }
200:
201:
202: /**
203: * Register the auto loader.
204: *
205: * @return void
206: */
207: public static function register()
208: {
209: spl_autoload_unregister('__autoload');
210: spl_autoload_register('ClassLoader::load', true, false);
211: spl_autoload_register('__autoload');
212: }
213:
214:
215: /**
216: * Dummy method.
217: *
218: * @return void
219: */
220: public static function scanAndRegister()
221: {
222: $modules = TL_ROOT . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'modules';
223:
224: foreach (scan($modules) as $module)
225: {
226: $file =
227: $modules . DIRECTORY_SEPARATOR .
228: $module . DIRECTORY_SEPARATOR .
229: 'config' . DIRECTORY_SEPARATOR .
230: 'autoload.php';
231: if (file_exists($file))
232: {
233: require_once $file;
234: }
235: }
236:
237: self::register();
238: }
239: }
240: