From: Matthias Schmidt Date: Sun, 19 May 2013 12:51:00 +0000 (+0200) Subject: Adds support for file installation of application plugins X-Git-Tag: 2.0.0_Beta_1~154 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=04727c8bc79e5ff15e7076c77eacf4491e681fd3;p=GitHub%2FWoltLab%2FWCF.git Adds support for file installation of application plugins Closes #1163 --- diff --git a/wcfsetup/install/files/acp/templates/templateList.tpl b/wcfsetup/install/files/acp/templates/templateList.tpl index e0327e97e3..88048c4453 100644 --- a/wcfsetup/install/files/acp/templates/templateList.tpl +++ b/wcfsetup/install/files/acp/templates/templateList.tpl @@ -93,7 +93,7 @@ {event name='rowButtons'} {@$template->templateID} - {if $template->packageDir}[{$template->getPackageAbbreviation()}] {/if}{if $template->templateGroupID}{$template->templateName}{else}{$template->templateName}{/if} + {if $template->application != 'wcf'}[{$template->application}] {/if}{if $template->templateGroupID}{$template->templateName}{else}{$template->templateName}{/if} {@$template->lastModificationTime|time} {event name='columns'} diff --git a/wcfsetup/install/files/lib/acp/page/TemplateListPage.class.php b/wcfsetup/install/files/lib/acp/page/TemplateListPage.class.php index e0147317c5..f99d46f162 100644 --- a/wcfsetup/install/files/lib/acp/page/TemplateListPage.class.php +++ b/wcfsetup/install/files/lib/acp/page/TemplateListPage.class.php @@ -92,7 +92,7 @@ class TemplateListPage extends SortablePage { public function readData() { parent::readData(); - // get template groups + // get template groups $templateGroupList = new TemplateGroupList(); $templateGroupList->readObjects(); $this->availableTemplateGroups = $templateGroupList->getObjects(); diff --git a/wcfsetup/install/files/lib/data/application/Application.class.php b/wcfsetup/install/files/lib/data/application/Application.class.php index 23916d4861..e2711d567b 100644 --- a/wcfsetup/install/files/lib/data/application/Application.class.php +++ b/wcfsetup/install/files/lib/data/application/Application.class.php @@ -1,7 +1,11 @@ */ - protected $pageURL = ''; + protected static $directories = null; /** * Returns absolute page URL. @@ -47,4 +57,30 @@ class Application extends DatabaseObject { return $this->pageURL; } + + /** + * Returns the directory of the application with the given abbrevation. + * + * @param string $abbreviation + * @return string + */ + public static function getDirectory($abbreviation) { + if (static::$directories === null) { + static::$directories = array(); + + // read application directories + $packageList = new PackageList(); + $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1)); + $packageList->readObjects(); + foreach ($packageList as $package) { + static::$directories[Package::getAbbreviation($package->package)] = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$package->packageDir)); + } + } + + if (!isset(static::$directories[$abbreviation])) { + throw new SystemException("Unknown application '".$abbreviation."'"); + } + + return static::$directories[$abbreviation]; + } } diff --git a/wcfsetup/install/files/lib/data/template/Template.class.php b/wcfsetup/install/files/lib/data/template/Template.class.php index e7e06abb94..9757b08fbd 100644 --- a/wcfsetup/install/files/lib/data/template/Template.class.php +++ b/wcfsetup/install/files/lib/data/template/Template.class.php @@ -74,15 +74,6 @@ class Template extends DatabaseObject { return @file_get_contents($this->getPath()); } - /** - * Returns the abbreviation of the package name. - * - * @return string - */ - public function getPackageAbbreviation() { - return Package::getAbbreviation($this->package); - } - /** * Searches in templates. * diff --git a/wcfsetup/install/files/lib/system/WCFSetup.class.php b/wcfsetup/install/files/lib/system/WCFSetup.class.php index 2744342c54..d6832ee049 100644 --- a/wcfsetup/install/files/lib/system/WCFSetup.class.php +++ b/wcfsetup/install/files/lib/system/WCFSetup.class.php @@ -777,13 +777,13 @@ class WCFSetup extends WCF { // save acp template log if (!empty($acpTemplateInserts)) { $sql = "INSERT INTO wcf".WCF_N."_acp_template - (templateName) - VALUES (?)"; + (templateName, application) + VALUES (?, ?)"; $statement = self::getDB()->prepareStatement($sql); self::getDB()->beginTransaction(); foreach ($acpTemplateInserts as $acpTemplate) { - $statement->executeUnbuffered(array($acpTemplate)); + $statement->executeUnbuffered(array($acpTemplate, 'wcf')); } self::getDB()->commitTransaction(); } @@ -792,13 +792,13 @@ class WCFSetup extends WCF { // save file log if (!empty($fileInserts)) { $sql = "INSERT INTO wcf".WCF_N."_package_installation_file_log - (filename) - VALUES (?)"; + (filename, application) + VALUES (?, ?)"; $statement = self::getDB()->prepareStatement($sql); self::getDB()->beginTransaction(); foreach ($fileInserts as $file) { - $statement->executeUnbuffered(array($file)); + $statement->executeUnbuffered(array($file, 'wcf')); } self::getDB()->commitTransaction(); } diff --git a/wcfsetup/install/files/lib/system/package/ACPTemplatesFileHandler.class.php b/wcfsetup/install/files/lib/system/package/ACPTemplatesFileHandler.class.php index b5c131af5a..27d23868f8 100644 --- a/wcfsetup/install/files/lib/system/package/ACPTemplatesFileHandler.class.php +++ b/wcfsetup/install/files/lib/system/package/ACPTemplatesFileHandler.class.php @@ -8,7 +8,7 @@ use wcf\system\WCF; /** * File handler implementation for the installation of ACP template files. * - * @author Alexander Ebert + * @author Alexander Ebert, Matthias Schmidt * @copyright 2001-2013 WoltLab GmbH * @license GNU Lesser General Public License * @package com.woltlab.wcf @@ -27,24 +27,21 @@ class ACPTemplatesFileHandler extends PackageInstallationFileHandler { */ public function checkFiles(array $files) { if ($this->packageInstallation->getPackage()->package != 'com.woltlab.wcf') { - $packageID = $this->packageInstallation->getPackageID(); - - // build sql string with ACP-templateNames - $fileNames = array(); - foreach ($files as $file) { - $fileNames[] = substr($file, 0, -4); - } - // check if files are existing already - if (!empty($fileNames)) { + if (!empty($files)) { + foreach ($files as &$file) { + $file = substr($file, 0, -4); + } + unset($file); + // get by other packages registered files $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("packageID <> ?", array($packageID)); - $conditions->add("packageID IN (SELECT packageID FROM wcf".WCF_N."_package WHERE packageDir = ? AND isApplication = ?)", array($this->packageInstallation->getPackage()->packageDir, 0)); - $conditions->add("templateName IN (?)", array($fileNames)); + $conditions->add('packageID <> ?', array($this->packageInstallation->getPackageID())); + $conditions->add('templateName IN (?)', array($files)); + $conditions->add('application = ?', array($this->application)); - $sql = "SELECT * - FROM wcf".WCF_N."_".$this->tableName." + $sql = "SELECT packageID, templateName + FROM wcf".WCF_N."_".$this->tableName." ".$conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); @@ -54,12 +51,15 @@ class ACPTemplatesFileHandler extends PackageInstallationFileHandler { $lockedFiles[$row['templateName']] = $row['packageID']; } - // check if files from installing package are in conflict with already installed files + // check if acp templates from the package beeing + // installed are in conflict with already installed + // files if (!$this->packageInstallation->getPackage()->isApplication && !empty($lockedFiles)) { - foreach ($fileNames as $key => $file) { - if (isset($lockedFiles[$file]) && $packageID != $lockedFiles[$file]) { + foreach ($files as $file) { + if (isset($lockedFiles[$file])) { $owningPackage = new Package($lockedFiles[$file]); - throw new SystemException("A non-application package can't overwrite template files. Only an update from the package which owns the template can do that. (Package '".$this->packageInstallation->getPackage()->package."' tries to overwrite template '".$file."', which is owned by package '".$owningPackage->package."')"); + + throw new SystemException("A package can't overwrite templates from other packages. Only an update from the package which owns the template can do that. (Package '".$this->packageInstallation->getPackage()->package."' tries to overwrite template '".$file."', which is owned by package '".$owningPackage->package."')"); } } } @@ -71,23 +71,26 @@ class ACPTemplatesFileHandler extends PackageInstallationFileHandler { * @see wcf\system\setup\IFileHandler::logFiles() */ public function logFiles(array $files) { - $packageID = $this->packageInstallation->getPackageID(); - // remove file extension foreach ($files as &$file) { $file = substr($file, 0, -4); } unset($file); - // get existing templates + // fetch already installed acp templates + $conditions = new PreparedStatementConditionBuilder(); + $conditions->add('packageID = ?', array($this->packageInstallation->getPackageID())); + $conditions->add('templateName IN (?)', array($files)); + $conditions->add('application = ?', array($this->application)); + $sql = "SELECT templateName FROM wcf".WCF_N."_".$this->tableName." - WHERE packageID = ?"; + ".$conditions; $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute(array($packageID)); + $statement->execute($conditions->getParameters()); - while ($row = $statement->fetchArray()) { - $index = array_search($row['templateName'], $files); + while ($templateName = $statement->fetchColumn()) { + $index = array_search($templateName, $files); if ($index !== false) { unset($files[$index]); @@ -96,14 +99,15 @@ class ACPTemplatesFileHandler extends PackageInstallationFileHandler { if (!empty($files)) { $sql = "INSERT INTO wcf".WCF_N."_".$this->tableName." - (packageID, templateName) - VALUES (?, ?)"; + (packageID, templateName, application) + VALUES (?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); foreach ($files as $file) { $statement->execute(array( - $packageID, - $file + $this->packageInstallation->getPackageID(), + $file, + $this->application )); } } diff --git a/wcfsetup/install/files/lib/system/package/FilesFileHandler.class.php b/wcfsetup/install/files/lib/system/package/FilesFileHandler.class.php index 67617ea410..fda4ac8dcb 100644 --- a/wcfsetup/install/files/lib/system/package/FilesFileHandler.class.php +++ b/wcfsetup/install/files/lib/system/package/FilesFileHandler.class.php @@ -1,13 +1,15 @@ * @package com.woltlab.wcf * @subpackage system.package @@ -20,29 +22,30 @@ class FilesFileHandler extends PackageInstallationFileHandler { public function checkFiles(array $files) { if ($this->packageInstallation->getPackage()->package != 'com.woltlab.wcf') { if (!empty($files)) { - // get by other packages registered files + // get registered files of other packages for the + // same application $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("file_log.packageID <> ?", array($this->packageInstallation->getPackageID())); - $conditions->add("file_log.filename IN (?)", array($files)); + $conditions->add('packageID <> ?', array($this->packageInstallation->getPackageID())); + $conditions->add('filename IN (?)', array($files)); + $conditions->add('application = ?', array($this->application)); - $sql = "SELECT file_log.filename, package.packageDir - FROM wcf".WCF_N."_package_installation_file_log file_log - LEFT JOIN wcf".WCF_N."_package package - ON (package.packageID = file_log.packageID) + $sql = "SELECT filename, packageID + FROM wcf".WCF_N."_package_installation_file_log ".$conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $lockedFiles = array(); while ($row = $statement->fetchArray()) { - $lockedFiles[$row['packageDir'].$row['filename']] = true; + $lockedFiles[$row['filename']] = $row['packageID']; } // check delivered files if (!empty($lockedFiles)) { - $dir = $this->packageInstallation->getPackage()->packageDir; foreach ($files as $key => $file) { - if (isset($lockedFiles[$dir.$file])) { - unset($files[$key]); + if (isset($lockedFiles[$file])) { + $owningPackage = new Package($lockedFiles[$file]); + + throw new SystemException("A package can't overwrite files from other packages. Only an update from the package which owns the file can do that. (Package '".$this->packageInstallation->getPackage()->package."' tries to overwrite file '".$file."', which is owned by package '".$owningPackage->package."')"); } } } @@ -60,39 +63,35 @@ class FilesFileHandler extends PackageInstallationFileHandler { // fetch already installed files $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("packageID = ?", array($this->packageInstallation->getPackageID())); - $conditions->add("filename IN (?)", array($files)); + $conditions->add('packageID = ?', array($this->packageInstallation->getPackageID())); + $conditions->add('filename IN (?)', array($files)); + $conditions->add('application = ?', array($this->application)); $sql = "SELECT filename FROM wcf".WCF_N."_package_installation_file_log ".$conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); - $installedFiles = array(); - while ($row = $statement->fetchArray()) { - $installedFiles[] = $row['filename']; - } - // ignore files which have already been installed - $installFiles = array(); - foreach ($files as $file) { - if (in_array($file, $installedFiles)) { - continue; - } + while ($filename = $statement->fetchColumn()) { + $index = array_search($filename, $files); - $installFiles[] = $file; + if ($index !== false) { + unset($files[$index]); + } } - if (!empty($installFiles)) { + if (!empty($files)) { $sql = "INSERT INTO wcf".WCF_N."_package_installation_file_log - (packageID, filename) - VALUES (?, ?)"; + (packageID, filename, application) + VALUES (?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); - foreach ($installFiles as $file) { + foreach ($files as $file) { $statement->execute(array( $this->packageInstallation->getPackageID(), - $file + $file, + $this->application )); } } diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationFileHandler.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationFileHandler.class.php index 1e38211693..bcc0c1471c 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationFileHandler.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationFileHandler.class.php @@ -7,13 +7,19 @@ use wcf\system\setup\IFileHandler; * installation. * * @author Marcel Werk - * @copyright 2001-2012 WoltLab GmbH + * @copyright 2001-2013 WoltLab GmbH * @license GNU Lesser General Public License * @package com.woltlab.wcf * @subpackage system.package * @category Community Framework */ abstract class PackageInstallationFileHandler implements IFileHandler { + /** + * abbrevation of the application the files belong to + * @var array + */ + protected $application = ''; + /** * active package installation dispatcher * @var wcf\system\package\PackageInstallationDispatcher @@ -25,7 +31,8 @@ abstract class PackageInstallationFileHandler implements IFileHandler { * * @param wcf\system\package\PackageInstallationDispatcher $packageInstallation */ - public function __construct(PackageInstallationDispatcher $packageInstallation) { + public function __construct(PackageInstallationDispatcher $packageInstallation, $application) { $this->packageInstallation = $packageInstallation; + $this->application = $application; } } diff --git a/wcfsetup/install/files/lib/system/package/TemplatesFileHandler.class.php b/wcfsetup/install/files/lib/system/package/TemplatesFileHandler.class.php index 82e7a72fa3..34a6bfb4df 100644 --- a/wcfsetup/install/files/lib/system/package/TemplatesFileHandler.class.php +++ b/wcfsetup/install/files/lib/system/package/TemplatesFileHandler.class.php @@ -36,17 +36,18 @@ class TemplatesFileHandler extends ACPTemplatesFileHandler { $sql = "SELECT templateName, templateID FROM wcf".WCF_N."_template WHERE packageID = ? + AND application = ? AND templateGroupID IS NULL"; $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute(array($packageID)); + $statement->execute(array($packageID, $this->application)); while ($row = $statement->fetchArray()) { $existingTemplates[$row['templateName']] = $row['templateID']; } // save new templates $sql = "INSERT INTO wcf".WCF_N."_template - (packageID, templateName, lastModificationTime) - VALUES (?, ?, ?)"; + (packageID, templateName, lastModificationTime, application) + VALUES (?, ?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); foreach ($files as $file) { if (isset($existingTemplates[$file])) { @@ -57,7 +58,8 @@ class TemplatesFileHandler extends ACPTemplatesFileHandler { $statement->execute(array( $packageID, $file, - TIME_NOW + TIME_NOW, + $this->application )); } diff --git a/wcfsetup/install/files/lib/system/package/plugin/ACPTemplatePackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/ACPTemplatePackageInstallationPlugin.class.php index 739200ed54..f16e9918c0 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/ACPTemplatePackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/ACPTemplatePackageInstallationPlugin.class.php @@ -1,14 +1,14 @@ * @package com.woltlab.wcf @@ -27,25 +27,25 @@ class ACPTemplatePackageInstallationPlugin extends AbstractPackageInstallationPl public function install() { parent::install(); + $abbreviation = 'wcf'; + if (isset($this->instruction['attributes']['application'])) { + $abbreviation = $this->instruction['attributes']['application']; + } + else if ($this->installation->getPackage()->isApplication) { + $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); + } + + // absolute path to package dir + $packageDir = Application::getDirectory($abbreviation); + // extract files.tar to temp folder $sourceFile = $this->installation->getArchive()->extractTar($this->instruction['value'], 'acptemplates_'); // create file handler - $fileHandler = new ACPTemplatesFileHandler($this->installation); - - // extract content of files.tar - $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$this->installation->getPackage()->packageDir)); + $fileHandler = new ACPTemplatesFileHandler($this->installation, $abbreviation); - try { - $fileInstaller = $this->installation->extractFiles($packageDir.'acp/templates/', $sourceFile, $fileHandler); - } - catch (SystemException $e) { - WCF::getTPL()->assign(array( - 'exception' => $e - )); - WCF::getTPL()->display('packageInstallationFileInstallationFailed'); - exit; - } + // extract templates + $this->installation->extractFiles($packageDir.'acp/templates/', $sourceFile, $fileHandler); // delete temporary sourceArchive @unlink($sourceFile); @@ -55,25 +55,24 @@ class ACPTemplatePackageInstallationPlugin extends AbstractPackageInstallationPl * @see wcf\system\package\plugin\IPackageInstallationPlugin::uninstall() */ public function uninstall() { - // create ACP-templates list - $templates = array(); - - // get ACP-templates from log - $sql = "SELECT * + // fetch ACP templates from log + $sql = "SELECT templateName, application FROM wcf".WCF_N."_acp_template WHERE packageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID())); + + $templates = array(); while ($row = $statement->fetchArray()) { - // store acp template with suffix (_$packageID) - $templates[] = 'acp/templates/'.$row['templateName'].'.tpl'; + if (!isset($templates[$row['application']])) { + $templates[$row['application']] = array(); + } + + $templates[$row['application']][] = 'acp/templates/'.$row['templateName'].'.tpl'; } - if (!empty($templates)) { - // delete template files - $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$this->installation->getPackage()->packageDir)); - $deleteEmptyDirectories = $this->installation->getPackage()->isApplication; - $this->installation->deleteFiles($packageDir, $templates, false, $deleteEmptyDirectories); + foreach ($templates as $application => $templateNames) { + $this->installation->deleteFiles(Application::getDirectory($application), $templateNames, false, $this->installation->getPackage()->isApplication); // delete log entries parent::uninstall(); diff --git a/wcfsetup/install/files/lib/system/package/plugin/FilePackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/FilePackageInstallationPlugin.class.php index 45f7922776..9231213594 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/FilePackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/FilePackageInstallationPlugin.class.php @@ -1,17 +1,17 @@ * @package com.woltlab.wcf * @subpackage system.package.plugin @@ -29,14 +29,22 @@ class FilePackageInstallationPlugin extends AbstractPackageInstallationPlugin { public function install() { parent::install(); + $abbreviation = 'wcf'; + if (isset($this->instruction['attributes']['application'])) { + $abbreviation = $this->instruction['attributes']['application']; + } + else if ($this->installation->getPackage()->isApplication) { + $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); + } + // absolute path to package dir - $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$this->installation->getPackage()->packageDir)); + $packageDir = Application::getDirectory($abbreviation); // extract files.tar to temp folder $sourceFile = $this->installation->getArchive()->extractTar($this->instruction['value'], 'files_'); // create file handler - $fileHandler = new FilesFileHandler($this->installation); + $fileHandler = new FilesFileHandler($this->installation, $abbreviation); // extract content of files.tar $fileInstaller = $this->installation->extractFiles($packageDir, $sourceFile, $fileHandler); @@ -51,10 +59,14 @@ class FilePackageInstallationPlugin extends AbstractPackageInstallationPlugin { // log file $sql = "INSERT INTO wcf".WCF_N."_package_installation_file_log - (packageID, filename) - VALUES (?, 'config.inc.php')"; + (packageID, filename, application) + VALUES (?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute(array($this->installation->getPackageID())); + $statement->execute(array( + $this->installation->getPackageID(), + 'config.inc.php', + Package::getAbbreviation($this->installation->getPackage()->package) + )); } // delete temporary sourceArchive @@ -68,25 +80,24 @@ class FilePackageInstallationPlugin extends AbstractPackageInstallationPlugin { * @see wcf\system\package\plugin\IPackageInstallationPlugin::uninstall() */ public function uninstall() { - // get absolute package dir - $packageDir = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(realpath(WCF_DIR.$this->installation->getPackage()->packageDir))); - - // create file list - $files = array(); - - // get files from log - $sql = "SELECT * + // fetch files from log + $sql = "SELECT filename, application FROM wcf".WCF_N."_package_installation_file_log WHERE packageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID())); + + $files = array(); while ($row = $statement->fetchArray()) { - $files[] = $row['filename']; + if (!isset($files[$row['application']])) { + $files[$row['application']] = array(); + } + + $files[$row['application']][] = $row['filename']; } - if (!empty($files)) { - // delete files - $this->installation->deleteFiles($packageDir, $files); + foreach ($files as $application => $filenames) { + $this->installation->deleteFiles(Application::getDirectory($application), $filenames); // delete log entries parent::uninstall(); diff --git a/wcfsetup/install/files/lib/system/package/plugin/TemplatePackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/TemplatePackageInstallationPlugin.class.php index 3578fe8e9e..5dac956941 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/TemplatePackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/TemplatePackageInstallationPlugin.class.php @@ -1,14 +1,15 @@ * @package com.woltlab.wcf * @subpackage system.package.plugin @@ -26,16 +27,24 @@ class TemplatePackageInstallationPlugin extends AbstractPackageInstallationPlugi public function install() { parent::install(); + $abbreviation = 'wcf'; + if (isset($this->instruction['attributes']['application'])) { + $abbreviation = $this->instruction['attributes']['application']; + } + else if ($this->installation->getPackage()->isApplication) { + $abbreviation = Package::getAbbreviation($this->installation->getPackage()->package); + } + + // absolute path to package dir + $packageDir = Application::getDirectory($abbreviation); + // extract files.tar to temp folder $sourceFile = $this->installation->getArchive()->extractTar($this->instruction['value'], 'templates_'); // create file handler - $fileHandler = new TemplatesFileHandler($this->installation); - - // extract content of files.tar - $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$this->installation->getPackage()->packageDir)); + $fileHandler = new TemplatesFileHandler($this->installation, $abbreviation); - $fileInstaller = $this->installation->extractFiles($packageDir.'templates/', $sourceFile, $fileHandler); + $this->installation->extractFiles($packageDir.'templates/', $sourceFile, $fileHandler); // delete temporary sourceArchive @unlink($sourceFile); @@ -45,24 +54,24 @@ class TemplatePackageInstallationPlugin extends AbstractPackageInstallationPlugi * Uninstalls the templates of this package. */ public function uninstall() { - // create templates list - $templates = array(); - - // get templates from log - $sql = "SELECT templateName + // fetch templates from log + $sql = "SELECT templateName, application FROM wcf".WCF_N."_template WHERE packageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID())); + + $templates = array(); while ($row = $statement->fetchArray()) { - $templates[] = 'templates/'.$row['templateName'].'.tpl'; + if (!isset($templates[$row['application']])) { + $templates[$row['application']] = array(); + } + + $templates[$row['application']][] = 'templates/'.$row['templateName'].'.tpl'; } - if (!empty($templates)) { - // delete template files - $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR.$this->installation->getPackage()->packageDir)); - $deleteEmptyDirectories = $this->installation->getPackage()->isApplication; - $this->installation->deleteFiles($packageDir, $templates, false, $deleteEmptyDirectories); + foreach ($templates as $application => $templateNames) { + $this->installation->deleteFiles(Application::getDirectory($application), $templateNames, false, $this->installation->getPackage()->isApplication); // delete log entries parent::uninstall(); diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index 373576abf2..3930441ade 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -106,8 +106,9 @@ DROP TABLE IF EXISTS wcf1_acp_template; CREATE TABLE wcf1_acp_template ( templateID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, packageID INT(10), - templateName VARCHAR(255) NOT NULL DEFAULT '', - UNIQUE KEY (packageID, templateName) + templateName VARCHAR(255) NOT NULL, + application VARCHAR(255) NOT NULL, + UNIQUE KEY applicationTemplate (application, templateName) ); DROP TABLE IF EXISTS wcf1_application; @@ -345,8 +346,9 @@ CREATE TABLE wcf1_package_exclusion ( DROP TABLE IF EXISTS wcf1_package_installation_file_log; CREATE TABLE wcf1_package_installation_file_log ( packageID INT(10), - filename VARCHAR(255) NOT NULL DEFAULT '', - UNIQUE KEY packageID (packageID, filename) + filename VARCHAR(255) NOT NULL, + application VARCHAR(255) NOT NULL, + UNIQUE KEY applicationFile (application, filename) ); DROP TABLE IF EXISTS wcf1_package_installation_form; @@ -583,11 +585,12 @@ DROP TABLE IF EXISTS wcf1_template; CREATE TABLE wcf1_template ( templateID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, packageID INT(10) NOT NULL, - templateName VARCHAR(255) NOT NULL DEFAULT '', + templateName VARCHAR(255) NOT NULL, + application VARCHAR(255) NOT NULL, templateGroupID INT(10), lastModificationTime INT(10) NOT NULL DEFAULT 0, - KEY packageID (packageID, templateName), - KEY templateGroupID (packageID, templateGroupID, templateName) + UNIQUE KEY applicationTemplate (application, templateName), + UNIQUE KEY templateGroupID (application, templateGroupID, templateName) ); DROP TABLE IF EXISTS wcf1_template_group;