/** * @see wcf\system\package\plugin\IPackageInstallationPlugin::uninstall() */ public function uninstall() { // call uninstall event EventHandler::fireAction($this, 'uninstall'); // get all style of this package $isDefault = false; $styleList = new StyleList(); $styleList->getConditionBuilder()->add("packageID = ?", array($this->installation->getPackageID())); $styleList->sqlLimit = 0; $styleList->readObjects(); foreach ($styleList->getObjects() as $style) { $styleEditor = new StyleEditor($style); $styleEditor->delete(); $isDefault = $isDefault || $style->isDefault; } // default style deleted if ($isDefault) { $styleList = new StyleList(); $styleList->sqlOrderBy = 'style.styleID ASC'; $styleList->sqlLimit = 1; $styleList->readObjects(); $styles = $styleList->getObjects(); if (count($styles)) { $styleEditor = new StyleEditor($styles[0]); $styleEditor->setAsDefault(); } } }
/** * Copies a style. * * @return array<string> */ public function copy() { // get unique style name $sql = "SELECT\tstyleName\n\t\t\tFROM\twcf" . WCF_N . "_style\n\t\t\tWHERE\tstyleName LIKE ?\n\t\t\t\tAND styleID <> ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleEditor->styleName . '%', $this->styleEditor->styleID)); $numbers = array(); $regEx = new Regex('\\((\\d+)\\)$'); while ($row = $statement->fetchArray()) { $styleName = $row['styleName']; if ($regEx->match($styleName)) { $matches = $regEx->getMatches(); // check if name matches the pattern 'styleName (x)' if ($styleName == $this->styleEditor->styleName . ' (' . $matches[1] . ')') { $numbers[] = $matches[1]; } } } $number = count($numbers) ? max($numbers) + 1 : 2; $styleName = $this->styleEditor->styleName . ' (' . $number . ')'; // create the new style $newStyle = StyleEditor::create(array('styleName' => $styleName, 'templateGroupID' => $this->styleEditor->templateGroupID, 'isDisabled' => 1, 'styleDescription' => $this->styleEditor->styleDescription, 'styleVersion' => $this->styleEditor->styleVersion, 'styleDate' => $this->styleEditor->styleDate, 'copyright' => $this->styleEditor->copyright, 'license' => $this->styleEditor->license, 'authorName' => $this->styleEditor->authorName, 'authorURL' => $this->styleEditor->authorURL, 'imagePath' => $this->styleEditor->imagePath)); // check if style description uses i18n if (preg_match('~^wcf.style.styleDescription\\d+$~', $newStyle->styleDescription)) { $styleDescription = 'wcf.style.styleDescription' . $newStyle->styleID; // copy language items $sql = "INSERT INTO\twcf" . WCF_N . "_language_item\n\t\t\t\t\t\t(languageID, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID)\n\t\t\t\tSELECT\t\tlanguageID, '" . $styleDescription . "', languageItemValue, 0, languageCategoryID, packageID\n\t\t\t\tFROM\t\twcf" . WCF_N . "_language_item\n\t\t\t\tWHERE\t\tlanguageItem = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($newStyle->styleDescription)); // update style description $styleEditor = new StyleEditor($newStyle); $styleEditor->update(array('styleDescription' => $styleDescription)); } // copy style variables $sql = "INSERT INTO\twcf" . WCF_N . "_style_variable_value\n\t\t\t\t\t(styleID, variableID, variableValue)\n\t\t\tSELECT\t\t" . $newStyle->styleID . " AS styleID, value.variableID, value.variableValue\n\t\t\tFROM\t\twcf" . WCF_N . "_style_variable_value value\n\t\t\tWHERE\t\tvalue.styleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleEditor->styleID)); // copy preview image if ($this->styleEditor->image) { // get extension $fileExtension = mb_substr($this->styleEditor->image, mb_strrpos($this->styleEditor->image, '.')); // copy existing preview image if (@copy(WCF_DIR . 'images/' . $this->styleEditor->image, WCF_DIR . 'images/stylePreview-' . $newStyle->styleID . $fileExtension)) { // bypass StyleEditor::update() to avoid scaling of already fitting image $sql = "UPDATE\twcf" . WCF_N . "_style\n\t\t\t\t\tSET\timage = ?\n\t\t\t\t\tWHERE\tstyleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array('stylePreview-' . $newStyle->styleID . $fileExtension, $newStyle->styleID)); } } // copy images if ($this->styleEditor->imagePath && is_dir(WCF_DIR . $this->styleEditor->imagePath)) { $path = FileUtil::removeTrailingSlash($this->styleEditor->imagePath); $newPath = ''; $i = 2; while (true) { $newPath = "{$path}-{$i}/"; if (!file_exists(WCF_DIR . $newPath)) { break; } $i++; } if (!FileUtil::makePath(WCF_DIR . $newPath)) { $newPath = ''; } if ($newPath) { $src = FileUtil::addTrailingSlash(WCF_DIR . $this->styleEditor->imagePath); $dst = WCF_DIR . $newPath; $dir = opendir($src); while (($file = readdir($dir)) !== false) { if ($file != '.' && $file != '..' && !is_dir($file)) { @copy($src . $file, $dst . $file); } } closedir($dir); } $sql = "UPDATE\twcf" . WCF_N . "_style\n\t\t\t\tSET\timagePath = ?\n\t\t\t\tWHERE\tstyleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($newPath, $newStyle->styleID)); } StyleCacheBuilder::getInstance()->reset(); return array('redirectURL' => LinkHandler::getInstance()->getLink('StyleEdit', array('id' => $newStyle->styleID))); }
/** * @see \wcf\data\IEditableObject::create() */ public static function create(array $parameters = array()) { $variables = null; if (isset($parameters['variables'])) { $variables = $parameters['variables']; unset($parameters['variables']); } // default values if (!isset($parameters['packageID'])) { $parameters['packageID'] = 1; } if (!isset($parameters['styleDate'])) { $parameters['styleDate'] = gmdate('Y-m-d', TIME_NOW); } // check if no default style is defined $sql = "SELECT\tstyleID\n\t\t\tFROM\twcf" . WCF_N . "_style\n\t\t\tWHERE\tisDefault = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(1)); $row = $statement->fetchArray(); // no default style exists if ($row === false) { $parameters['isDefault'] = 1; } // save style $style = parent::create($parameters); $styleEditor = new StyleEditor($style); // save variables if ($variables !== null) { $styleEditor->setVariables($variables); } // scale preview image if (!empty($parameters['image'])) { self::scalePreviewImage(WCF_DIR . $parameters['image']); } return $style; }
/** * Updates styles files of all styles. */ protected function cleanup() { // get all styles $styleList = new StyleList(); $styleList->sqlLimit = 0; $styleList->readObjects(); foreach ($styleList->getObjects() as $style) { $styleEditor = new StyleEditor($style); $styleEditor->writeStyleFile(); } }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); $this->objectAction = new StyleAction(array(), 'create', array('data' => array_merge($this->additionalFields, array('styleName' => $this->styleName, 'templateGroupID' => $this->templateGroupID, 'isDisabled' => 1, 'styleDescription' => '', 'styleVersion' => $this->styleVersion, 'styleDate' => $this->styleDate, 'imagePath' => $this->imagePath, 'copyright' => $this->copyright, 'license' => $this->license, 'authorName' => $this->authorName, 'authorURL' => $this->authorURL)), 'tmpHash' => $this->tmpHash, 'variables' => $this->variables)); $returnValues = $this->objectAction->executeAction(); $style = $returnValues['returnValues']; // save style description I18nHandler::getInstance()->save('styleDescription', 'wcf.style.styleDescription' . $style->styleID, 'wcf.style'); $styleEditor = new StyleEditor($style); $styleEditor->update(array('styleDescription' => 'wcf.style.styleDescription' . $style->styleID)); // call saved event $this->saved(); // reset variables $this->authorName = $this->authorURL = $this->copyright = $this->image = ''; $this->license = $this->styleDate = $this->styleDescription = $this->styleName = $this->styleVersion = ''; $this->imagePath = 'images/'; $this->templateGroupID = 0; I18nHandler::getInstance()->reset(); // reload variables $this->readStyleVariables(); WCF::getTPL()->assign('success', true); }
/** * @see wcf\data\IEditableObject::create() */ public static function create(array $parameters = array()) { $variables = null; if (isset($parameters['variables'])) { $variables = $parameters['variables']; unset($parameters['variables']); } // default values if (!isset($parameters['packageID'])) { $parameters['packageID'] = PACKAGE_ID; } if (!isset($parameters['styleDate'])) { $parameters['styleDate'] = gmdate('Y-m-d', TIME_NOW); } // save style $style = parent::create($parameters); $styleEditor = new StyleEditor($style); // save variables if ($variables !== null) { $styleEditor->setVariables($variables); } // scale preview image if (!empty($parameters['image'])) { self::scalePreviewImage(WCF_DIR . $parameters['image']); } return $style; }
/** * Copies a style. * * @return array<string> */ public function copy() { // get unique style name $sql = "SELECT styleName FROM wcf".WCF_N."_style WHERE styleName LIKE ? AND styleID <> ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array( $this->styleEditor->styleName.'%', $this->styleEditor->styleID )); $numbers = array(); $regEx = new Regex('\((\d+)\)$'); while ($row = $statement->fetchArray()) { $styleName = $row['styleName']; if ($regEx->match($styleName)) { $matches = $regEx->getMatches(); // check if name matches the pattern 'styleName (x)' if ($styleName == $this->styleEditor->styleName . ' ('.$matches[1].')') { $numbers[] = $matches[1]; } } } $number = (count($numbers)) ? max($numbers) + 1 : 2; $styleName = $this->styleEditor->styleName . ' ('.$number.')'; // create the new style $newStyle = StyleEditor::create(array( 'packageID' => PACKAGE_ID, 'styleName' => $styleName, 'templateGroupID' => $this->styleEditor->templateGroupID, 'isDisabled' => 1, // newly created styles are disabled by default 'styleDescription' => $this->styleEditor->styleDescription, 'styleVersion' => $this->styleEditor->styleVersion, 'styleDate' => $this->styleEditor->styleDate, 'copyright' => $this->styleEditor->copyright, 'license' => $this->styleEditor->license, 'authorName' => $this->styleEditor->authorName, 'authorURL' => $this->styleEditor->authorURL, 'imagePath' => $this->styleEditor->imagePath )); // copy style variables $sql = "INSERT INTO wcf".WCF_N."_style_variable_value (styleID, variableID, variableValue) SELECT ".$newStyle->styleID." AS styleID, value.variableID, value.variableValue FROM wcf".WCF_N."_style_variable_value value WHERE value.styleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->styleEditor->styleID)); // copy preview image if ($this->styleEditor->image) { // get extension $fileExtension = StringUtil::substring($this->styleEditor->image, StringUtil::lastIndexOf($this->styleEditor->image, '.')); // copy existing preview image if (@copy(WCF_DIR.'images/'.$this->styleEditor->image, WCF_DIR.'images/stylePreview-'.$newStyle->styleID.$fileExtension)) { // bypass StyleEditor::update() to avoid scaling of already fitting image $sql = "UPDATE wcf".WCF_N."_style SET image = ? WHERE styleID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array( 'stylePreview-'.$newStyle->styleID.$fileExtension, $newStyle->styleID )); } } return array( 'redirectURL' => LinkHandler::getInstance()->getLink('StyleEdit', array('id' => $newStyle->styleID)) ); }
/** * @see wcf\form\IForm::save() */ public function save() { parent::save(); // get style filename $filename = str_replace(' ', '-', preg_replace('/[^a-z0-9 _-]/', '', StringUtil::toLowerCase($this->style->styleName))); // send headers header('Content-Type: application/x-gzip; charset=utf-8'); if ($this->exportAsPackage) { header('Content-Disposition: attachment; filename="'.$this->packageName.'.tar.gz"'); } else { header('Content-Disposition: attachment; filename="'.$filename.'-style.tgz"'); } // export style $styleEditor = new StyleEditor($this->style); $styleEditor->export($this->exportTemplates, $this->exportImages, $this->packageName); // call saved event $this->saved(); exit; }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->source['name'])) { throw new UserInputException('source'); } if (empty($this->source['tmp_name'])) { throw new UserInputException('source', 'uploadFailed'); } try { // check if the uploaded file is a package $archive = new PackageArchive($this->source['tmp_name']); $archive->openArchive(); // check if the package is an application if ($archive->getPackageInfo('isApplication')) { throw new SystemException("Package is application"); } // check if the package includes a style $containsStyle = false; $installInstructions = $archive->getInstallInstructions(); foreach ($installInstructions as $instruction) { if ($instruction['pip'] == 'style') { $containsStyle = true; break; } } if (!$containsStyle) { throw new SystemException("Package contains no style"); } $filename = FileUtil::getTemporaryFilename('package_', preg_replace('!^.*(?=\\.(?:tar\\.gz|tgz|tar)$)!i', '', basename($this->source['name']))); if (!@move_uploaded_file($this->source['tmp_name'], $filename)) { throw new SystemException("Cannot move uploaded file"); } WCF::getSession()->register('stylePackageImportLocation', $filename); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('PackageStartInstall', array('action' => 'install'))); exit; } catch (SystemException $e) { // ignore errors } try { $this->style = StyleEditor::import($this->source['tmp_name']); } catch (\Exception $e) { @unlink($this->source['tmp_name']); throw new UserInputException('source', 'importFailed'); } }