Classes

File core/ClassLoader.class.php

File core/ClassLoader.class.php

  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 
<?php
/**
 * @package     Core
 * @copyright   &copy; 2005-2019 PHPBoost
 * @license     https://www.gnu.org/licenses/gpl-3.0.html GNU/GPL-3.0
 * @author      Loic ROUCHON <horn@phpboost.com>
 * @version     PHPBoost 5.2 - last update: 2016 11 15
 * @since       PHPBoost 3.0 - 2009 10 21
 * @contributor mipel <mipel@phpboost.com>
*/

class ClassLoader
{
    private static $cache_file = '/cache/autoload.php';
    private static $autoload;
    private static $already_reloaded = false;
    private static $exclude_paths = array(
        '/cache', '/images', '/lang', '/upload', '/templates',
        '/kernel/data', '/kernel/lib/js', '/kernel/lib/flash', '/kernel/lib/css', '/kernel/lib/php/geshi',
        '/kernel/framework/io/db/dbms/Doctrine', '/test/PHPUnit',
    );

    private static $exclude_folders_names = array('templates', 'lang');

    /**
     * initializes the autoload class list
     */
    public static function init_autoload()
    {
        spl_autoload_register(array(get_class(), 'autoload'));
        if (!self::inc(PATH_TO_ROOT . self::$cache_file))
        {
            self::generate_classlist();
        }
    }

    /**
     * tries to autoload the given <code>$classname</code> else, a fatal error is raised
     * @param string $classname the name of the class to load
     */
    public static function autoload($classname)
    {
        if (!isset(self::$autoload[$classname]) || !self::inc(PATH_TO_ROOT . self::$autoload[$classname]))
        {
            self::generate_classlist();
            if (isset(self::$autoload[$classname]))
            {
                require_once PATH_TO_ROOT . self::$autoload[$classname];
            }
        }
        self::call_static_initializer($classname);
    }

    public static function is_class_registered_and_valid($classname)
    {
        if (!self::is_class_registered($classname))
        {
            return false;
        }
        elseif (!file_exists(PATH_TO_ROOT . self::$autoload[$classname]))
        {
            self::generate_classlist();
            return self::is_class_registered($classname);
        }
        else
        {
            return true;
        }
    }

    /**
     * Generates the autoload cache file by exploring phpboost folders
     */
    public static function generate_classlist()
    {
        if (!self::$already_reloaded)
        {
            self::$already_reloaded = true;
            self::$autoload = array();

            include_once(PATH_TO_ROOT . '/kernel/framework/io/filesystem/FileSystemElement.class.php');
            include_once(PATH_TO_ROOT . '/kernel/framework/io/filesystem/Folder.class.php');
            include_once(PATH_TO_ROOT . '/kernel/framework/io/filesystem/File.class.php');
            include_once(PATH_TO_ROOT . '/kernel/framework/io/IOException.class.php');
            include_once(PATH_TO_ROOT . '/kernel/framework/util/Path.class.php');

            $phpboost_classfile_pattern = '`\.class\.php$`';
            $paths = array('/', '/kernel/framework/core/lang');

            foreach ($paths as $path)
            {
                self::add_classes(Path::phpboost_path() . $path, $phpboost_classfile_pattern);
            }
            self::add_classes(Path::phpboost_path() . '/kernel/framework/io/db/dbms/Doctrine/', '`\.php$`');
            self::generate_autoload_cache();
        }
    }

    public static function clear_cache()
    {
        $file = new File(PATH_TO_ROOT . self::$cache_file);
        $file->delete();
        self::$already_reloaded = false;
    }

    private static function is_class_registered($classname)
    {
        return array_key_exists($classname, self::$autoload);
    }

    private static function add_classes($directory, $pattern, $recursive = true)
    {
        $files = array();
        $folder = new Folder($directory);
        $relative_path = Path::get_path_from_root($folder->get_path());
        $files = $folder->get_files($pattern);
        foreach ($files as $file)
        {
            $filename = $file->get_name();
            $classname = $file->get_name_without_extension();
            self::$autoload[$classname] = $relative_path . '/' . $filename;
        }

        if ($recursive)
        {
            $folders = $folder->get_folders('`^[a-z]{1}.*$`iu');
            foreach ($folders as $a_folder)
            {
                if (!in_array($a_folder->get_path_from_root(), self::$exclude_paths)
                && !in_array($a_folder->get_name(), self::$exclude_folders_names))
                {
                    self::add_classes($a_folder->get_path(), $pattern);
                }
            }
        }
    }

    private static function generate_autoload_cache()
    {
        $file = new File(PATH_TO_ROOT . self::$cache_file);
        try
        {
            $file->write('<?php self::$autoload = ' . var_export(self::$autoload, true) . '; ?>');
            $file->close();
        }
        catch (IOException $ex)
        {
            die('The cache folder is not writeable, please set CHMOD to 777');
        }
    }

    private static function inc($file)
    {
        return file_exists($file) && @include_once $file;
    }

    private static function call_static_initializer($classname)
    {
        if (method_exists($classname, '__static'))
        {
            call_user_func(array($classname, '__static'));
        }
    }
}
?>