From 46cb89adf842e2fbac254fc99355d6577e4e86eb Mon Sep 17 00:00:00 2001 From: Alexis Degrugillier Date: Sat, 26 Dec 2020 06:47:39 -0500 Subject: Extract autoloading process (#3283) * Extract autoloading process The process sits in its own file now to ease future improvements. * Change the autoload process Before, the autoload process was too restricted. It was really dependant on our code tree. It was hard to add more classes to be loaded automatically. On top of that, it did not support autoloading classes following the PSR-4 recommendation. Now, the autoload process is more open. It supports partially the PSR-4 recommendation, there is no specific code to load Minz classes or PHPMailer classes. This is the starting point to reorganize the codebase to introduce long waiting changes as seen in #789. It would be a nice to later rework the tree, rename classes, and add namespace in a fashion that follows the PSR-4. Then specific FRSS workarounds in the autoload could be dropped. --- lib/autoload.php | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/lib_rss.php | 29 ++-------------------- 2 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 lib/autoload.php (limited to 'lib') diff --git a/lib/autoload.php b/lib/autoload.php new file mode 100644 index 000000000..5be952876 --- /dev/null +++ b/lib/autoload.php @@ -0,0 +1,74 @@ +searchPath[] = $path; + } + if (is_array($path)) { + array_push($this->searchPath, ...$path); + } + } + + /** + * Load class file if found. + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + require $file; + } + } + + /** + * Find the file containing the class definition. + */ + public function findFile($class) { + // This match most of classes directly + foreach ($this->searchPath as $path) { + $file = $path . DIRECTORY_SEPARATOR . str_replace(['\\', '_'], DIRECTORY_SEPARATOR, $class) . '.php'; + if (file_exists($file)) { + return $file; + } + } + + // This match FRSS model classes + $freshrssClass = str_replace('FreshRSS_', '', $class); + foreach ($this->searchPath as $path) { + $file = $path . DIRECTORY_SEPARATOR . str_replace(['\\', '_'], DIRECTORY_SEPARATOR, $freshrssClass) . '.php'; + if (file_exists($file)) { + return $file; + } + } + + // This match FRSS other classes + list(, $classType) = explode('_', $freshrssClass); + foreach ($this->searchPath as $path) { + $file = $path . DIRECTORY_SEPARATOR . $classType . 's' . DIRECTORY_SEPARATOR . str_replace('_', '', $freshrssClass) . '.php'; + if (file_exists($file)) { + return $file; + } + } + } + + /** + * Register the current loader in the autoload queue. + */ + public function register($prepend = false) { + spl_autoload_register([$this, 'loadClass'], true, $prepend); + } +} + +$loader = new ClassLoader(); +$loader->registerPath([ + APP_PATH, + APP_PATH . DIRECTORY_SEPARATOR . 'Models', + LIB_PATH, + LIB_PATH . DIRECTORY_SEPARATOR . 'SimplePie', +]); +$loader->register(); diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 64f12c633..1ee054c14 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -15,6 +15,8 @@ if (COPY_SYSLOG_TO_STDERR) { openlog('FreshRSS', LOG_CONS | LOG_ODELAY | LOG_PID, LOG_USER); } +require_once LIB_PATH . DIRECTORY_SEPARATOR . 'autoload.php'; + /** * Build a directory path by concatenating a list of directory names. * @@ -26,33 +28,6 @@ function join_path() { return join(DIRECTORY_SEPARATOR, $path_parts); } -// -function classAutoloader($class) { - if (strpos($class, 'FreshRSS') === 0) { - $components = explode('_', $class); - switch (count($components)) { - case 1: - include(APP_PATH . '/' . $components[0] . '.php'); - return; - case 2: - include(APP_PATH . '/Models/' . $components[1] . '.php'); - return; - case 3: //Controllers, Exceptions - include(APP_PATH . '/' . $components[2] . 's/' . $components[1] . $components[2] . '.php'); - return; - } - } elseif (strpos($class, 'Minz') === 0) { - include(LIB_PATH . '/' . str_replace('_', '/', $class) . '.php'); - } elseif (strpos($class, 'SimplePie') === 0) { - include(LIB_PATH . '/SimplePie/' . str_replace('_', '/', $class) . '.php'); - } elseif (strpos($class, 'PHPMailer') === 0) { - include(LIB_PATH . '/' . str_replace('\\', '/', $class) . '.php'); - } -} - -spl_autoload_register('classAutoloader'); -// - function idn_to_puny($url) { if (function_exists('idn_to_ascii')) { $idn = parse_url($url, PHP_URL_HOST); -- cgit v1.2.3