Exponential Basic 2.4.0.1 Exponential Basic CMS — PHP Class Reference

ezautoloadgenerator.php
Go to the documentation of this file.
1 <?php
19 class eZAutoloadGenerator
20 {
26 protected $options;
27
33 protected $mask;
34
42 protected $existingAutoloadArrays;
43
49 protected $messages;
50
56 protected $warnings;
57
63 protected $outputCallback;
64
70 protected $output;
71
72
78 protected $modeName = array(
79 self::MODE_KERNEL => "Kernel",
80 self::MODE_EXTENSION => "Extension",
81 self::MODE_TESTS => "Test",
82 self::MODE_SINGLE_EXTENSION =>"Single extension",
83 self::MODE_KERNEL_OVERRIDE => "Kernel overrides",
84 );
85
94 protected $autoloadArrays;
95
99 const MODE_NONE = 0;
100
104 const MODE_KERNEL = 1;
105
109 const MODE_EXTENSION = 2;
110
114 const MODE_TESTS = 4;
115
121 const MODE_SINGLE_EXTENSION = 8;
122
128 const MODE_KERNEL_OVERRIDE = 16;
129
134 const OUTPUT_PROGRESS_PHASE1 = 1;
135
140 const OUTPUT_PROGRESS_PHASE2 = 2;
141
146 const DEFAULT_EXCLUDE_FILE = '.autoloadignore';
147
151 const UNDEFINED_TOKEN = -1;
152
156 function __construct( ezpAutoloadGeneratorOptions $options = null )
157 {
158 if ( $options === null )
159 {
160 $this->options = new ezpAutoloadGeneratorOptions();
161 }
162 else
163 {
164 $this->options = $options;
165 }
166 $this->mask = $this->runMode();
167
168 // Set up arrays for existing autoloads, used to check for class name
169 // collisions.
170 $this->existingAutoloadArrays = array();
171 $this->existingAutoloadArrays[self::MODE_KERNEL] = @include 'var/autoload/ezp_kernel.php';
172 $this->existingAutoloadArrays[self::MODE_EXTENSION] = @include 'var/autoload/ezp_extension.php';
173 $this->existingAutoloadArrays[self::MODE_TESTS] = @include 'var/autoload/ezp_tests.php';
174
175 $this->messages = array();
176 $this->warnings = array();
177 }
178
186 public function buildAutoloadArrays()
187 {
188 $phpFiles = $this->fetchFiles();
189
190 $phpClasses = array();
191 foreach ( $phpFiles as $mode => $fileList )
192 {
193 $phpClasses[$mode] = $this->getClassFileList( $fileList, $mode );
194 }
195
196 $maxClassNameLength = $this->checkMaxClassLength( $phpClasses );
197 $this->autoloadArrays = $this->dumpArray( $phpClasses, $maxClassNameLength );
198
199 if ( $this->options->writeFiles )
200 {
201 $this->writeAutoloadFiles();
202 }
203 }
204
217 protected function writeAutoloadFiles()
218 {
219 $directorySeparators = "/\\";
220
221 foreach( $this->autoloadArrays as $location => $data )
222 {
223 if ( $this->options->outputDir )
224 {
225 $targetBasedir = rtrim( $this->options->outputDir, $directorySeparators );
226 }
227 else
228 {
229 $targetBasedir = $this->targetTable( $location );
230 }
231
232 if( file_exists( $targetBasedir ) && !is_dir( $targetBasedir ) )
233 {
234 throw new Exception( "Specified target: {$targetBasedir} is not a directory." );
235 }
236 else if ( !file_exists( $targetBasedir ) )
237 {
238 if ( defined( 'EZP_INI_FILE_PERMISSION' ) )
239 {
240 mkdir( $targetBasedir, EZP_INI_FILE_PERMISSION, true );
241 }
242 else
243 {
244 mkdir( $targetBasedir, 0777, true );
245 }
246 }
247
248 $filename = $this->nameTable( $location );
249 $filePath = $targetBasedir . DIRECTORY_SEPARATOR . $filename;
250
251 $file = fopen( $filePath, "w+" );
252 if ( $file )
253 {
254 fwrite( $file, $this->dumpArrayStart( $location ) );
255 fwrite( $file, $data );
256 fwrite( $file, $this->dumpArrayEnd() );
257 fclose( $file );
258 if ( defined( 'EZP_INI_FILE_PERMISSION' ) )
259 {
260 chmod( $filePath, EZP_INI_FILE_PERMISSION );
261 }
262 else
263 {
264 chmod( $filePath, 0777 );
265 }
266
267 }
268 else
269 {
270 throw new Exception( __METHOD__ . ": The file {$filePath} is not writable by the system." );
271 }
272 }
273 }
274
284 protected function handleDefaultExcludeFile()
285 {
286 $defaultExcludeFile = $this->options->basePath . DIRECTORY_SEPARATOR . self::DEFAULT_EXCLUDE_FILE;
287 if ( !file_exists( $defaultExcludeFile ) )
288 {
289 return $this->options->excludeDirs;
290 }
291
292 $defaultExcludeArray = explode( "\n", trim( file_get_contents( $defaultExcludeFile ) ) );
293 return array_merge( $defaultExcludeArray, $this->options->excludeDirs );
294 }
295
303 protected function fetchFiles()
304 {
305 $path = $this->options->basePath;
306 $excludeDirs = $this->handleDefaultExcludeFile();
307
308 // make sure ezcBaseFile::findRecursive and the exclusion filters we pass to it
309 // work correctly on systems with another file seperator than the forward slash
310 $sanitisedBasePath = DIRECTORY_SEPARATOR == '/' ? $path : strtr( $path, DIRECTORY_SEPARATOR, '/' );
311 $dirSep = preg_quote( DIRECTORY_SEPARATOR );
312
313 $extraExcludeDirs = array();
314 if ( $excludeDirs !== false and is_array( $excludeDirs ) )
315 {
316 foreach ( $excludeDirs as $dir )
317 {
318 $extraExcludeDirs[] = "@^{$sanitisedBasePath}{$dirSep}{$dir}@";
319 }
320 }
321
322 $retFiles = array();
323
324 $activeModes = $this->checkMode();
325
326 foreach( $activeModes as $modusOperandi )
327 {
328 switch( $modusOperandi )
329 {
330 case self::MODE_KERNEL:
331 $extraExcludeKernelDirs = $extraExcludeDirs;
332 $extraExcludeKernelDirs[] = "@^{$sanitisedBasePath}{$dirSep}extension@";
333 $extraExcludeKernelDirs[] = "@^{$sanitisedBasePath}{$dirSep}tests@";
334 $retFiles[$modusOperandi] = $this->buildFileList( $sanitisedBasePath, $extraExcludeKernelDirs );
335 break;
336
337 case self::MODE_EXTENSION:
338 case self::MODE_KERNEL_OVERRIDE:
339 $extraExcludeExtensionDirs = $extraExcludeDirs;
340 $extraExcludeExtensionDirs[] = "@^{$sanitisedBasePath}{$dirSep}extension{$dirSep}[^{$dirSep}]+{$dirSep}tests@";
341 $retFiles[$modusOperandi] = $this->buildFileList( "$sanitisedBasePath/extension", $extraExcludeExtensionDirs );
342 break;
343
344 case self::MODE_TESTS:
345 $retFiles[$modusOperandi] = $this->buildFileList( "$sanitisedBasePath/tests", $extraExcludeDirs );
346 $extraExcludeExtensionDirs = $extraExcludeDirs;
347 $extraExcludeExtensionDirs[] = "@^{$sanitisedBasePath}{$dirSep}extension{$dirSep}[^{$dirSep}]+{$dirSep}(?!tests)@";
348 $extensionTestFiles = $this->buildFileList("$sanitisedBasePath/extension", $extraExcludeExtensionDirs );
349 $retFiles[$modusOperandi] = array_merge( $retFiles[$modusOperandi], $extensionTestFiles );
350 break;
351
352 case self::MODE_SINGLE_EXTENSION:
353 $retFiles = array( $modusOperandi => $this->buildFileList( "$sanitisedBasePath", $extraExcludeDirs ) );
354 break;
355 }
356 }
357
358 //Make all the paths relative to $path
359 foreach ( $retFiles as &$fileBundle )
360 {
361 foreach ( $fileBundle as $key => &$file )
362 {
363 // ezcBaseFile::calculateRelativePath only works correctly with paths where DIRECTORY_SEPARATOR is used
364 // so we need to correct the results of ezcBaseFile::findRecursive again
365 if ( DIRECTORY_SEPARATOR != '/' )
366 {
367 $file = strtr( $file, '/', DIRECTORY_SEPARATOR );
368 }
369 $fileBundle[$key] = ezcBaseFile::calculateRelativePath( $file, $path );
370 }
371 }
372 unset( $file, $fileBundle );
373 return $retFiles;
374 }
375
383 protected function buildFileList( $path, $extraFilter = null )
384 {
385 $dirSep = preg_quote( DIRECTORY_SEPARATOR );
386 $exclusionFilter = array( "@^{$path}{$dirSep}(var|settings|benchmarks|bin|autoload|port_info|update|templates|tmp|UnitTest|lib{$dirSep}ezc)@" );
387
388 if ( !empty( $extraFilter ) and is_array( $extraFilter ) )
389 {
390 foreach( $extraFilter as $filter )
391 {
392 $exclusionFilter[] = $filter;
393 }
394 }
395
396 if (!empty( $path ) )
397 {
398 return self::findRecursive( $path, array( '@\.php$@' ), $exclusionFilter, $this );
399 }
400 return false;
401 }
402
414 public static function findRecursive( $sourceDir, array $includeFilters, array $excludeFilters, eZAutoloadGenerator $gen )
415 {
416 if ( is_string( $includeFilters ) )
417 $includeFilters = array( $includeFilters );
418 if ( is_string( $excludeFilters ) )
419 $excludeFilters = array( $excludeFilters );
420
421 $gen->log( "Scanning for PHP-files." );
422 $gen->startProgressOutput( self::OUTPUT_PROGRESS_PHASE1 );
423
424 // create the context, and then start walking over the array
425 $context = new ezpAutoloadFileFindContext();
426 $context->generator = $gen;
427
428 self::walkRecursive( $sourceDir, $includeFilters, $excludeFilters,
429 array( 'eZAutoloadGenerator', 'findRecursiveCallback' ), $context );
430
431 // return the found and pattern-matched files
432 sort( $context->elements );
433
434 $gen->stopProgressOutput( self::OUTPUT_PROGRESS_PHASE1 );
435 $gen->log( "Scan complete. Found {$context->count} PHP files." );
436
437 return $context->elements;
438 }
439
460 static protected function walkRecursive( $sourceDir, array $includeFilters, array $excludeFilters, $callback, &$callbackContext )
461 {
462 if ( is_string( $includeFilters ) )
463 $includeFilters = array( $includeFilters );
464 if ( is_string( $excludeFilters ) )
465 $excludeFilters = array( $excludeFilters );
466
467 if ( !is_dir( $sourceDir ) )
468 {
469 throw new ezcBaseFileNotFoundException( $sourceDir, 'directory' );
470 }
471 $elements = array();
472
473 // Iterate over the $excludeFilters and prohibit the directory from
474 // being scanned when atleast one of them matches
475 foreach ( $excludeFilters as $filter )
476 {
477 if ( preg_match( $filter, $sourceDir ) )
478 {
479 return $elements;
480 }
481 }
482
483 $d = @dir( $sourceDir );
484 if ( !$d )
485 {
486 throw new ezcBaseFilePermissionException( $sourceDir, ezcBaseFileException::READ );
487 }
488
489 while ( ( $entry = $d->read() ) !== false )
490 {
491 if ( $entry == '.' || $entry == '..' )
492 {
493 continue;
494 }
495
496 $fileInfo = @stat( $sourceDir . DIRECTORY_SEPARATOR . $entry );
497 if ( !$fileInfo )
498 {
499 $fileInfo = array( 'size' => 0, 'mode' => 0 );
500 }
501
502 if ( $fileInfo['mode'] & 0x4000 )
503 {
504 // We need to ignore the Permission exceptions here as it can
505 // be normal that a directory can not be accessed. We only need
506 // the exception if the top directory could not be read.
507 try
508 {
509 call_user_func_array( $callback, array( $callbackContext, $sourceDir, $entry, $fileInfo ) );
510 $subList = self::walkRecursive( $sourceDir . DIRECTORY_SEPARATOR . $entry, $includeFilters, $excludeFilters, $callback, $callbackContext );
511 $elements = array_merge( $elements, $subList );
512 }
513 catch ( ezcBaseFilePermissionException $e )
514 {
515 }
516 }
517 else
518 {
519 // By default a file is included in the return list
520 $ok = true;
521 // Iterate over the $includeFilters and prohibit the file from
522 // being returned when atleast one of them does not match
523 foreach ( $includeFilters as $filter )
524 {
525 if ( !preg_match( $filter, $sourceDir . DIRECTORY_SEPARATOR . $entry ) )
526 {
527 $ok = false;
528 break;
529 }
530 }
531 // Iterate over the $excludeFilters and prohibit the file from
532 // being returns when atleast one of them matches
533 foreach ( $excludeFilters as $filter )
534 {
535 if ( preg_match( $filter, $sourceDir . DIRECTORY_SEPARATOR . $entry ) )
536 {
537 $ok = false;
538 break;
539 }
540 }
541
542 // If everything's allright, call the callback and add the
543 // entry to the elements array
544 if ( $ok )
545 {
546 call_user_func( $callback, $callbackContext, $sourceDir, $entry, $fileInfo );
547 $elements[] = $sourceDir . DIRECTORY_SEPARATOR . $entry;
548 }
549 }
550 }
551 sort( $elements );
552 return $elements;
553 }
554
565 public static function findRecursiveCallback( ezpAutoloadFileFindContext $context, $sourceDir, $fileName, $fileInfo )
566 {
567 if ( $fileInfo['mode'] & 0x4000 )
568 {
569 return;
570 }
571
572 // update the statistics
573 $context->elements[] = $sourceDir . DIRECTORY_SEPARATOR . $fileName;
574 $context->count++;
575
576 $context->generator->updateProgressOutput( eZAutoloadGenerator::OUTPUT_PROGRESS_PHASE1 );
577 }
578
583 protected function getClassFileList( $fileList, $mode )
584 {
585 $retArray = array();
586 $this->log( "Searching for classes (tokenizing)." );
587 $statArray = array( 'nFiles' => count( $fileList ),
588 'classCount' => 0,
589 'classAdded' => 0,
590 );
591 $this->setStatArray( self::OUTPUT_PROGRESS_PHASE2, $statArray );
592
593 if ( count( $fileList ) )
594 {
595 $this->startProgressOutput( self::OUTPUT_PROGRESS_PHASE2 );
596
597 // Compatibility with PHP 5.2 where T_NAMESPACE constant is not available
598 // Assigning the constant value to $tNamespace
599 // 377 is the value for T_NAMESPACE in PHP 5.3.x
600 $tNamespace = defined( 'T_NAMESPACE' ) ? T_NAMESPACE : self::UNDEFINED_TOKEN;
601
602 // Traits support, see http://issues.ez.no/19028
603 $tTrait = defined( 'T_TRAIT' ) ? T_TRAIT : self::UNDEFINED_TOKEN;
604
605 foreach( $fileList as $file )
606 {
607 $this->updateProgressOutput( self::OUTPUT_PROGRESS_PHASE2 );
608 if ( $mode === self::MODE_SINGLE_EXTENSION )
609 {
610 $file = getcwd() . DIRECTORY_SEPARATOR . $this->options->basePath . DIRECTORY_SEPARATOR . $file;
611 }
612
613 $tokens = @token_get_all( file_get_contents( $file ) );
614 $namespace = null;
615 foreach( $tokens as $key => $token )
616 {
617 if ( is_array( $token ) )
618 {
619 switch( $token[0] )
620 {
621 case self::UNDEFINED_TOKEN:
622 // Unsupported token, do nothing
623 break;
624
625 // Store namespace name, if applicable, to concatenate with class name
626 case $tNamespace:
627 // NAMESPACE_TOKEN - WHITESPACE_TOKEN - TEXT_TOKENS (containing namespace name)
628 $offset = $key + 2;
629 $namespace = "";
630 while ( $tokens[$offset] !== ";" && $tokens[$offset] !== "{" )
631 {
632 if ( is_array( $tokens[$offset] ) )
633 {
634 $namespace .= $tokens[$offset][1];
635 }
636
637 $offset++;
638 }
639
640 $namespace = trim( addcslashes( $namespace, '\\' ) );
641 break;
642
643 case T_CLASS:
644 case T_INTERFACE:
645 case $tTrait:
646 // Ignore token if prefixed by a double colon: "<ClassName>::class"
647 // @see http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class
648 // TEXT_TOKEN - "::"-TEXT_TOKEN - CLASS_TOKEN
649 if ($tokens[$key-1][1] === '::') {
650 break;
651 }
657 if(isset($tokens[$key-2][0]) && $tokens[$key-2][0] === T_NEW) {
658 break;
659 }
660
661 // Increment stat for found class.
662 $this->incrementProgressStat( self::OUTPUT_PROGRESS_PHASE2, 'classCount' );
663
664 // CLASS_TOKEN - WHITESPACE_TOKEN - TEXT_TOKEN (containing class name)
665 if( isset( $tokens[$key+2] ) && is_array( $tokens[$key+2] ) )
666 $className = $tokens[$key+2][1];
667 else
668 $className = $tokens[$key+1][1];
669
670 if ( $namespace !== null )
671 {
672 $className = "$namespace\\\\$className";
673 }
674
675 $filePath = $file;
676
677 if ( $mode === self::MODE_SINGLE_EXTENSION )
678 {
679 $filePath = ezcBaseFile::calculateRelativePath( $filePath, getcwd() . DIRECTORY_SEPARATOR . $this->options->basePath );
680 }
681
682 // make sure we store cross-platform file system paths,
683 // using a forward slash as directory separator
684 if ( DIRECTORY_SEPARATOR != '/' )
685 {
686 $filePath = str_replace( DIRECTORY_SEPARATOR, '/', $filePath );
687 }
688 // Here there are two code paths.
689 // MODE_KERNEL_OVERRIDE will only add a class if
690 // it exists in the MODE_KERNEL autoload array.
691 // All other modes will only add a class if the
692 // class name is unique.
693
694 $addClass = $this->classCanBeAdded( $className, $filePath, $mode, $retArray );
695
696 if ( $addClass )
697 {
698 // increment stat for actually added number of classes.
699 $this->incrementProgressStat( self::OUTPUT_PROGRESS_PHASE2, 'classAdded' );
700
701 $retArray[$className] = $filePath;
702 }
703
704 break;
705 }
706 }
707 }
708 }
709
710 $this->stopProgressOutput( self::OUTPUT_PROGRESS_PHASE2 );
711 ksort( $retArray );
712 }
713
714 if ( $this->output !== null )
715 {
716 extract( $this->getStatArray( self::OUTPUT_PROGRESS_PHASE2 ) );
717 $this->log( "Found {$classCount} classes, added {$classAdded} of them to the autoload array." );
718 }
719
720 return $retArray;
721 }
722
729 protected function checkMaxClassLength( $depData )
730 {
731 $max = array();
732 foreach( array_keys( $depData) as $key )
733 {
734 $max[$key] = 0;
735 }
736
737 foreach( $depData as $location => $locationBundle )
738 {
739 foreach ( $locationBundle as $className => $path )
740 {
741 if ( strlen( $className ) > $max[$location] )
742 {
743 $max[$location] = strlen( $className );
744 }
745 }
746 }
747 return $max;
748 }
749
757 protected function dumpArray( $sortedArray, $length )
758 {
759 $retArray = array();
760 foreach ( $sortedArray as $location => $sorted )
761 {
762 $ret = '';
763 $offset = $length[$location] + 2;
764 foreach( $sorted as $class => $path )
765 {
766 $ret .= sprintf( " %-{$offset}s => '%s'," . PHP_EOL, "'{$class}'", $path );
767 }
768 $retArray[$location] = $ret;
769 }
770 return $retArray;
771 }
772
779 protected function checkMode()
780 {
781 $modes = array( self::MODE_KERNEL, self::MODE_EXTENSION,
782 self::MODE_TESTS, self::MODE_SINGLE_EXTENSION, self::MODE_KERNEL_OVERRIDE );
783
784 $activeModes = array();
785
786 foreach( $modes as $mode )
787 {
788 if ( ( $this->mask & $mode ) == $mode )
789 {
790 $activeModes[] = $mode;
791 }
792 }
793 return $activeModes;
794 }
795
802 protected function runMode()
803 {
804 $mode = self::MODE_NONE;
805
806 // If an extension is given as an argument, that will override other
807 // mode options
808 if ( $this->options->basePath !== getcwd() )
809 {
810 $mode |= self::MODE_SINGLE_EXTENSION;
811 return $mode;
812 }
813
814 if ( $this->options->searchKernelOverride )
815 {
816 $mode |= self::MODE_KERNEL_OVERRIDE;
817 return $mode;
818 }
819
820 // If no file selectors are chosen we will default to extension files.
821 if ( !$this->options->searchKernelFiles and !$this->options->searchExtensionFiles and !$this->options->searchTestFiles )
822 {
823 $mode |= self::MODE_EXTENSION;
824 }
825
826 if ( $this->options->searchKernelFiles )
827 {
828 $mode |= self::MODE_KERNEL;
829 }
830
831 if ( $this->options->searchExtensionFiles )
832 {
833 $mode |= self::MODE_EXTENSION;
834 }
835
836 if ( $this->options->searchTestFiles )
837 {
838 $mode |= self::MODE_TESTS;
839 }
840
841 return $mode;
842 }
843
859 public function setMode( $modeValue )
860 {
861 if ( is_numeric( $modeValue ) and $modeValue > 0 )
862 {
863 $this->mask = $modeValue;
864 }
865 }
866
873 protected function nameTable( $lookup )
874 {
875 $names = array( self::MODE_EXTENSION => "ezp_extension.php",
876 self::MODE_SINGLE_EXTENSION => basename( $this->options->basePath ) . '_autoload.php',
877 self::MODE_KERNEL => "ezp_kernel.php",
878 self::MODE_TESTS => "ezp_tests.php",
879 self::MODE_KERNEL_OVERRIDE => "ezp_override.php",
880 );
881
882 if ( array_key_exists( $lookup, $names ) )
883 {
884 return $names[$lookup];
885 }
886 return false;
887 }
888
895 protected function targetTable( $lookup )
896 {
897 $targets = array(
898 self::MODE_EXTENSION => "var/autoload",
899 self::MODE_TESTS => "var/autoload",
900 self::MODE_KERNEL => "var/autoload",
901 self::MODE_SINGLE_EXTENSION => $this->options->basePath . DIRECTORY_SEPARATOR . 'autoload',
902 self::MODE_KERNEL_OVERRIDE => "var/autoload",
903 );
904
905 if ( array_key_exists( $lookup, $targets ) )
906 {
907 return $targets[$lookup];
908 }
909 return false;
910 }
911
918 protected function dumpArrayStart( $part )
919 {
920 $description = "";
921 switch( $part )
922 {
923 case self::MODE_SINGLE_EXTENSION:
924 $description = basename( $this->options->basePath ) . ' extension';
925 break;
926
927 case self::MODE_EXTENSION:
928 case self::MODE_KERNEL:
929 case self::MODE_TESTS:
930 case self::MODE_KERNEL_OVERRIDE:
931 $description = $this->modeName[$part];
932 break;
933 }
934 return <<<ENDL
935 <?php
946 return array(
947
948 ENDL;
949 }
950
956 protected function dumpArrayEnd()
957 {
958 return <<<END
959 );
960
961 ?>
962
963 END;
964 }
965
990 protected function classCanBeAdded( $class, $file, $mode, $inProgressAutoloadArray )
991 {
992 $addClass = true;
993 $sameRepositoryConflict = false;
994 $kernelRepositoryConflict = false;
995
996 if ( empty( $this->existingAutoloadArrays[self::MODE_KERNEL] ) )
997 {
998 $this->logWarning( "No existing kernel override found. Please generate kernel autoloads first." );
999 }
1000
1001 switch( $mode )
1002 {
1003 case self::MODE_KERNEL:
1004 $sameRepositoryConflict = $this->classExistsInArray( $class, $mode, $file, $inProgressAutoloadArray, $mode );
1005
1006 if ( $sameRepositoryConflict )
1007 {
1008 $addClass = false;
1009 }
1010 break;
1011
1012 case self::MODE_EXTENSION:
1013 case self::MODE_TESTS:
1014 case self::MODE_SINGLE_EXTENSION:
1015 $kernelRepositoryConflict = $this->classExistsInArray( $class, self::MODE_KERNEL, $file, null, $mode );
1016 $sameRepositoryConflict = $this->classExistsInArray( $class, $mode, $file, $inProgressAutoloadArray, $mode );
1017
1018 if ( $kernelRepositoryConflict or $sameRepositoryConflict )
1019 {
1020 $addClass = false;
1021 }
1022 break;
1023
1024 case self::MODE_KERNEL_OVERRIDE:
1025 // For kernel overrides we only want class name collisions in
1026 // the kernel array to trigger a addClass hit. However we
1027 // like to emit warnings about duplicateses found in the current
1028 // generated array. Only one class may be overriding a kernel
1029 // at a time.
1030
1031 $kernelRepositoryConflict = $this->classExistsInArray( $class, self::MODE_KERNEL, $file, $inProgressAutoloadArray, $mode );
1032 $sameRepositoryConflict = $this->classExistsInArray( $class, $mode, $file, $inProgressAutoloadArray, $mode );
1033
1034 if ( ( $sameRepositoryConflict and !$kernelRepositoryConflict ) or
1035 ( $sameRepositoryConflict and $kernelRepositoryConflict ) or
1036 ( !$kernelRepositoryConflict and !$sameRepositoryConflict )
1037 )
1038 {
1039 $addClass = false;
1040 }
1041 break;
1042 }
1043 return $addClass;
1044 }
1045
1056 protected function classExistsInArray( $class, $checkMode, $file, $inProgressAutoloadArray = null, $generatingMode = null )
1057 {
1058 if ( ( $checkMode === $generatingMode ) and $inProgressAutoloadArray !== null )
1059 {
1060 $classCollision = array_key_exists( $class, $inProgressAutoloadArray );
1061 }
1062 else
1063 {
1064 $classCollision = array_key_exists( $class, $this->existingAutoloadArrays[$checkMode] );
1065 }
1066
1067 if ( $classCollision )
1068 {
1069 // If there is a class collisions we want to give feedback to the user.
1070 $this->logIssue( $class, $checkMode, $file, $inProgressAutoloadArray, $generatingMode );
1071 return true;
1072 }
1073 return false;
1074 }
1075
1083 protected function logIssue( $class, $checkMode, $file, $inProgressAutoloadArray, $generatingMode )
1084 {
1085 $conflictFile = ($checkMode === $generatingMode) ?
1086 $inProgressAutoloadArray[$class] :
1087 $this->existingAutoloadArrays[$checkMode][$class];
1088
1089 if ( $generatingMode === self::MODE_KERNEL_OVERRIDE and $checkMode === self::MODE_KERNEL )
1090 {
1091 if ( $inProgressAutoloadArray !== null and array_key_exists( $class, $inProgressAutoloadArray ) )
1092 {
1093 return;
1094 }
1095
1096 $message = "Class {$class}";
1097 $message .= " in file {$file}";
1098 $message .= " will override:\n";
1099 $message .= "{$conflictFile} ({$this->targetTable($checkMode)}/{$this->nameTable($checkMode)})";
1100 $this->log( $message );
1101 }
1102 else
1103 {
1104 $message = "Class {$class}";
1105 $message .= " in file {$file}";
1106 $message .= " is already defined in:\n";
1107 $message .= "{$conflictFile} ({$this->targetTable($checkMode)}/{$this->nameTable($checkMode)})";
1108 $message .= "\nThis class was not added to the autoload array.";
1109 $this->logWarning( $message );
1110 }
1111 }
1112
1121 protected function log( $message )
1122 {
1123 $this->messages[] = $message;
1124 $this->emit( $message, 'normal' );
1125 }
1126
1135 protected function logWarning( $message )
1136 {
1137 $this->warnings[] = $message;
1138
1139 // If we are showing progress output, we display the warnings
1140 // summarized after the other output (CLI)
1141 if ( $this->options->displayProgress )
1142 {
1143 return;
1144 }
1145 $this->emit( $message, 'warning' );
1146 }
1147
1154 public function setOutputCallback( $callback )
1155 {
1156 $this->outputCallback = $callback;
1157 }
1158
1171 protected function emit( $message, $messageType )
1172 {
1173 if ( $this->outputCallback === null )
1174 {
1175 return;
1176 }
1177 call_user_func( $this->outputCallback , $message, $messageType );
1178 }
1179
1185 public function getMessages()
1186 {
1187 return $this->messages;
1188 }
1189
1195 public function getWarnings()
1196 {
1197 return $this->warnings;
1198 }
1199
1210 public function printAutoloadArray( $printForMode = null )
1211 {
1212 if ( $printForMode !== null )
1213 {
1214 if ( array_key_exists( $printForMode, $this->autoloadArrays ) )
1215 {
1216 $this->log( $this->dumpArrayStart( $printForMode ) . $this->autoloadArrays[$printForMode] . $this->dumpArrayEnd() );
1217 }
1218 return;
1219 }
1220
1221 foreach( $this->autoloadArrays as $location => $data )
1222 {
1223 $this->log( $this->dumpArrayStart( $location ) . $data . $this->dumpArrayEnd() );
1224 }
1225 }
1226
1227 public function setOptions( $options )
1228 {
1229 $this->options = $options;
1230 $this->mask = $this->runMode();
1231 }
1232
1243 protected function updateProgressOutput( $phase )
1244 {
1245 if ( !$this->options->displayProgress || $this->output === null )
1246 {
1247 return;
1248 }
1249 $this->output->updateProgress( $phase );
1250 }
1251
1261 protected function incrementProgressStat( $phase, $stat )
1262 {
1263 if ( $this->output === null )
1264 {
1265 return;
1266 }
1267 $statArray = $this->output->getData( $phase );
1268 $statArray[$stat]++;
1269 $this->output->updateData( $phase, $statArray );
1270 }
1271
1278 protected function startProgressOutput( $phase )
1279 {
1280 if ( !$this->options->displayProgress || $this->output === null )
1281 {
1282 return;
1283 }
1284 $func = 'initPhase' . $phase;
1285 $this->output->$func();
1286 }
1287
1294 protected function stopProgressOutput( $phase )
1295 {
1296 if ( !$this->options->displayProgress || $this->output === null )
1297 {
1298 return;
1299 }
1300 $func = 'finishPhase' . $phase;
1301 $this->output->$func();
1302 }
1303
1310 protected function getStatArray( $phase )
1311 {
1312 if ( $this->output === null )
1313 {
1314 return;
1315 }
1316 return $this->output->getData( $phase );
1317 }
1318
1326 protected function setStatArray( $phase, $data )
1327 {
1328 if ( $this->output === null )
1329 {
1330 return;
1331 }
1332 $this->output->updateData( $phase, $data );
1333 }
1334
1344 public function setOutputObject( $outputObject )
1345 {
1346 $this->output = $outputObject;
1347 }
1348 }
1349 ?>
$message
$message
Definition: admin/message.php:51
eZAutoloadGenerator
Definition: ezautoloadgenerator.php:20
eZAutoloadGenerator\handleDefaultExcludeFile
handleDefaultExcludeFile()
Definition: ezautoloadgenerator.php:284
eZAutoloadGenerator\MODE_NONE
const MODE_NONE
Definition: ezautoloadgenerator.php:99
eZAutoloadGenerator\MODE_KERNEL_OVERRIDE
const MODE_KERNEL_OVERRIDE
Definition: ezautoloadgenerator.php:128
eZAutoloadGenerator\walkRecursive
static walkRecursive( $sourceDir, array $includeFilters, array $excludeFilters, $callback, &$callbackContext)
Definition: ezautoloadgenerator.php:460
eZAutoloadGenerator\OUTPUT_PROGRESS_PHASE1
const OUTPUT_PROGRESS_PHASE1
Definition: ezautoloadgenerator.php:134
eZAutoloadGenerator\updateProgressOutput
updateProgressOutput( $phase)
Definition: ezautoloadgenerator.php:1235
eZAutoloadGenerator\setOutputObject
setOutputObject( $outputObject)
Definition: ezautoloadgenerator.php:1336
eZAutoloadGenerator\$warnings
$warnings
Definition: ezautoloadgenerator.php:56
eZAutoloadGenerator\MODE_TESTS
const MODE_TESTS
Definition: ezautoloadgenerator.php:114
eZAutoloadGenerator\$modeName
$modeName
Definition: ezautoloadgenerator.php:78
eZAutoloadGenerator\printAutoloadArray
printAutoloadArray( $printForMode=null)
Definition: ezautoloadgenerator.php:1202
eZAutoloadGenerator\setMode
setMode( $modeValue)
Definition: ezautoloadgenerator.php:859
eZAutoloadGenerator\$messages
$messages
Definition: ezautoloadgenerator.php:49
eZAutoloadGenerator\$options
$options
Definition: ezautoloadgenerator.php:26
eZAutoloadGenerator\emit
emit( $message, $messageType)
Definition: ezautoloadgenerator.php:1163
eZAutoloadGenerator\buildFileList
buildFileList( $path, $extraFilter=null)
Definition: ezautoloadgenerator.php:383
eZAutoloadGenerator\targetTable
targetTable( $lookup)
Definition: ezautoloadgenerator.php:895
eZAutoloadGenerator\dumpArray
dumpArray( $sortedArray, $length)
Definition: ezautoloadgenerator.php:757
eZAutoloadGenerator\logWarning
logWarning( $message)
Definition: ezautoloadgenerator.php:1127
eZAutoloadGenerator\incrementProgressStat
incrementProgressStat( $phase, $stat)
Definition: ezautoloadgenerator.php:1253
eZAutoloadGenerator\dumpArrayEnd
dumpArrayEnd()
Definition: ezautoloadgenerator.php:948
eZAutoloadGenerator\checkMaxClassLength
checkMaxClassLength( $depData)
Definition: ezautoloadgenerator.php:729
eZAutoloadGenerator\writeAutoloadFiles
writeAutoloadFiles()
Definition: ezautoloadgenerator.php:217
eZAutoloadGenerator\setOutputCallback
setOutputCallback( $callback)
Definition: ezautoloadgenerator.php:1146
eZAutoloadGenerator\getClassFileList
getClassFileList( $fileList, $mode)
Definition: ezautoloadgenerator.php:583
eZAutoloadGenerator\OUTPUT_PROGRESS_PHASE2
const OUTPUT_PROGRESS_PHASE2
Definition: ezautoloadgenerator.php:140
eZAutoloadGenerator\stopProgressOutput
stopProgressOutput( $phase)
Definition: ezautoloadgenerator.php:1286
eZAutoloadGenerator\findRecursive
static findRecursive( $sourceDir, array $includeFilters, array $excludeFilters, eZAutoloadGenerator $gen)
Definition: ezautoloadgenerator.php:414
eZAutoloadGenerator\setOptions
setOptions( $options)
Definition: ezautoloadgenerator.php:1219
eZAutoloadGenerator\$existingAutoloadArrays
$existingAutoloadArrays
Definition: ezautoloadgenerator.php:42
eZAutoloadGenerator\$outputCallback
$outputCallback
Definition: ezautoloadgenerator.php:63
eZAutoloadGenerator\log
log( $message)
Definition: ezautoloadgenerator.php:1113
eZAutoloadGenerator\DEFAULT_EXCLUDE_FILE
const DEFAULT_EXCLUDE_FILE
Definition: ezautoloadgenerator.php:146
eZAutoloadGenerator\startProgressOutput
startProgressOutput( $phase)
Definition: ezautoloadgenerator.php:1270
eZAutoloadGenerator\dumpArrayStart
dumpArrayStart( $part)
Definition: ezautoloadgenerator.php:918
eZAutoloadGenerator\setStatArray
setStatArray( $phase, $data)
Definition: ezautoloadgenerator.php:1318
eZAutoloadGenerator\fetchFiles
fetchFiles()
Definition: ezautoloadgenerator.php:303
eZAutoloadGenerator\$autoloadArrays
$autoloadArrays
Definition: ezautoloadgenerator.php:94
eZAutoloadGenerator\classExistsInArray
classExistsInArray( $class, $checkMode, $file, $inProgressAutoloadArray=null, $generatingMode=null)
Definition: ezautoloadgenerator.php:1048
eZAutoloadGenerator\MODE_SINGLE_EXTENSION
const MODE_SINGLE_EXTENSION
Definition: ezautoloadgenerator.php:121
eZAutoloadGenerator\$mask
$mask
Definition: ezautoloadgenerator.php:33
eZAutoloadGenerator\logIssue
logIssue( $class, $checkMode, $file, $inProgressAutoloadArray, $generatingMode)
Definition: ezautoloadgenerator.php:1075
eZAutoloadGenerator\$output
$output
Definition: ezautoloadgenerator.php:70
eZAutoloadGenerator\MODE_KERNEL
const MODE_KERNEL
Definition: ezautoloadgenerator.php:104
eZAutoloadGenerator\nameTable
nameTable( $lookup)
Definition: ezautoloadgenerator.php:873
eZAutoloadGenerator\__construct
__construct(ezpAutoloadGeneratorOptions $options=null)
Definition: ezautoloadgenerator.php:156
eZAutoloadGenerator\MODE_EXTENSION
const MODE_EXTENSION
Definition: ezautoloadgenerator.php:109
eZAutoloadGenerator\getWarnings
getWarnings()
Definition: ezautoloadgenerator.php:1187
eZAutoloadGenerator\checkMode
checkMode()
Definition: ezautoloadgenerator.php:779
eZAutoloadGenerator\buildAutoloadArrays
buildAutoloadArrays()
Definition: ezautoloadgenerator.php:186
eZAutoloadGenerator\getMessages
getMessages()
Definition: ezautoloadgenerator.php:1177
eZAutoloadGenerator\getStatArray
getStatArray( $phase)
Definition: ezautoloadgenerator.php:1302
eZAutoloadGenerator\classCanBeAdded
classCanBeAdded( $class, $file, $mode, $inProgressAutoloadArray)
Definition: ezautoloadgenerator.php:982
eZAutoloadGenerator\runMode
runMode()
Definition: ezautoloadgenerator.php:802
eZAutoloadGenerator\findRecursiveCallback
static findRecursiveCallback(ezpAutoloadFileFindContext $context, $sourceDir, $fileName, $fileInfo)
Definition: ezautoloadgenerator.php:565
eZAutoloadGenerator\UNDEFINED_TOKEN
const UNDEFINED_TOKEN
Definition: ezautoloadgenerator.php:151
ezpAutoloadFileFindContext
Definition: ezpautoloadfilefindcontext.php:18
ezpAutoloadGeneratorOptions
Definition: ezpautoloadgeneratoroptions.php:56
file_exists
static file_exists( $inifilename)
Definition: eZPBINIFile.php:195
$checkMode
if(isSet( $DetailView)) if(isSet( $NormalView)) $checkMode
Definition: ezarticle/admin/categorylist.php:89
$fileList
$fileList
Definition: ezfilemanager/admin/browse.php:163
$fileName
if(eZObjectPermission::hasPermission( $file->id(), "filemanager_file", "r", $user)==false) $fileName
Definition: ezfilemanager/user/filedownload.php:43
$file
$file
Definition: ezfilemanager/user/filedownload.php:35
$filePath
$filePath
Definition: ezfilemanager/user/filedownload.php:50
READ
const READ
Definition: ezmail.php:51
$dir
$dir
Definition: ezsitemanager/admin/filelist.php:87
$ret
$ret
Definition: ezsitemanager/admin/filelist.php:88
$offset
$offset
Definition: ezstats/admin/cron.php:51
$elements
$elements
Definition: formedit.php:355
$part
$part
Definition: tag.php:46
$location
$location
Definition: user/gotolink.php:43
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.