class AutoLoader {
static protected $autoloadLocalClassesLower = null;
+ /**
+ * @private Only public for ExtensionRegistry
+ * @var string[] Namespace (ends with \) => Path (ends with /)
+ */
+ static public $psr4Namespaces = [];
+
/**
* autoload - take a class name and attempt to load it
*
global $wgAutoloadClasses, $wgAutoloadLocalClasses,
$wgAutoloadAttemptLowercase;
- // Workaround for PHP bug <https://bugs.php.net/bug.php?id=49143> (5.3.2. is broken, it's
- // fixed in 5.3.6). Strip leading backslashes from class names. When namespaces are used,
- // leading backslashes are used to indicate the top-level namespace, e.g. \foo\Bar. When
- // used like this in the code, the leading backslash isn't passed to the auto-loader
- // ($className would be 'foo\Bar'). However, if a class is accessed using a string instead
- // of a class literal (e.g. $class = '\foo\Bar'; new $class()), then some versions of PHP
- // do not strip the leading backlash in this case, causing autoloading to fail.
- $className = ltrim( $className, '\\' );
-
$filename = false;
if ( isset( $wgAutoloadLocalClasses[$className] ) ) {
}
}
+ if ( !$filename && strpos( $className, '\\' ) !== false ) {
+ // This class is namespaced, so try looking at the namespace map
+ $prefix = $className;
+ while ( false !== $pos = strrpos( $prefix, '\\' ) ) {
+ // Check to see if this namespace prefix is in the map
+ $prefix = substr( $className, 0, $pos + 1 );
+ if ( isset( self::$psr4Namespaces[$prefix] ) ) {
+ $relativeClass = substr( $className, $pos + 1 );
+ // Build the expected filename, and see if it exists
+ $file = self::$psr4Namespaces[$prefix] . '/' .
+ str_replace( '\\', '/', $relativeClass ) . '.php';
+ if ( file_exists( $file ) ) {
+ $filename = $file;
+ break;
+ }
+ }
+
+ // Remove trailing separator for next iteration
+ $prefix = rtrim( $prefix, '\\' );
+ }
+ }
+
if ( !$filename ) {
// Class not found; let the next autoloader try to find it
return;
require $filename;
}
- /**
- * Force a class to be run through the autoloader, helpful for things like
- * Sanitizer that have define()s outside of their class definition. Of course
- * this wouldn't be necessary if everything in MediaWiki was class-based. Sigh.
- *
- * @param string $class
- * @return bool Return the results of class_exists() so we know if we were successful
- */
- static function loadClass( $class ) {
- return class_exists( $class );
- }
-
/**
* Method to clear the protected class property $autoloadLocalClassesLower.
* Used in tests.
static function resetAutoloadLocalClassesLower() {
self::$autoloadLocalClassesLower = null;
}
+
+ /**
+ * Get a mapping of namespace => file path
+ * The namespaces should follow the PSR-4 standard for autoloading
+ *
+ * @see <http://www.php-fig.org/psr/psr-4/>
+ * @private Only public for usage in AutoloadGenerator
+ * @since 1.31
+ * @return string[]
+ */
+ public static function getAutoloadNamespaces() {
+ return [
+ 'MediaWiki\\Linker\\' => __DIR__ .'/linker/'
+ ];
+ }
}
+AutoLoader::$psr4Namespaces = AutoLoader::getAutoloadNamespaces();
spl_autoload_register( [ 'AutoLoader', 'autoload' ] );