From 3b5caaf4e8a156d5dfce996dcc12214ee5c4427a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 29 Dec 2025 08:07:59 -0800 Subject: [PATCH] scss autoloader + jsonresponse fixes Signed-off-by: Andy Miller --- admin.php | 48 +++++++++++++++++++++++++++--- classes/plugin/AdminController.php | 21 +++++++------ classes/plugin/WhiteLabel.php | 17 +++++++++-- 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/admin.php b/admin.php index 305b7683..ed73880d 100644 --- a/admin.php +++ b/admin.php @@ -179,6 +179,42 @@ class AdminPlugin extends Plugin */ public function autoload(): ClassLoader { + // Register a fallback autoloader for vendor dependencies that might be missing during upgrades. + // This helps prevent "class not found" errors when upgrading between versions with different dependencies. + // The fallback reads the autoload maps fresh from disk each time - critical because files may change during upgrades. + $psr4File = __DIR__ . '/vendor/composer/autoload_psr4.php'; + $classmapFile = __DIR__ . '/vendor/composer/autoload_classmap.php'; + + spl_autoload_register(function ($class) use ($psr4File, $classmapFile) { + // Read fresh from disk - files may have been replaced during an upgrade + $classMap = file_exists($classmapFile) ? (include $classmapFile) : []; + $psr4Map = file_exists($psr4File) ? (include $psr4File) : []; + + // First check classmap for exact class match + if (isset($classMap[$class]) && file_exists($classMap[$class])) { + require_once $classMap[$class]; + return true; + } + + // Then try PSR-4 namespaces + foreach ($psr4Map as $prefix => $paths) { + $prefixLen = strlen($prefix); + if (strncmp($prefix, $class, $prefixLen) === 0) { + $relativeClass = substr($class, $prefixLen); + $relativePath = str_replace('\\', '/', $relativeClass) . '.php'; + + foreach ($paths as $path) { + $file = $path . '/' . $relativePath; + if (file_exists($file)) { + require_once $file; + return true; + } + } + } + } + return false; + }, true, false); // prepend=true to run before other autoloaders + return require __DIR__ . '/vendor/autoload.php'; } @@ -1111,13 +1147,17 @@ class AdminPlugin extends Plugin return new Themes($this->grav); }; - // Initialize white label functionality - $this->grav['admin-whitelabel'] = new WhiteLabel(); + // Initialize white label functionality (lazy-loaded to avoid loading scssphp during upgrades) + $this->grav['admin-whitelabel'] = function () { + return new WhiteLabel(); + }; - // Compile a missing preset.css file + // Compile a missing preset.css file - skip during AJAX task requests to avoid autoloader conflicts during upgrades + $task = $this->uri->param('task') ?? $this->uri->query('task'); + $isTaskRequest = !empty($task); $preset_css = 'asset://admin-preset.css'; $preset_path = $this->grav['locator']->findResource($preset_css); - if (!$preset_path) { + if (!$preset_path && !$isTaskRequest) { $this->grav['admin-whitelabel']->compilePresetScss($this->config->get('plugins.admin.whitelabel')); } diff --git a/classes/plugin/AdminController.php b/classes/plugin/AdminController.php index 36b56c0e..a85be847 100644 --- a/classes/plugin/AdminController.php +++ b/classes/plugin/AdminController.php @@ -1041,15 +1041,16 @@ class AdminController extends AdminBaseController $result = Gpm::install(array_keys($dependencies), ['theme' => $type === 'themes']); if ($result) { - $this->admin->json_response = ['status' => 'success', 'message' => 'Dependencies installed successfully']; + $json_response = ['status' => 'success', 'message' => 'Dependencies installed successfully']; } else { - $this->admin->json_response = [ + $json_response = [ 'status' => 'error', 'message' => $this->admin::translate('PLUGIN_ADMIN.INSTALLATION_FAILED') ]; } - return true; + // Exit early to prevent any post-install code from running with potentially mismatched autoloaders + $this->sendJsonResponse($json_response); } /** @@ -1094,19 +1095,20 @@ class AdminController extends AdminBaseController } if ($result) { - $this->admin->json_response = [ + $json_response = [ 'status' => 'success', 'message' => $this->admin::translate(is_string($result) ? $result : sprintf($this->admin::translate($reinstall ?: 'PLUGIN_ADMIN.PACKAGE_X_REINSTALLED_SUCCESSFULLY', null), $package)) ]; } else { - $this->admin->json_response = [ + $json_response = [ 'status' => 'error', 'message' => $this->admin::translate($reinstall ?: 'PLUGIN_ADMIN.INSTALLATION_FAILED') ]; } - return true; + // Exit early to prevent any post-install code from running with potentially mismatched autoloaders + $this->sendJsonResponse($json_response); } /** @@ -1219,19 +1221,20 @@ class AdminController extends AdminBaseController $result = Gpm::directInstall($url); if ($result === true) { - $this->admin->json_response = [ + $json_response = [ 'status' => 'success', 'message' => $this->admin::translate(sprintf($this->admin::translate('PLUGIN_ADMIN.PACKAGE_X_REINSTALLED_SUCCESSFULLY', null), $package_name)) ]; } else { - $this->admin->json_response = [ + $json_response = [ 'status' => 'error', 'message' => $this->admin::translate('PLUGIN_ADMIN.REINSTALLATION_FAILED') ]; } - return true; + // Exit early to prevent any post-install code from running with potentially mismatched autoloaders + $this->sendJsonResponse($json_response); } /** diff --git a/classes/plugin/WhiteLabel.php b/classes/plugin/WhiteLabel.php index a9ecdb8a..8d01d25b 100644 --- a/classes/plugin/WhiteLabel.php +++ b/classes/plugin/WhiteLabel.php @@ -23,7 +23,20 @@ class WhiteLabel public function __construct() { $this->grav = Grav::instance(); - $this->scss = new ScssCompiler(); + // ScssCompiler is now lazy-loaded to avoid loading scssphp classes until actually needed + } + + /** + * Get the ScssCompiler instance (lazy-loaded) + * + * @return ScssCompiler + */ + protected function getScss(): ScssCompiler + { + if ($this->scss === null) { + $this->scss = new ScssCompiler(); + } + return $this->scss; } public function compilePresetScss($config, $options = [ @@ -61,7 +74,7 @@ class WhiteLabel } try { - $compiler = $this->scss->reset(); + $compiler = $this->getScss()->reset(); $compiler->setVariables($color_scheme['colors'] + $color_scheme['accents']); $compiler->setImportPaths($imports);