From a71a204a50ab57f1a3fdcbb22d6861d27199bc7f Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Sun, 14 Mar 2021 09:07:15 +0100 Subject: [PATCH] Add `DatabasePackageInstallationPlugin` --- com.woltlab.wcf/packageInstallationPlugin.xml | 1 + ...atabasePackageInstallationPlugin.class.php | 113 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 wcfsetup/install/files/lib/system/package/plugin/DatabasePackageInstallationPlugin.class.php diff --git a/com.woltlab.wcf/packageInstallationPlugin.xml b/com.woltlab.wcf/packageInstallationPlugin.xml index 4d40c7f98e..943f68c06a 100644 --- a/com.woltlab.wcf/packageInstallationPlugin.xml +++ b/com.woltlab.wcf/packageInstallationPlugin.xml @@ -31,5 +31,6 @@ wcf\system\package\plugin\MenuPackageInstallationPlugin wcf\system\package\plugin\MenuItemPackageInstallationPlugin wcf\system\package\plugin\MediaProviderPackageInstallationPlugin + wcf\system\package\plugin\DatabasePackageInstallationPlugin diff --git a/wcfsetup/install/files/lib/system/package/plugin/DatabasePackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/DatabasePackageInstallationPlugin.class.php new file mode 100644 index 0000000000..30cdaf0a01 --- /dev/null +++ b/wcfsetup/install/files/lib/system/package/plugin/DatabasePackageInstallationPlugin.class.php @@ -0,0 +1,113 @@ + + * @package WoltLabSuite\Core\System\Package\Plugin + */ +class DatabasePackageInstallationPlugin extends AbstractPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin +{ + public const SCRIPT_DIR = 'acp/database/'; + + /** + * @inheritDoc + */ + public function install() + { + parent::install(); + + $abbreviation = 'wcf'; + $path = ''; + if (isset($this->instruction['attributes']['application'])) { + $abbreviation = $this->instruction['attributes']['application']; + } elseif ($this->installation->getPackage()->isApplication) { + $path = FileUtil::getRealPath(WCF_DIR . $this->installation->getPackage()->packageDir); + } + + if (empty($path)) { + $dirConstant = \strtoupper($abbreviation) . '_DIR'; + if (!\defined($dirConstant)) { + throw new \InvalidArgumentException("Cannot execute database PIP, abbreviation '{$abbreviation}' is unknown."); + } + + $path = \constant($dirConstant); + } + + $scriptPath = $path . $this->instruction['value']; + + $this->updateDatabase($scriptPath); + + if (@\unlink($scriptPath)) { + $sql = "DELETE FROM wcf" . WCF_N . "_package_installation_file_log + WHERE packageID = ? + AND filename = ?"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute([ + $this->installation->getPackageID(), + $this->instruction['value'], + ]); + } + } + + /** + * Runs the database script at the given path. + * + * @param string $scriptPath + */ + private function updateDatabase(string $scriptPath): void + { + $tables = include($scriptPath); + if (!\is_array($tables)) { + throw new \UnexpectedValueException("A database script must return an array."); + } + + (new DatabaseTableChangeProcessor( + $this->installation->getPackage(), + $tables, + WCF::getDB()->getEditor() + ))->process(); + } + + /** + * @inheritDoc + */ + public function hasUninstall() + { + // Database scripts cannot be uninstalled. + return false; + } + + /** + * @inheritDoc + */ + public function uninstall() + { + // does nothing + } + + /** + * @inheritDoc + */ + public static function getDefaultFilename() + { + return static::SCRIPT_DIR . '*.php'; + } + + /** + * @inheritDoc + */ + public static function getSyncDependencies() + { + return ['file']; + } +} -- 2.20.1