ClassMapGenerator.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\ClassLoader;
  11. /**
  12. * ClassMapGenerator
  13. *
  14. * @author Gyula Sallai <salla016@gmail.com>
  15. */
  16. class ClassMapGenerator
  17. {
  18. /**
  19. * Generate a class map file
  20. *
  21. * @param array|string $dirs Directories or a single path to search in
  22. * @param string $file The name of the class map file
  23. */
  24. static public function dump($dirs, $file)
  25. {
  26. $dirs = (array) $dirs;
  27. $maps = array();
  28. foreach ($dirs as $dir) {
  29. $maps = array_merge($maps, static::createMap($dir));
  30. }
  31. file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true)));
  32. }
  33. /**
  34. * Iterate over all files in the given directory searching for classes
  35. *
  36. * @param Iterator|string $dir The directory to search in or an iterator
  37. *
  38. * @return array A class map array
  39. */
  40. static public function createMap($dir)
  41. {
  42. if (is_string($dir)) {
  43. $dir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
  44. }
  45. $map = array();
  46. foreach ($dir as $file) {
  47. if (!$file->isFile()) {
  48. continue;
  49. }
  50. $path = $file->getRealPath();
  51. if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') {
  52. continue;
  53. }
  54. $classes = self::findClasses($path);
  55. foreach ($classes as $class) {
  56. $map[$class] = $path;
  57. }
  58. }
  59. return $map;
  60. }
  61. /**
  62. * Extract the classes in the given file
  63. *
  64. * @param string $path The file to check
  65. *
  66. * @return array The found classes
  67. */
  68. static private function findClasses($path)
  69. {
  70. $contents = file_get_contents($path);
  71. $tokens = token_get_all($contents);
  72. $T_TRAIT = version_compare(PHP_VERSION, '5.4', '<') ? -1 : T_TRAIT;
  73. $classes = array();
  74. $namespace = '';
  75. for ($i = 0, $max = count($tokens); $i < $max; $i++) {
  76. $token = $tokens[$i];
  77. if (is_string($token)) {
  78. continue;
  79. }
  80. $class = '';
  81. switch ($token[0]) {
  82. case T_NAMESPACE:
  83. $namespace = '';
  84. // If there is a namespace, extract it
  85. while (($t = $tokens[++$i]) && is_array($t)) {
  86. if (in_array($t[0], array(T_STRING, T_NS_SEPARATOR))) {
  87. $namespace .= $t[1];
  88. }
  89. }
  90. $namespace .= '\\';
  91. break;
  92. case T_CLASS:
  93. case T_INTERFACE:
  94. case $T_TRAIT:
  95. // Find the classname
  96. while (($t = $tokens[++$i]) && is_array($t)) {
  97. if (T_STRING === $t[0]) {
  98. $class .= $t[1];
  99. } elseif ($class !== '' && T_WHITESPACE == $t[0]) {
  100. break;
  101. }
  102. }
  103. $classes[] = ltrim($namespace . $class, '\\');
  104. break;
  105. default:
  106. break;
  107. }
  108. }
  109. return $classes;
  110. }
  111. }