/common/libraries/php/util/various/autoloader_utilities.class.php
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
- <?php
-
- namespace common\libraries;
-
- /**
- * Generate/update an autoloader based on the file system.
- *
- * @author laurent
- */
- class AutoloaderUtilities
- {
-
- /**
- * Synchronize the autoloader map with the current file structure.
- *
- * Searches all files and sub directories for class declarations.
- * Creates a map of class name to (relative) file path.
- * Update the autoloader with the map declaration if $update equals true.
- * Returns a map of class name to file path.
- *
- * @param string $current_dir The current directory in which we search for class declarations
- * @param string $root_dir The root directory. The one containing the autoloader declaration
- * @param bool $update If true update the autoloader file if one exists. If false only returns the result.
- * @return array Array mapping class name to (not relative) path
- */
- public static function synch($current_dir = null, $root_dir = null, $update = false)
- {
- $result = array();
- $current_dir = $current_dir ? $current_dir : __DIR__;
- $root_dir = $root_dir ? $root_dir : __DIR__;
-
- //plugins are not handled by the autoloader.
- if (basename($current_dir) == 'plugin')
- {
- return $result;
- }
-
- $files = Filesystem :: get_directory_content($current_dir, Filesystem :: LIST_FILES, false);
- foreach ($files as $file)
- {
- if ($file == 'autoloader.class.php')
- {
- $root_dir = $current_dir;
- break;
- }
- }
-
- foreach ($files as $file)
- {
- if (StringUtilities :: end_with($file, '.class.php', false))
- {
- $content = file_get_contents($current_dir . '/' . $file);
- $content = CodeUtilities :: remove_comments($content); //comments may contains class declaration we don't want to capture.
- $classes = CodeUtilities :: get_classes($content);
-
- $namespace = CodeUtilities :: get_namespace($content);
- $namespace = $namespace ? $namespace . '\\' : '';
-
- foreach ($classes as $class)
- {
- /* a few classes have the same namespace and class name
- * in this case we let the latest win as this may
- * relates to different autoloader.
- */
- $result[$namespace . $class] = $current_dir . '/' . $file;
- }
- }
- }
-
- $directories = Filesystem :: get_directory_content($current_dir, Filesystem :: LIST_DIRECTORIES, false);
- foreach ($directories as $dir)
- {
- $items = self :: synch($current_dir . '/' . $dir, $root_dir, $update);
- $result = array_merge($result, $items);
- }
- //ksort($result);
-
-
- if ($current_dir == $root_dir && $update)
- {
- //an autoloader may not exist. For example for p
- $autoloader_path = $root_dir . '/autoloader.class.php';
- if (is_readable($autoloader_path))
- {
- $text = file_get_contents($autoloader_path);
- $autoloader_namespace = CodeUtilities :: get_namespace($text);
- $autoloader_namespace = $autoloader_namespace ? $autoloader_namespace : '';
-
- $format = self :: format($result, $autoloader_namespace, $root_dir);
-
- // //remove existing map if it exists
- // $array_pattern = '/\s*private\s*static\s*\$map.*\)\;/isU';
- // $text = preg_replace($array_pattern, '', $text);
- //
- // //add map declaration to the start of the class
- // $text = preg_replace_callback(CodeUtilities::CLASS_PATTERN, function($match) use($format)
- // {
- // return reset($match) . "\n" . $format;
- // }, $text);
- file_put_contents($autoloader_path, $format);
-
- //debug(htmlentities($format));
- }
- }
-
- return $result;
- }
-
- public static function format($map, $namespace, $root_dir)
- {
- $format = "array(\n";
- foreach ($map as $key => $path)
- {
- $key = str_replace($namespace . '\\', '', $key);
- $path = CodeUtilities :: relative_path($root_dir, $path);
- $format .= " '$key' => '$path',\n";
- }
- $format .= ' )';
-
- $result = <<<EOT
- <?php
- namespace $namespace;
- class Autoloader
- {
- private static \$map = $format;
- static function load(\$classname)
- {
- if (isset(self::\$map[\$classname]))
- {
- require_once __DIR__ . self::\$map[\$classname];
- return true;
- }
- return false;
- }
- static function synch(\$update){
- return \\common\\libraries\\AutoloaderUtilities::synch(__DIR__, __DIR__, \$update);
- }
- }
- ?>
- EOT;
- return $result;
- }
- }
-
- ?>