/** * @see \wcf\data\AbstractDatabaseObjectAction::create() */ public function create() { $template = parent::create(); if (isset($this->parameters['source'])) { $editor = new TemplateEditor($template); $editor->setSource($this->parameters['source']); } return $template; }
/** * Imports a style. * * @param string $filename * @param integer $packageID * @param StyleEditor $style * @return StyleEditor */ public static function import($filename, $packageID = 1, StyleEditor $style = null) { // open file $tar = new Tar($filename); // get style data $data = self::readStyleData($tar); $styleData = array('styleName' => $data['name'], 'variables' => $data['variables'], 'styleVersion' => $data['version'], 'styleDate' => $data['date'], 'copyright' => $data['copyright'], 'license' => $data['license'], 'authorName' => $data['authorName'], 'authorURL' => $data['authorURL']); // create template group if (!empty($data['templates'])) { $templateGroupName = $originalTemplateGroupName = $data['name']; $templateGroupFolderName = preg_replace('/[^a-z0-9_-]/i', '', $templateGroupName); if (empty($templateGroupFolderName)) { $templateGroupFolderName = 'generic' . mb_substr(StringUtil::getRandomID(), 0, 8); } $originalTemplateGroupFolderName = $templateGroupFolderName; // get unique template group name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($templateGroupName)); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupName = $originalTemplateGroupName . '_' . $i; $i++; } // get unique folder name $i = 1; while (true) { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupFolderName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(FileUtil::addTrailingSlash($templateGroupFolderName))); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupFolderName = $originalTemplateGroupFolderName . '_' . $i; $i++; } $templateGroupAction = new TemplateGroupAction(array(), 'create', array('data' => array('templateGroupName' => $templateGroupName, 'templateGroupFolderName' => FileUtil::addTrailingSlash($templateGroupFolderName)))); $returnValues = $templateGroupAction->executeAction(); $styleData['templateGroupID'] = $returnValues['returnValues']->templateGroupID; } // import images if (!empty($data['images']) && $data['imagesPath'] != 'images/') { // create images folder if necessary $imagesLocation = self::getFileLocation($data['imagesPath']); $styleData['imagePath'] = FileUtil::getRelativePath(WCF_DIR, $imagesLocation); $index = $tar->getIndexByFilename($data['images']); if ($index !== false) { // extract images tar $destination = FileUtil::getTemporaryFilename('images_'); $tar->extract($index, $destination); // open images tar $imagesTar = new Tar($destination); $contentList = $imagesTar->getContentList(); foreach ($contentList as $key => $val) { if ($val['type'] == 'file') { $imagesTar->extract($key, $imagesLocation . basename($val['filename'])); FileUtil::makeWritable($imagesLocation . basename($val['filename'])); } } // delete tmp file $imagesTar->close(); @unlink($destination); } } // import templates if (!empty($data['templates'])) { $index = $tar->getIndexByFilename($data['templates']); if ($index !== false) { // extract templates tar $destination = FileUtil::getTemporaryFilename('templates_'); $tar->extract($index, $destination); // open templates tar and group templates by package $templatesTar = new Tar($destination); $contentList = $templatesTar->getContentList(); $packageToTemplates = array(); foreach ($contentList as $val) { if ($val['type'] == 'file') { $folders = explode('/', $val['filename']); $packageName = array_shift($folders); if (!isset($packageToTemplates[$packageName])) { $packageToTemplates[$packageName] = array(); } $packageToTemplates[$packageName][] = array('index' => $val['index'], 'filename' => implode('/', $folders)); } } // copy templates foreach ($packageToTemplates as $package => $templates) { // try to find package $sql = "SELECT\t*\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?\n\t\t\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package, 1)); while ($row = $statement->fetchArray()) { // get template path $templatesDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'templates/' . $templateGroupFolderName); // create template path if (!file_exists($templatesDir)) { @mkdir($templatesDir, 0777); FileUtil::makeWritable($templatesDir); } // copy templates foreach ($templates as $template) { $templatesTar->extract($template['index'], $templatesDir . $template['filename']); TemplateEditor::create(array('application' => Package::getAbbreviation($package), 'packageID' => $row['packageID'], 'templateName' => str_replace('.tpl', '', $template['filename']), 'templateGroupID' => $styleData['templateGroupID'])); } } } // delete tmp file $templatesTar->close(); @unlink($destination); } } // save style if ($style !== null) { $style->update($styleData); } else { $styleData['packageID'] = $packageID; $style = new StyleEditor(self::create($styleData)); } // import preview image if (!empty($data['image'])) { $fileExtension = mb_substr($data['image'], mb_strrpos($data['image'], '.')); $index = $tar->getIndexByFilename($data['image']); if ($index !== false) { $filename = WCF_DIR . 'images/stylePreview-' . $style->styleID . $fileExtension; $tar->extract($index, $filename); FileUtil::makeWritable($filename); if (file_exists($filename)) { $style->update(array('image' => 'stylePreview-' . $style->styleID . $fileExtension)); } } } $tar->close(); // handle descriptions if (!empty($data['description'])) { self::saveLocalizedDescriptions($style, $data['description']); LanguageFactory::getInstance()->deleteLanguageCache(); } if ($data['default']) { $style->setAsDefault(); } return $style; }
/** * Searches in templates. * * @param string $search search query * @param string $replace * @param array $templateIDs * @param boolean $invertTemplates * @param boolean $useRegex * @param boolean $caseSensitive * @param boolean $invertSearch * @return array results */ public static function search($search, $replace = null, $templateIDs = null, $invertTemplates = 0, $useRegex = 0, $caseSensitive = 0, $invertSearch = 0) { // get available template ids $results = array(); $availableTemplateIDs = array(); $sql = "SELECT templateName, templateID, templateGroupID, packageID FROM wcf".WCF_N."_template ".($replace !== null ? "WHERE templateGroupID <> 0" : ""); $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); while ($row = $statement->fetchArray()) { if (!isset($availableTemplateIDs[$row['templateName'].'-'.$row['templateGroupID']]) || PACKAGE_ID == $row['packageID']) { $availableTemplateIDs[$row['templateName'].'-'.$row['templateGroupID']] = $row['templateID']; } } // get templates if (empty($availableTemplateIDs)) return $results; $conditions = new PreparedStatementConditionBuilder(); $conditions->add("template.templateID IN (?)", array($availableTemplateIDs)); if ($templateIDs !== null) $conditions->add("template.templateID ".($invertTemplates ? "NOT " : "")." IN (?)", array($templateIDs)); $sql = "SELECT template.*, group.templateGroupFolderName, package.packageDir FROM wcf".WCF_N."_template template LEFT JOIN wcf".WCF_N."_template_group group ON (group.templateGroupID = template.templateGroupID) LEFT JOIN wcf".WCF_N."_package package ON (package.packageID = template.packageID) ".$conditions." ORDER BY templateName ASC"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); unset($availableTemplateIDs); while ($row = $statement->fetchArray()) { $template = new TemplateEditor(null, $row); if ($replace === null) { // search if ($useRegex) $matches = (intval(preg_match('/'.$search.'/s'.(!$caseSensitive ? 'i' : ''), $template->getSource())) !== 0); else { if ($caseSensitive) $matches = (StringUtil::indexOf($template->getSource(), $search) !== false); else $matches = (StringUtil::indexOfIgnoreCase($template->getSource(), $search) !== false); } if (($matches && !$invertSearch) || (!$matches && $invertSearch)) { $results[] = $row; } } else { // search and replace $matches = 0; if ($useRegex) { $newSource = preg_replace('/'.$search.'/s'.(!$caseSensitive ? 'i' : ''), $replace, $template->getSource(), -1, $matches); } else { if ($caseSensitive) $newSource = StringUtil::replace($search, $replace, $template->getSource(), $matches); else $newSource = StringUtil::replaceIgnoreCase($search, $replace, $template->getSource(), $matches); } if ($matches > 0) { $template->setSource($newSource); $row['matches'] = $matches; $results[] = $row; } } } return $results; }
/** * Searches in templates. * * @param string $search search query * @param string $replace * @param array $templateIDs * @param boolean $invertTemplates * @param boolean $useRegex * @param boolean $caseSensitive * @param boolean $invertSearch * @return array results */ public static function search($search, $replace = null, $templateIDs = null, $invertTemplates = 0, $useRegex = 0, $caseSensitive = 0, $invertSearch = 0) { // get available template ids $results = array(); $availableTemplateIDs = array(); $sql = "SELECT\t\ttemplate.templateName, template.templateID, template.templateGroupID, template.packageID\n\t\t\tFROM\t\twcf" . WCF_N . "_template template\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_dependency package_dependency\n\t\t\tON\t\t(package_dependency.dependency = template.packageID)\n\t\t\tWHERE \t\tpackage_dependency.packageID = ?\n\t\t\t\t\t" . ($replace !== null ? "AND template.templateGroupID <> 0" : "") . "\n\t\t\tORDER BY\tpackage_dependency.priority ASC"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(PACKAGE_ID)); while ($row = $statement->fetchArray()) { if (!isset($availableTemplateIDs[$row['templateName'] . '-' . $row['templateGroupID']]) || PACKAGE_ID == $row['packageID']) { $availableTemplateIDs[$row['templateName'] . '-' . $row['templateGroupID']] = $row['templateID']; } } // get templates if (!count($availableTemplateIDs)) { return $results; } $conditions = new PreparedStatementConditionBuilder(); $conditions->add("template.templateID IN (?)", array($availableTemplateIDs)); if ($templateIDs !== null) { $conditions->add("template.templateID " . ($invertTemplates ? "NOT " : "") . " IN (?)", array($templateIDs)); } $sql = "SELECT\t\ttemplate.*, group.templateGroupFolderName, package.packageDir\n\t\t\tFROM\t\twcf" . WCF_N . "_template template\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_template_group group\n\t\t\tON\t\t(group.templateGroupID = template.templateGroupID)\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\tON\t\t(package.packageID = template.packageID)\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\ttemplateName ASC"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); unset($availableTemplateIDs); while ($row = $statement->fetchArray()) { $template = new TemplateEditor(null, $row); if ($replace === null) { // search if ($useRegex) { $matches = intval(preg_match('/' . $search . '/s' . (!$caseSensitive ? 'i' : ''), $template->getSource())) !== 0; } else { if ($caseSensitive) { $matches = StringUtil::indexOf($template->getSource(), $search) !== false; } else { $matches = StringUtil::indexOfIgnoreCase($template->getSource(), $search) !== false; } } if ($matches && !$invertSearch || !$matches && $invertSearch) { $results[] = $row; } } else { // search and replace $matches = 0; if ($useRegex) { $newSource = preg_replace('/' . $search . '/s' . (!$caseSensitive ? 'i' : ''), $replace, $template->getSource(), -1, $matches); } else { if ($caseSensitive) { $newSource = StringUtil::replace($search, $replace, $template->getSource(), $matches); } else { $newSource = StringUtil::replaceIgnoreCase($search, $replace, $template->getSource(), $matches); } } if ($matches > 0) { $template->setSource($newSource); $row['matches'] = $matches; $results[] = $row; } } } return $results; }
/** * @see \wcf\data\IEditableObject::deleteAll() */ public static function deleteAll(array $objectIDs = array()) { $list = new TemplateList(); $list->setObjectIDs($objectIDs); $list->readObjects(); foreach ($list as $template) { $editor = new TemplateEditor($template); $editor->deleteFile(); } return parent::deleteAll($objectIDs); }
/** * Imports a style. * * @param string $filename * @param integer $packageID * @param StyleEditor $style * @return StyleEditor */ public static function import($filename, $packageID = PACKAGE_ID, StyleEditor $style = null) { // open file $tar = new Tar($filename); // get style data $data = self::readStyleData($tar); // get image locations $iconsLocation = FileUtil::addTrailingSlash($data['variables']['global.icons.location']); $imagesLocation = $data['variables']['global.images.location']; // create template group $templateGroupID = 0; if (!empty($data['templates'])) { $templateGroupName = $data['name']; $templateGroupFolderName = preg_replace('/[^a-z0-9_-]/i', '', $templateGroupName); if (empty($templateGroupFolderName)) { $templateGroupFolderName = 'generic' . StringUtil::substring(StringUtil::getRandomID(), 0, 8); } $originalTemplatePackFolderName = $templateGroupFolderName; // get unique template pack name $i = 1; do { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupName = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($templateGroupName)); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupName = $originalTemplatePackName . '_' . $i; //TODO: undefined variable $i++; } while (true); // get unique folder name $i = 1; do { $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\t\tFROM\twcf" . WCF_N . "_template_group\n\t\t\t\t\tWHERE\ttemplateGroupFolderName = ?\n\t\t\t\t\t\tAND parentTemplatePackID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(FileUtil::addTrailingSlash($templateGroupFolderName), 0)); $row = $statement->fetchArray(); if (!$row['count']) { break; } $templateGroupFolderName = $originalTemplatePackFolderName . '_' . $i; $i++; } while (true); $templateGroup = TemplateGroupEditor::create(array('templateGroupName' => $templateGroupName, 'templateGroupFolderName' => FileUtil::addTrailingSlash($templateGroupFolderName))); $templateGroupID = $templateGroup->templateGroupID; } // save style $styleData = array('styleName' => $data['name'], 'variables' => $data['variables'], 'templateGroupID' => $templateGroupID, 'styleDescription' => $data['description'], 'styleVersion' => $data['version'], 'styleDate' => $data['date'], 'image' => ($data['image'] ? 'images/' : '') . $data['image'], 'copyright' => $data['copyright'], 'license' => $data['license'], 'authorName' => $data['authorName'], 'authorURL' => $data['authorURL']); if ($style !== null) { $style->update($styleData); } else { $styleData['packageID'] = $packageID; $style = self::create($styleData); } // import preview image if (!empty($data['image'])) { $i = $tar->getIndexByFilename($data['image']); if ($i !== false) { $tar->extract($i, WCF_DIR . 'images/' . $data['image']); @chmod(WCF_DIR . 'images/' . $data['image'], 0777); } } // import images if (!empty($data['images'])) { // create images folder if necessary if (!file_exists(WCF_DIR . $imagesLocation)) { @mkdir(WCF_DIR . $data['variables']['global.images.location'], 0777); @chmod(WCF_DIR . $data['variables']['global.images.location'], 0777); } $i = $tar->getIndexByFilename($data['images']); if ($i !== false) { // extract images tar $destination = FileUtil::getTemporaryFilename('images_'); $tar->extract($i, $destination); // open images tar $imagesTar = new Tar($destination); $contentList = $imagesTar->getContentList(); foreach ($contentList as $key => $val) { if ($val['type'] == 'file') { $imagesTar->extract($key, WCF_DIR . $imagesLocation . basename($val['filename'])); @chmod(WCF_DIR . $imagesLocation . basename($val['filename']), 0666); } } // delete tmp file $imagesTar->close(); @unlink($destination); } } // import icons if (!empty($data['icons']) && $iconsLocation != 'icon/') { $i = $tar->getIndexByFilename($data['icons']); if ($i !== false) { // extract icons tar $destination = FileUtil::getTemporaryFilename('icons_'); $tar->extract($i, $destination); // open icons tar and group icons by package $iconsTar = new Tar($destination); $contentList = $iconsTar->getContentList(); $packageToIcons = array(); foreach ($contentList as $val) { if ($val['type'] == 'file') { $folders = explode('/', $val['filename']); $packageName = array_shift($folders); if (!isset($packageToIcons[$packageName])) { $packageToIcons[$packageName] = array(); } $packageToIcons[$packageName][] = array('index' => $val['index'], 'filename' => implode('/', $folders)); } } // copy icons foreach ($packageToIcons as $package => $icons) { // try to find package $sql = "SELECT\t*\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?\n\t\t\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package, 1)); while ($row = $statement->fetchArray()) { // get icon path $iconDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . $iconsLocation; // create icon path if (!file_exists($iconDir)) { @mkdir($iconDir, 0777); @chmod($iconDir, 0777); } // copy icons foreach ($icons as $icon) { $iconsTar->extract($icon['index'], $iconDir . $icon['filename']); } } } // delete tmp file $iconsTar->close(); @unlink($destination); } } // import templates if (!empty($data['templates'])) { $i = $tar->getIndexByFilename($data['templates']); if ($i !== false) { // extract templates tar $destination = FileUtil::getTemporaryFilename('templates_'); $tar->extract($i, $destination); // open templates tar and group templates by package $templatesTar = new Tar($destination); $contentList = $templatesTar->getContentList(); $packageToTemplates = array(); foreach ($contentList as $val) { if ($val['type'] == 'file') { $folders = explode('/', $val['filename']); $packageName = array_shift($folders); if (!isset($packageToTemplates[$packageName])) { $packageToTemplates[$packageName] = array(); } $packageToTemplates[$packageName][] = array('index' => $val['index'], 'filename' => implode('/', $folders)); } } // copy templates foreach ($packageToTemplates as $package => $templates) { // try to find package $sql = "SELECT\t*\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?\n\t\t\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package, 1)); while ($row = $statement->fetchArray()) { // get icon path $templatesDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'templates/' . $templateGroupFolderName); // create template path if (!file_exists($templatesDir)) { @mkdir($templatesDir, 0777); @chmod($templatesDir, 0777); } // copy templates foreach ($templates as $template) { $templatesTar->extract($template['index'], $templatesDir . $template['filename']); TemplateEditor::create(array('packageID' => $row['packageID'], 'templateName' => StringUtil::replace('.tpl', '', $template['filename']), 'templateGroupID' => $templateGroupID)); } } } // delete tmp file $templatesTar->close(); @unlink($destination); } } $tar->close(); return $style; }