Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1429563
autoload.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
autoload.php
View Options
<?php
/**
* Autoloads files for PHP_CodeSniffer and tracks what has been loaded.
*
* Due to different namespaces being used for custom coding standards,
* the autoloader keeps track of what class is loaded after a file is included,
* even if the file is ultimately included by another autoloader (such as composer).
*
* This allows PHP_CodeSniffer to request the class name after loading a class
* when it only knows the filename, without having to parse the file to find it.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace
PHP_CodeSniffer
;
use
Composer\Autoload\ClassLoader
;
use
Exception
;
if
(
class_exists
(
'PHP_CodeSniffer
\A
utoload'
,
false
)
===
false
)
{
class
Autoload
{
/**
* The composer autoloader.
*
* @var \Composer\Autoload\ClassLoader
*/
private
static
$composerAutoloader
=
null
;
/**
* A mapping of file names to class names.
*
* @var array<string, string>
*/
private
static
$loadedClasses
=
[];
/**
* A mapping of class names to file names.
*
* @var array<string, string>
*/
private
static
$loadedFiles
=
[];
/**
* A list of additional directories to search during autoloading.
*
* This is typically a list of coding standard directories.
*
* @var string[]
*/
private
static
$searchPaths
=
[];
/**
* Loads a class.
*
* This method only loads classes that exist in the PHP_CodeSniffer namespace.
* All other classes are ignored and loaded by subsequent autoloaders.
*
* @param string $class The name of the class to load.
*
* @return bool
*/
public
static
function
load
(
$class
)
{
// Include the composer autoloader if there is one, but re-register it
// so this autoloader runs before the composer one as we need to include
// all files so we can figure out what the class/interface/trait name is.
if
(
self
::
$composerAutoloader
===
null
)
{
// Make sure we don't try to load any of Composer's classes
// while the autoloader is being setup.
if
(
strpos
(
$class
,
'Composer
\\
'
)
===
0
)
{
return
false
;
}
if
(
strpos
(
__DIR__
,
'phar://'
)
!==
0
&&
@
file_exists
(
__DIR__
.
'/../../autoload.php'
)
===
true
)
{
self
::
$composerAutoloader
=
include
__DIR__
.
'/../../autoload.php'
;
if
(
self
::
$composerAutoloader
instanceof
ClassLoader
)
{
self
::
$composerAutoloader
->
unregister
();
self
::
$composerAutoloader
->
register
();
}
else
{
// Something went wrong, so keep going without the autoloader
// although namespaced sniffs might error.
self
::
$composerAutoloader
=
false
;
}
}
else
{
self
::
$composerAutoloader
=
false
;
}
}
//end if
$ds
=
DIRECTORY_SEPARATOR
;
$path
=
false
;
if
(
substr
(
$class
,
0
,
16
)
===
'PHP_CodeSniffer
\\
'
)
{
if
(
substr
(
$class
,
0
,
22
)
===
'PHP_CodeSniffer
\T
ests
\\
'
)
{
$isInstalled
=
!
is_dir
(
__DIR__
.
$ds
.
'tests'
);
if
(
$isInstalled
===
false
)
{
$path
=
__DIR__
.
$ds
.
'tests'
;
}
else
{
$path
=
'@test_dir@'
.
$ds
.
'PHP_CodeSniffer'
.
$ds
.
'CodeSniffer'
;
}
$path
.=
$ds
.
substr
(
str_replace
(
'
\\
'
,
$ds
,
$class
),
22
).
'.php'
;
}
else
{
$path
=
__DIR__
.
$ds
.
'src'
.
$ds
.
substr
(
str_replace
(
'
\\
'
,
$ds
,
$class
),
16
).
'.php'
;
}
}
// See if the composer autoloader knows where the class is.
if
(
$path
===
false
&&
self
::
$composerAutoloader
!==
false
)
{
$path
=
self
::
$composerAutoloader
->
findFile
(
$class
);
}
// See if the class is inside one of our alternate search paths.
if
(
$path
===
false
)
{
foreach
(
self
::
$searchPaths
as
$searchPath
=>
$nsPrefix
)
{
$className
=
$class
;
if
(
$nsPrefix
!==
''
&&
substr
(
$class
,
0
,
strlen
(
$nsPrefix
))
===
$nsPrefix
)
{
$className
=
substr
(
$class
,
(
strlen
(
$nsPrefix
)
+
1
));
}
$path
=
$searchPath
.
$ds
.
str_replace
(
'
\\
'
,
$ds
,
$className
).
'.php'
;
if
(
is_file
(
$path
)
===
true
)
{
break
;
}
$path
=
false
;
}
}
if
(
$path
!==
false
&&
is_file
(
$path
)
===
true
)
{
self
::
loadFile
(
$path
);
return
true
;
}
return
false
;
}
//end load()
/**
* Includes a file and tracks what class or interface was loaded as a result.
*
* @param string $path The path of the file to load.
*
* @return string The fully qualified name of the class in the loaded file.
*/
public
static
function
loadFile
(
$path
)
{
if
(
strpos
(
__DIR__
,
'phar://'
)
!==
0
)
{
$path
=
realpath
(
$path
);
if
(
$path
===
false
)
{
return
false
;
}
}
if
(
isset
(
self
::
$loadedClasses
[
$path
])
===
true
)
{
return
self
::
$loadedClasses
[
$path
];
}
$classesBeforeLoad
=
[
'classes'
=>
get_declared_classes
(),
'interfaces'
=>
get_declared_interfaces
(),
'traits'
=>
get_declared_traits
(),
];
include
$path
;
$classesAfterLoad
=
[
'classes'
=>
get_declared_classes
(),
'interfaces'
=>
get_declared_interfaces
(),
'traits'
=>
get_declared_traits
(),
];
$className
=
self
::
determineLoadedClass
(
$classesBeforeLoad
,
$classesAfterLoad
);
self
::
$loadedClasses
[
$path
]
=
$className
;
self
::
$loadedFiles
[
$className
]
=
$path
;
return
self
::
$loadedClasses
[
$path
];
}
//end loadFile()
/**
* Determine which class was loaded based on the before and after lists of loaded classes.
*
* @param array $classesBeforeLoad The classes/interfaces/traits before the file was included.
* @param array $classesAfterLoad The classes/interfaces/traits after the file was included.
*
* @return string The fully qualified name of the class in the loaded file.
*/
public
static
function
determineLoadedClass
(
$classesBeforeLoad
,
$classesAfterLoad
)
{
$className
=
null
;
$newClasses
=
array_diff
(
$classesAfterLoad
[
'classes'
],
$classesBeforeLoad
[
'classes'
]);
if
(
PHP_VERSION_ID
<
70400
)
{
$newClasses
=
array_reverse
(
$newClasses
);
}
// Since PHP 7.4 get_declared_classes() does not guarantee any order, making
// it impossible to use order to determine which is the parent and which is the child.
// Let's reduce the list of candidates by removing all the classes known to be "parents".
// That way, at the end, only the "main" class just included will remain.
$newClasses
=
array_reduce
(
$newClasses
,
function
(
$remaining
,
$current
)
{
return
array_diff
(
$remaining
,
class_parents
(
$current
));
},
$newClasses
);
foreach
(
$newClasses
as
$name
)
{
if
(
isset
(
self
::
$loadedFiles
[
$name
])
===
false
)
{
$className
=
$name
;
break
;
}
}
if
(
$className
===
null
)
{
$newClasses
=
array_reverse
(
array_diff
(
$classesAfterLoad
[
'interfaces'
],
$classesBeforeLoad
[
'interfaces'
]));
foreach
(
$newClasses
as
$name
)
{
if
(
isset
(
self
::
$loadedFiles
[
$name
])
===
false
)
{
$className
=
$name
;
break
;
}
}
}
if
(
$className
===
null
)
{
$newClasses
=
array_reverse
(
array_diff
(
$classesAfterLoad
[
'traits'
],
$classesBeforeLoad
[
'traits'
]));
foreach
(
$newClasses
as
$name
)
{
if
(
isset
(
self
::
$loadedFiles
[
$name
])
===
false
)
{
$className
=
$name
;
break
;
}
}
}
return
$className
;
}
//end determineLoadedClass()
/**
* Adds a directory to search during autoloading.
*
* @param string $path The path to the directory to search.
* @param string $nsPrefix The namespace prefix used by files under this path.
*
* @return void
*/
public
static
function
addSearchPath
(
$path
,
$nsPrefix
=
''
)
{
self
::
$searchPaths
[
$path
]
=
rtrim
(
trim
((
string
)
$nsPrefix
),
'
\\
'
);
}
//end addSearchPath()
/**
* Retrieve the namespaces and paths registered by external standards.
*
* @return array
*/
public
static
function
getSearchPaths
()
{
return
self
::
$searchPaths
;
}
//end getSearchPaths()
/**
* Gets the class name for the given file path.
*
* @param string $path The name of the file.
*
* @throws \Exception If the file path has not been loaded.
* @return string
*/
public
static
function
getLoadedClassName
(
$path
)
{
if
(
isset
(
self
::
$loadedClasses
[
$path
])
===
false
)
{
throw
new
Exception
(
"Cannot get class name for $path; file has not been included"
);
}
return
self
::
$loadedClasses
[
$path
];
}
//end getLoadedClassName()
/**
* Gets the file path for the given class name.
*
* @param string $class The name of the class.
*
* @throws \Exception If the class name has not been loaded.
* @return string
*/
public
static
function
getLoadedFileName
(
$class
)
{
if
(
isset
(
self
::
$loadedFiles
[
$class
])
===
false
)
{
throw
new
Exception
(
"Cannot get file name for $class; class has not been included"
);
}
return
self
::
$loadedFiles
[
$class
];
}
//end getLoadedFileName()
/**
* Gets the mapping of file names to class names.
*
* @return array<string, string>
*/
public
static
function
getLoadedClasses
()
{
return
self
::
$loadedClasses
;
}
//end getLoadedClasses()
/**
* Gets the mapping of class names to file names.
*
* @return array<string, string>
*/
public
static
function
getLoadedFiles
()
{
return
self
::
$loadedFiles
;
}
//end getLoadedFiles()
}
//end class
// Register the autoloader before any existing autoloaders to ensure
// it gets a chance to hear about every autoload request, and record
// the file and class name for it.
spl_autoload_register
(
__NAMESPACE__
.
'
\A
utoload::load'
,
true
,
true
);
}
//end if
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 17:46 (8 h, 52 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
6c/c8/44ef003676a3f1136e306060f9ab
Default Alt Text
autoload.php (11 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment