autoloader.php 6.01 KB
Newer Older
Taylor Otwell committed
1
<?php namespace Laravel; defined('DS') or die('No direct script access.');
2 3 4 5

class Autoloader {

	/**
6
	 * The mappings from class names to file paths.
7 8 9
	 *
	 * @var array
	 */
10
	public static $mappings = array();
11 12

	/**
13
	 * The directories that use the PSR-0 naming convention.
Taylor Otwell committed
14 15 16
	 *
	 * @var array
	 */
17
	public static $directories = array();
Taylor Otwell committed
18 19

	/**
20
	 * The mappings for namespaces to directories.
21 22 23
	 *
	 * @var array
	 */
24
	public static $namespaces = array();
25 26

	/**
27 28 29 30 31 32 33
	 * The mappings for underscored libraries to directories.
	 *
	 * @var array
	 */
	public static $underscored = array();

	/**
34
	 * All of the class aliases registered with the auto-loader.
35 36 37
	 *
	 * @var array
	 */
38
	public static $aliases = array();
39 40

	/**
41 42
	 * Load the file corresponding to a given class.
	 *
43
	 * This method is registerd in the bootstrap file as an SPL auto-loader.
Taylor Otwell committed
44
	 *
45 46 47
	 * @param  string  $class
	 * @return void
	 */
48
	public static function load($class)
49
	{
50 51
		// First, we will check to see if the class has been aliased. If it has,
		// we will register the alias, which may cause the auto-loader to be
52
		// called again for the "real" class name to load its file.
53
		if (isset(static::$aliases[$class]))
54
		{
55
			class_alias(static::$aliases[$class], $class);
56 57
		}

58 59 60 61
		// All classes in Laravel are staticly mapped. There is no crazy search
		// routine that digs through directories. It's just a simple array of
		// class to file path maps for ultra-fast file loading.
		elseif (isset(static::$mappings[$class]))
62
		{
63
			require static::$mappings[$class];
64
		}
65

66
		// If the class namespace is mapped to a directory, we will load the
67
		// class using the PSR-0 standards from that directory accounting
68 69 70
		// for the root of the namespace by trimming it off.
		$namespace = root_namespace($class).'\\';

71
		if (isset(static::$namespaces[$namespace]))
72
		{
73
			$directory = static::$namespaces[$namespace];
74

75
			return static::load_namespaced($class, $namespace, $directory);
76 77
		}

Taylor Otwell committed
78 79
		// If the class uses PEAR-ish style underscores for indicating its
		// directory structure we'll load the class using PSR-0 standards
80 81 82 83 84 85 86 87 88 89 90 91 92
		// standards from that directory, trimming the root.
		$namespace = root_namespace($class, '_').'_';

		if (isset(static::$underscored[$namespace]))
		{
			$directory = static::$underscored[$namespace];

			return static::load_namespaced($class, $namespace, $directory);
		}

		// If all else fails we will just iterator through the mapped
		// PSR-0 directories looking for the class. This is the last
		// resort and slowest loading option for the class.
93
		static::load_psr($class);
94
	}
95

96
	/**
97 98 99 100 101 102 103 104 105 106 107 108 109
	 * Load a namespaced class from a given directory.
	 *
	 * @param  string  $class
	 * @param  string  $namespace
	 * @param  string  $directory
	 * @return void
	 */
	protected static function load_namespaced($class, $namespace, $directory)
	{
		return static::load_psr(substr($class, strlen($namespace)), $directory);
	}

	/**
110
	 * Attempt to resolve a class using the PSR-0 standard.
111 112
	 *
	 * @param  string  $class
113
	 * @param  string  $directory
114
	 * @return void
115
	 */
116
	protected static function load_psr($class, $directory = null)
117
	{
118 119
		// The PSR-0 standard indicates that class namespaces and underscores
		// shoould be used to indcate the directory tree in which the class
120
		// resides, so we'll convert them to slashes.
121 122
		$file = str_replace(array('\\', '_'), '/', $class);

123
		$directories = $directory ?: static::$directories;
124

125 126
		$lower = strtolower($file);

127 128 129 130
		// Once we have formatted the class name, we'll simply spin through
		// the registered PSR-0 directories and attempt to locate and load
		// the class file into the script.
		foreach ((array) $directories as $directory)
131
		{
132
			if (file_exists($path = $directory.$lower.EXT))
133 134 135 136 137 138 139
			{
				return require $path;
			}
			elseif (file_exists($path = $directory.$file.EXT))
			{
				return require $path;
			}
140 141 142 143
		}
	}

	/**
144
	 * Register an array of class to path mappings.
145
	 *
146 147
	 * @param  array  $mappings
	 * @return void
148
	 */
149
	public static function map($mappings)
150
	{
151
		static::$mappings = array_merge(static::$mappings, $mappings);
152 153 154
	}

	/**
155
	 * Register a class alias with the auto-loader.
156
	 *
157 158
	 * @param  string  $class
	 * @param  string  $alias
159 160
	 * @return void
	 */
161
	public static function alias($class, $alias)
162
	{
163
		static::$aliases[$alias] = $class;
164 165
	}

166
	/**
167
	 * Register directories to be searched as a PSR-0 library.
168
	 *
169
	 * @param  string|array  $directory
170 171
	 * @return void
	 */
172
	public static function directories($directory)
173
	{
174
		$directories = static::format($directory);
175

176
		static::$directories = array_unique(array_merge(static::$directories, $directories));
177 178
	}

179
	/**
Taylor Otwell committed
180
	 * Register underscored "namespaces" to directory mappings.
181
	 *
Phill Sparks committed
182 183
	 * @param  array  $mappings
	 * @return void
184
	 */
Taylor Otwell committed
185
	public static function underscored($mappings)
186
	{
187 188 189
		$mappings = static::format_mappings($mappings, '_');

		static::$underscored = array_merge($mappings, static::$underscored);
190
	}
191

192
	/**
Taylor Otwell committed
193
	 * Map namespaces to directories.
194
	 *
195 196 197 198 199 200 201 202 203 204 205 206 207
	 * @param  array  $mappings
	 * @return void
	 */
	public static function namespaces($mappings)
	{
		$mappings = static::format_mappings($mappings, '\\');

		static::$namespaces = array_merge($mappings, static::$namespaces);
	}

	/**
	 * Format an array of namespace to directory mappings.
	 *
Taylor Otwell committed
208 209
	 * @param  array   $mappings
	 * @param  string  $append
210
	 * @return array
211
	 */
212
	protected static function format_mappings($mappings, $append)
213 214 215
	{
		foreach ($mappings as $namespace => $directory)
		{
Taylor Otwell committed
216 217 218 219 220 221 222 223
			// When adding new namespaces to the mappings, we will unset the previously
			// mapped value if it existed. This allows previously registered spaces to
			// be mapped to new directories on the fly.
			$namespace = trim($namespace, $append).$append;

			unset(static::$namespaces[$namespace]);

			$namespaces[$namespace] = head(static::format($directory));
224
		}
Taylor Otwell committed
225

226
		return $namespaces;
227 228
	}

229 230 231 232 233 234 235 236 237 238 239
	/**
	 * Format an array of directories with the proper trailing slashes.
	 *
	 * @param  array  $directories
	 * @return array
	 */
	protected static function format($directories)
	{
		return array_map(function($directory)
		{
			return rtrim($directory, DS).DS;
240
		
241 242 243
		}, (array) $directories);
	}

244
}