diff --git a/administrator/components/com_patchtester/PatchTester/Model/PullModel.php b/administrator/components/com_patchtester/PatchTester/Model/PullModel.php index 4a850d9..4caa803 100644 --- a/administrator/components/com_patchtester/PatchTester/Model/PullModel.php +++ b/administrator/components/com_patchtester/PatchTester/Model/PullModel.php @@ -124,7 +124,7 @@ class PullModel extends AbstractModel throw new RuntimeException(Text::_('COM_PATCHTESTER_REPO_IS_GONE')); } - $sha = $pull->head->sha; + $sha = $pull->head->sha; // Create tmp folder if it does not exist if (!file_exists($ciSettings->get('folder.temp'))) @@ -191,8 +191,16 @@ class PullModel extends AbstractModel // Remove zip to avoid get listing afterwards File::delete($zipPath); + // Verify the composer autoloader for any invalid entries + if ($this->verifyAutoloader($tempPath) === false) + { + // There is something broken in the autoloader, clean up and go back + Folder::delete($tempPath); + throw new RuntimeException(Text::_('COM_PATCHTESTER_PATCH_BREAKS_SITE')); + } + // Get files from deleted_logs - $deletedFiles = (file_exists($delLogPath) ? file($delLogPath) : array()); + $deletedFiles = (file_exists($delLogPath) ? file($delLogPath) : []); $deletedFiles = array_map('trim', $deletedFiles); if (file_exists($delLogPath)) @@ -332,6 +340,65 @@ class PullModel extends AbstractModel return $pull; } + /** + * Verify if the autoload contains any broken entries. + * + * @param string $path The path to look for the autoloader + * + * @return boolean True if there are broken dependencies | False otherwise. + * + * @since 4.0.0 + */ + private function verifyAutoloader(string $path): bool + { + $result = false; + $autoloadClass = false; + + // Check if we have an autoload file + if (!file_exists($path . '/libraries/vendor/autoload.php')) + { + return $result; + } + + // Get the generated token + $autoload = file_get_contents($path . '/libraries/vendor/autoload.php'); + $resultMatch = preg_match('/ComposerAutoloaderInit(.*)::/', $autoload, $match); + + if (!$resultMatch) + { + return $result; + } + + // Load the static autoloader + require_once $path . '/libraries/vendor/composer/autoload_static.php'; + $autoloadClass = '\Composer\Autoload\ComposerStaticInit' . $match[1]; + + // Get all the files + $files = $autoloadClass::$files; + + // Verify all the files exist + foreach ($files as $file) + { + // Fix the filepath to use the Joomla filesystem + $file = str_ireplace($path, JPATH_SITE, $file); + + if (!file_exists($file)) + { + $result = false; + } + } + + // Load the files loader + + // Load the classmap loader + + // Load the namespaces loader + + // Load the PSR-4 loader + + return $result; + } + /** * Saves the applied patch into database * @@ -497,7 +564,7 @@ class PullModel extends AbstractModel // We only create a backup if the file already exists if ($file->action === 'deleted' || (file_exists(JPATH_ROOT . '/' . $file->filename) - && $file->action === 'modified') + && $file->action === 'modified') || (file_exists(JPATH_ROOT . '/' . $file->originalFile) && $file->action === 'renamed')) { $filename = $file->action === 'renamed' ? $file->originalFile : $file->filename; diff --git a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini index 7bf92bf..a5ed87a 100644 --- a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini +++ b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini @@ -106,5 +106,6 @@ COM_PATCHTESTER_TOOLBAR_FETCH_DATA="Fetch Data" COM_PATCHTESTER_TOOLBAR_RESET="Reset" COM_PATCHTESTER_VIEW_ON_GITHUB="View on GitHub" COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER="View on Joomla! Issue Tracker" -COM_PATCHTESTER_ZIP_DOES_NOT_EXIST="The patch could not be applied, because it couldn't be retrieved from server." -COM_PATCHTESTER_ZIP_EXTRACT_FAILED="The patch could not be applied, because it couldn't be extracted." +COM_PATCHTESTER_ZIP_DOES_NOT_EXIST="The patch could not be applied because it couldn't be retrieved from server." +COM_PATCHTESTER_ZIP_EXTRACT_FAILED="The patch could not be applied because it couldn't be extracted." +COM_PATCHTESTER_PATCH_BREAKS_SITE="The patch could not be applied because it would break the site"