From f508cca64c64094d6171630a7fa95cc22ab80a27 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 18 Dec 2024 11:58:30 +0200 Subject: [PATCH] before upgrade --- upgrades/9.0/data.json | 3 + upgrades/9.0/scripts/BeforeUpgrade.php | 156 +++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 upgrades/9.0/data.json create mode 100644 upgrades/9.0/scripts/BeforeUpgrade.php diff --git a/upgrades/9.0/data.json b/upgrades/9.0/data.json new file mode 100644 index 0000000000..3d74c7fbee --- /dev/null +++ b/upgrades/9.0/data.json @@ -0,0 +1,3 @@ +{ + "manifest": {} +} diff --git a/upgrades/9.0/scripts/BeforeUpgrade.php b/upgrades/9.0/scripts/BeforeUpgrade.php new file mode 100644 index 0000000000..54a2a05082 --- /dev/null +++ b/upgrades/9.0/scripts/BeforeUpgrade.php @@ -0,0 +1,156 @@ +. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +use Espo\Core\Container; +use Espo\Entities\Extension; +use Espo\ORM\EntityManager; + +/** @noinspection PhpMultipleClassDeclarationsInspection */ +class BeforeUpgrade +{ + private ?Container $container = null; + + /** + * @throws Exception + */ + public function run(Container $container): void + { + $this->container = $container; + + $this->processCheckExtensions(); + + $this->checkBadClasses([ + 'Espo\\Core\\Services\\Base', + 'Espo\\Core\\ORM\\Repositories\\RDB', + 'Espo\\Core\\Hooks\\Base', + 'Espo\\Core\\Acl\\Base', + 'Espo\\Core\\Acl\\Acl', + 'Espo\\Core\\AclPortal\\Base', + 'Espo\\Core\\AclPortal\\Acl', + 'Espo\\Core\\Injectable', + ]); + } + + /** + * @param string[] $badList + * @throws Exception + * @noinspection PhpSameParameterValueInspection + */ + private function checkBadClasses(array $badList): void + { + foreach (['custom', 'application/Espo/Modules'] as $dir) { + $this->loadFromDir($dir); + } + + $ignoreList = [ + 'Espo\\Core\\Acl\\Acl', + 'Espo\\Core\\AclPortal\\Acl', + 'Espo\\Core\\Cleanup\\Base', + ]; + + $msg = ''; + + foreach (get_declared_classes() as $class) { + if (in_array($class, $ignoreList)) { + continue; + } + + foreach ($badList as $badClass) { + if (is_subclass_of($class, $badClass) && $class !== $badClass) { + $msg .= " $class is sub-class of $badClass\n"; + } + } + } + + if ($msg !== '') { + $msg = "These classes should be fixed before upgrade. " . + "They extend classes that are removed in the next version.\n\n" . $msg; + + throw new Exception($msg); + } + } + + private function loadFromDir(string $dir): void + { + $directory = new \RecursiveDirectoryIterator($dir); + $fullTree = new \RecursiveIteratorIterator($directory); + $phpFiles = new \RegexIterator($fullTree, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH); + + foreach ($phpFiles as $file) { + require_once($file[0]); + } + } + + /** + * @throws Error + */ + private function processCheckExtensions(): void + { + $errorMessageList = []; + + $this->processCheckExtension('VoIP Integration', '2.0.0', $errorMessageList); + $this->processCheckExtension('Real Estate', '1.8.3', $errorMessageList); + + if (!count($errorMessageList)) { + return; + } + + $message = implode("\n\n", $errorMessageList); + + throw new Error($message); + } + + private function processCheckExtension(string $name, string $minVersion, array &$errorMessageList): void + { + $em = $this->container->getByClass(EntityManager::class); + + $extension = $em->getRDBRepository(Extension::ENTITY_TYPE) + ->where([ + 'name' => $name, + 'isInstalled' => true, + ]) + ->findOne(); + + if (!$extension) { + return; + } + + $version = $extension->get('version'); + + if (version_compare($version, $minVersion, '>=')) { + return; + } + + $message = + "EspoCRM 9.0 is not compatible with '$name' extension of versions lower than $minVersion. " . + "Please upgrade the extension or uninstall it."; + + $errorMessageList[] = $message; + } +}