9use InvalidArgumentException;
11use RecursiveDirectoryIterator;
12use RecursiveIteratorIterator;
34 private const FILETYPE_JSON =
'json';
35 private const FILETYPE_PHP =
'php';
77 if ( !is_array( $flags ) ) {
82 if ( in_array(
'local', $flags ) ) {
83 $this->variableName =
'wgAutoloadLocalClasses';
94 foreach ( $paths as
$path ) {
105 private function shouldExclude(
$path ) {
106 foreach ( $this->excludePaths as $dir ) {
107 if ( str_starts_with(
$path, $dir ) ) {
126 throw new InvalidArgumentException(
"Invalid path: $inputPath" );
128 if ( !str_starts_with(
$path, $this->basepath ) ) {
129 throw new InvalidArgumentException(
"Path is not within basepath: $inputPath" );
131 $shortpath = substr(
$path, strlen( $this->basepath ) );
132 $this->overrides[$fqcn] = $shortpath;
144 $len = strlen( $this->basepath );
145 if ( !str_starts_with( $inputPath, $this->basepath ) ) {
146 throw new InvalidArgumentException(
"Path is not within basepath: $inputPath" );
148 if ( $this->shouldExclude( $inputPath ) ) {
151 $fileContents = file_get_contents( $inputPath );
154 if ( preg_match(
'!^// *NO_AUTOLOAD!m', $fileContents ) ) {
160 '/(require|require_once)[ (].*(CommandLineInc.php|commandLine.inc)/',
166 $result = $this->collector->getClasses( $fileContents );
169 $shortpath = substr( $inputPath, $len );
170 $this->classes[$shortpath] = $result;
178 $it =
new RecursiveDirectoryIterator(
179 self::normalizePathSeparator( realpath( $dir ) ) );
180 $it =
new RecursiveIteratorIterator( $it );
182 foreach ( $it as
$path => $file ) {
183 if ( pathinfo(
$path, PATHINFO_EXTENSION ) ===
'php' ) {
198 $key =
'AutoloadClasses';
199 $json = FormatJson::decode( file_get_contents( $filename ),
true );
200 unset( $json[$key] );
203 foreach ( $this->classes as
$path => $contained ) {
204 foreach ( $contained as $fqcn ) {
206 $json[$key][$fqcn] = substr(
$path, 1 );
209 foreach ( $this->overrides as
$path => $fqcn ) {
211 $json[$key][$fqcn] = substr(
$path, 1 );
215 ksort( $json[$key] );
218 return FormatJson::encode( $json,
"\t", FormatJson::ALL_OK ) .
"\n";
234 $format =
"%s => __DIR__ . %s,";
235 foreach ( $this->classes as
$path => $contained ) {
236 $exportedPath = var_export(
$path,
true );
237 foreach ( $contained as $fqcn ) {
238 $content[$fqcn] = sprintf(
240 var_export( $fqcn,
true ),
246 foreach ( $this->overrides as $fqcn =>
$path ) {
247 $content[$fqcn] = sprintf(
249 var_export( $fqcn,
true ),
250 var_export(
$path,
true )
259 if ( $this->variableName ===
'wgAutoloadClasses' ) {
265 $output = implode(
"\n\t", $content );
270global \${$this->variableName};
272\${$this->variableName} {$op} [
287 public function getAutoload( $commandName =
'AutoloadGenerator' ) {
293 if ( $fileinfo[
'type'] === self::FILETYPE_JSON ) {
309 if ( file_exists( $this->basepath .
'/extension.json' ) ) {
311 'filename' => $this->basepath .
'/extension.json',
312 'type' => self::FILETYPE_JSON
315 if ( file_exists( $this->basepath .
'/skin.json' ) ) {
317 'filename' => $this->basepath .
'/skin.json',
318 'type' => self::FILETYPE_JSON
323 'filename' => $this->basepath .
'/autoload.php',
324 'type' => self::FILETYPE_PHP
335 return str_replace(
'\\',
'/',
$path );
348 foreach ( [
'includes',
'languages',
'maintenance',
'mw-config' ] as $dir ) {
349 $this->
readDir( $this->basepath .
'/' . $dir );
351 foreach ( glob( $this->basepath .
'/*.php' ) as $file ) {
358class_alias( AutoloadGenerator::class,
'AutoloadGenerator' );