PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/common/libraries/php/util/various/autoloader_utilities.class.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 151 lines | 117 code | 15 blank | 19 comment | 6 complexity | 3af43954b26de176c625d4bad498f1ca MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. namespace common\libraries;
  3. /**
  4. * Generate/update an autoloader based on the file system.
  5. *
  6. * @author laurent
  7. */
  8. class AutoloaderUtilities
  9. {
  10. /**
  11. * Synchronize the autoloader map with the current file structure.
  12. *
  13. * Searches all files and sub directories for class declarations.
  14. * Creates a map of class name to (relative) file path.
  15. * Update the autoloader with the map declaration if $update equals true.
  16. * Returns a map of class name to file path.
  17. *
  18. * @param string $current_dir The current directory in which we search for class declarations
  19. * @param string $root_dir The root directory. The one containing the autoloader declaration
  20. * @param bool $update If true update the autoloader file if one exists. If false only returns the result.
  21. * @return array Array mapping class name to (not relative) path
  22. */
  23. public static function synch($current_dir = null, $root_dir = null, $update = false)
  24. {
  25. $result = array();
  26. $current_dir = $current_dir ? $current_dir : __DIR__;
  27. $root_dir = $root_dir ? $root_dir : __DIR__;
  28. //plugins are not handled by the autoloader.
  29. if (basename($current_dir) == 'plugin')
  30. {
  31. return $result;
  32. }
  33. $files = Filesystem :: get_directory_content($current_dir, Filesystem :: LIST_FILES, false);
  34. foreach ($files as $file)
  35. {
  36. if ($file == 'autoloader.class.php')
  37. {
  38. $root_dir = $current_dir;
  39. break;
  40. }
  41. }
  42. foreach ($files as $file)
  43. {
  44. if (StringUtilities :: end_with($file, '.class.php', false))
  45. {
  46. $content = file_get_contents($current_dir . '/' . $file);
  47. $content = CodeUtilities :: remove_comments($content); //comments may contains class declaration we don't want to capture.
  48. $classes = CodeUtilities :: get_classes($content);
  49. $namespace = CodeUtilities :: get_namespace($content);
  50. $namespace = $namespace ? $namespace . '\\' : '';
  51. foreach ($classes as $class)
  52. {
  53. /* a few classes have the same namespace and class name
  54. * in this case we let the latest win as this may
  55. * relates to different autoloader.
  56. */
  57. $result[$namespace . $class] = $current_dir . '/' . $file;
  58. }
  59. }
  60. }
  61. $directories = Filesystem :: get_directory_content($current_dir, Filesystem :: LIST_DIRECTORIES, false);
  62. foreach ($directories as $dir)
  63. {
  64. $items = self :: synch($current_dir . '/' . $dir, $root_dir, $update);
  65. $result = array_merge($result, $items);
  66. }
  67. //ksort($result);
  68. if ($current_dir == $root_dir && $update)
  69. {
  70. //an autoloader may not exist. For example for p
  71. $autoloader_path = $root_dir . '/autoloader.class.php';
  72. if (is_readable($autoloader_path))
  73. {
  74. $text = file_get_contents($autoloader_path);
  75. $autoloader_namespace = CodeUtilities :: get_namespace($text);
  76. $autoloader_namespace = $autoloader_namespace ? $autoloader_namespace : '';
  77. $format = self :: format($result, $autoloader_namespace, $root_dir);
  78. // //remove existing map if it exists
  79. // $array_pattern = '/\s*private\s*static\s*\$map.*\)\;/isU';
  80. // $text = preg_replace($array_pattern, '', $text);
  81. //
  82. // //add map declaration to the start of the class
  83. // $text = preg_replace_callback(CodeUtilities::CLASS_PATTERN, function($match) use($format)
  84. // {
  85. // return reset($match) . "\n" . $format;
  86. // }, $text);
  87. file_put_contents($autoloader_path, $format);
  88. //debug(htmlentities($format));
  89. }
  90. }
  91. return $result;
  92. }
  93. public static function format($map, $namespace, $root_dir)
  94. {
  95. $format = "array(\n";
  96. foreach ($map as $key => $path)
  97. {
  98. $key = str_replace($namespace . '\\', '', $key);
  99. $path = CodeUtilities :: relative_path($root_dir, $path);
  100. $format .= " '$key' => '$path',\n";
  101. }
  102. $format .= ' )';
  103. $result = <<<EOT
  104. <?php
  105. namespace $namespace;
  106. class Autoloader
  107. {
  108. private static \$map = $format;
  109. static function load(\$classname)
  110. {
  111. if (isset(self::\$map[\$classname]))
  112. {
  113. require_once __DIR__ . self::\$map[\$classname];
  114. return true;
  115. }
  116. return false;
  117. }
  118. static function synch(\$update){
  119. return \\common\\libraries\\AutoloaderUtilities::synch(__DIR__, __DIR__, \$update);
  120. }
  121. }
  122. ?>
  123. EOT;
  124. return $result;
  125. }
  126. }
  127. ?>