コード例 #1
0
 /**
  * Parses search keywords.
  * 
  * @param	string		$keywordString
  */
 protected static function parseKeywords($keywordString)
 {
     // convert encoding if necessary
     if (CHARSET == 'UTF-8' && !StringUtil::isASCII($keywordString) && !StringUtil::isUTF8($keywordString)) {
         $keywordString = StringUtil::convertEncoding('ISO-8859-1', 'UTF-8', $keywordString);
     }
     // remove bad wildcards
     $keywordString = preg_replace('/(?<!\\w)\\*/', '', $keywordString);
     // remove search operators
     $keywordString = preg_replace('/[\\+\\-><()~]+/', '', $keywordString);
     if (StringUtil::substring($keywordString, 0, 1) == '"' && StringUtil::substring($keywordString, -1) == '"') {
         // phrases search
         $keywordString = StringUtil::trim(StringUtil::substring($keywordString, 1, -1));
         if (!empty($keywordString)) {
             self::$keywords = array_merge(self::$keywords, array(StringUtil::encodeHTML($keywordString)));
         }
     } else {
         // replace word delimiters by space
         $keywordString = preg_replace('/[.,]/', ' ', $keywordString);
         $keywords = ArrayUtil::encodeHTML(ArrayUtil::trim(explode(' ', $keywordString)));
         if (count($keywords) > 0) {
             self::$keywords = array_merge(self::$keywords, $keywords);
         }
     }
 }
コード例 #2
0
 /**
  * Returns an abstract of the file content.
  * 
  * @param	array		$data
  * @return	string
  */
 protected static function getContentPreview($data)
 {
     if (!ATTACHMENT_ENABLE_CONTENT_PREVIEW || $data['isBinary'] || $data['attachmentSize'] == 0) {
         return '';
     }
     $content = '';
     try {
         $file = new File(WCF_DIR . 'attachments/attachment-' . $data['attachmentID'], 'rb');
         $content = $file->read(2003);
         $file->close();
         if (CHARSET == 'UTF-8') {
             if (!StringUtil::isASCII($content) && !StringUtil::isUTF8($content)) {
                 $content = StringUtil::convertEncoding('ISO-8859-1', CHARSET, $content);
             }
             $content = StringUtil::substring($content, 0, 500);
             if (strlen($content) < $file->filesize()) {
                 $content .= '...';
             }
         } else {
             if (StringUtil::isUTF8($content)) {
                 return '';
             }
             $content = StringUtil::substring($content, 0, 500);
             if ($file->filesize() > 500) {
                 $content .= '...';
             }
         }
     } catch (Exception $e) {
     }
     // ignore errors
     return $content;
 }
コード例 #3
0
 /**
  * Returns an abstract of the file content.
  * 
  * @return	string
  */
 public function getContentPreview()
 {
     if ($this->contentPreview === null) {
         $this->contentPreview = '';
         if (ATTACHMENT_ENABLE_CONTENT_PREVIEW && !$this->isBinary && $this->attachmentSize != 0) {
             try {
                 $file = new File(WCF_DIR . 'attachments/attachment-' . $this->attachmentID, 'rb');
                 $this->contentPreview = $file->read(2003);
                 $file->close();
                 if (CHARSET == 'UTF-8') {
                     if (!StringUtil::isASCII($this->contentPreview) && !StringUtil::isUTF8($this->contentPreview)) {
                         $this->contentPreview = StringUtil::convertEncoding('ISO-8859-1', CHARSET, $this->contentPreview);
                     }
                     $this->contentPreview = StringUtil::substring($this->contentPreview, 0, 500);
                     if (strlen($this->contentPreview) < $file->filesize()) {
                         $this->contentPreview .= '...';
                     }
                 } else {
                     if (StringUtil::isUTF8($this->contentPreview)) {
                         $this->contentPreview = '';
                     } else {
                         $this->contentPreview = StringUtil::substring($this->contentPreview, 0, 500);
                         if ($file->filesize() > 500) {
                             $this->contentPreview .= '...';
                         }
                     }
                 }
             } catch (Exception $e) {
             }
             // ignore errors
         }
     }
     return $this->contentPreview;
 }
コード例 #4
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_POST['query'])) {
         $this->query = StringUtil::trim($_POST['query']);
         if (CHARSET != 'UTF-8') {
             $this->query = StringUtil::convertEncoding('UTF-8', CHARSET, $this->query);
         }
     }
 }
コード例 #5
0
 /**
  * @see Action::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_POST['title'])) {
         $this->title = $_POST['title'];
         if (CHARSET != 'UTF-8') {
             $this->title = StringUtil::convertEncoding('UTF-8', CHARSET, $this->title);
         }
     }
 }
コード例 #6
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['query'])) {
         $queryString = $_REQUEST['query'];
         if (CHARSET != 'UTF-8') {
             $queryString = StringUtil::convertEncoding('UTF-8', CHARSET, $queryString);
         }
         $this->query = ArrayUtil::trim(explode(',', $queryString));
     }
 }
コード例 #7
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_POST['query'])) {
         $this->query = StringUtil::trim($_POST['query']);
         if (CHARSET != 'UTF-8') {
             $this->query = StringUtil::convertEncoding('UTF-8', CHARSET, $this->query);
         }
     }
     if (count(Language::getAvailableContentLanguages(PACKAGE_ID)) > 0) {
         $this->languageID = WCF::getLanguage()->getLanguageID();
     }
 }
コード例 #8
0
 /**
  * @see Action::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['packageID'])) {
         $this->packageID = intval($_REQUEST['packageID']);
     }
     if (isset($_POST['name'])) {
         $this->name = $_POST['name'];
         if (CHARSET != 'UTF-8') {
             $this->name = StringUtil::convertEncoding('UTF-8', CHARSET, $this->name);
         }
     }
 }
コード例 #9
0
 /**
  * @see Action::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['contestRatingoptionID'])) {
         $this->contestRatingoptionID = intval($_REQUEST['contestRatingoptionID']);
     }
     if (isset($_POST['title'])) {
         $this->title = $_POST['title'];
         if (CHARSET != 'UTF-8') {
             $this->title = StringUtil::convertEncoding('UTF-8', CHARSET, $this->title);
         }
     }
 }
コード例 #10
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['query']) && isset($_REQUEST['text'])) {
         $querySubject = $_REQUEST['query'];
         $queryText = $_REQUEST['text'];
         if (CHARSET != 'UTF-8') {
             $querySubject = StringUtil::convertEncoding('UTF-8', CHARSET, $querySubject);
             $queryText = StringUtil::convertEncoding('UTF-8', CHARSET, $queryText);
         }
         $this->subject = $querySubject;
         $this->message = $queryText;
     }
 }
コード例 #11
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['postID'])) {
         $this->postID = ArrayUtil::toIntegerArray($_REQUEST['postID']);
     }
     if (isset($_REQUEST['threadID'])) {
         $this->threadID = intval($_REQUEST['threadID']);
     }
     if (isset($_REQUEST['reason'])) {
         $this->reason = StringUtil::trim($_REQUEST['reason']);
         if (CHARSET != 'UTF-8') {
             $this->reason = StringUtil::convertEncoding('UTF-8', CHARSET, $this->reason);
         }
     }
     if (isset($_REQUEST['boardID'])) {
         $this->boardID = intval($_REQUEST['boardID']);
     }
     if (isset($_REQUEST['topic'])) {
         $this->topic = StringUtil::trim($_REQUEST['topic']);
         if (CHARSET != 'UTF-8') {
             $this->topic = StringUtil::convertEncoding('UTF-8', CHARSET, $this->topic);
         }
     }
     if (isset($_REQUEST['url'])) {
         $this->url = $_REQUEST['url'];
     }
     // check permissions
     if (!is_array($this->postID) && $this->postID != 0) {
         require_once WBB_DIR . 'lib/data/post/PostEditor.class.php';
         $this->post = new PostEditor($this->postID);
         if (!$this->post->postID) {
             throw new IllegalLinkException();
         }
         $this->threadID = $this->post->threadID;
     }
     if ($this->threadID != 0) {
         require_once WBB_DIR . 'lib/data/thread/ThreadEditor.class.php';
         $this->thread = new ThreadEditor($this->threadID);
         $this->boardID = $this->thread->boardID;
         $this->thread->enter();
     }
     if ($this->boardID != 0) {
         require_once WBB_DIR . 'lib/data/board/BoardEditor.class.php';
         $this->board = new BoardEditor($this->boardID);
         if ($this->thread != null) {
             $this->thread->enter();
         }
     }
 }
コード例 #12
0
 /**
  * @see Page::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     if (isset($_REQUEST['boardID'])) {
         $this->boardID = intval($_REQUEST['boardID']);
     }
     if (isset($_REQUEST['threadID'])) {
         $this->threadID = ArrayUtil::toIntegerArray($_REQUEST['threadID']);
     }
     if (isset($_REQUEST['reason'])) {
         $this->reason = StringUtil::trim($_REQUEST['reason']);
         if (CHARSET != 'UTF-8') {
             $this->reason = StringUtil::convertEncoding('UTF-8', CHARSET, $this->reason);
         }
     }
     if (isset($_REQUEST['topic'])) {
         $this->topic = StringUtil::trim($_REQUEST['topic']);
         if (CHARSET != 'UTF-8') {
             $this->topic = StringUtil::convertEncoding('UTF-8', CHARSET, $this->topic);
         }
     }
     if (isset($_REQUEST['prefix'])) {
         $this->prefix = $_REQUEST['prefix'];
         if (CHARSET != 'UTF-8') {
             $this->prefix = StringUtil::convertEncoding('UTF-8', CHARSET, $this->prefix);
         }
     }
     if (isset($_REQUEST['url'])) {
         $this->url = $_REQUEST['url'];
     }
     if (!is_array($this->threadID) && $this->threadID != 0) {
         $this->thread = new ThreadEditor($this->threadID);
         $this->boardID = $this->thread->boardID;
         if ($this->thread->movedThreadID) {
             $movedThread = new ThreadEditor($this->thread->movedThreadID);
             $movedThread->enter();
         } else {
             $this->thread->enter();
         }
     }
     if ($this->boardID != 0) {
         $this->board = new BoardEditor($this->boardID);
         if ($this->thread == null) {
             $this->board->enter();
         }
     }
 }
コード例 #13
0
 /**
  * @see Action::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     try {
         // get post
         if (isset($_REQUEST['postID'])) {
             $this->postID = intval($_REQUEST['postID']);
         }
         $this->post = new PostEditor($this->postID);
         if (!$this->post->postID) {
             throw new IllegalLinkException();
         }
         // get thread
         $this->thread = new ThreadEditor($this->post->threadID);
         $this->board = new BoardEditor($this->thread->boardID);
         $this->thread->enter($this->board);
         // check permissions
         $isModerator = $this->board->getModeratorPermission('canEditPost') || $this->board->getModeratorPermission('canDeletePost');
         $isAuthor = $this->post->userID && $this->post->userID == WCF::getUser()->userID;
         $canEditPost = $this->board->getModeratorPermission('canEditPost') || $isAuthor && $this->board->getPermission('canEditOwnPost');
         if (!$canEditPost || !$isModerator && ($this->board->isClosed || $this->thread->isClosed || $this->post->isClosed)) {
             throw new PermissionDeniedException();
         }
         // check post edit timeout
         if (!$isModerator && WCF::getUser()->getPermission('user.board.postEditTimeout') != -1 && TIME_NOW - $this->post->time > WCF::getUser()->getPermission('user.board.postEditTimeout') * 60) {
             throw new NamedUserException(WCF::getLanguage()->get('wbb.postEdit.error.timeout', array('$timeout' => WCF::getUser()->getPermission('user.board.postEditTimeout'))));
         }
         // get message
         if (isset($_POST['text'])) {
             $this->text = StringUtil::trim($_POST['text']);
             if (CHARSET != 'UTF-8') {
                 $this->text = StringUtil::convertEncoding('UTF-8', CHARSET, $this->text);
             }
             if (empty($this->text)) {
                 throw new IllegalLinkException();
             }
         }
     } catch (UserException $e) {
         @header('HTTP/1.0 403 Forbidden');
         echo $e->getMessage();
         exit;
     }
 }
コード例 #14
0
 /**
  * Loads the compiled language file.
  * Compiles the language file before if necessary.
  */
 public function loadLanguage()
 {
     $this->languageLoaded = true;
     $filename = TMP_DIR . TMP_FILE_PREFIX . $this->data['languageCode'] . '_' . $this->data['languageEncoding'] . '_wcf.setup.php';
     if (!file_exists($filename)) {
         $xml = new XML(TMP_DIR . TMP_FILE_PREFIX . 'setup_' . $this->data['languageCode'] . '.xml');
         // compile an array with XML::getElementTree
         $languageXML = $xml->getElementTree('language');
         // extract attributes (language code, language name)
         //$languageXML = array_merge($languageXML, $languageXML['attrs']);
         // get language items
         $categoriesToCache = array();
         foreach ($languageXML['children'] as $key => $languageCategory) {
             // language category does not exist yet, create it
             if (isset($languageCategory['children'])) {
                 foreach ($languageCategory['children'] as $key2 => $languageitem) {
                     $categoriesToCache[] = array('name' => $languageitem['attrs']['name'], 'cdata' => $languageitem['cdata']);
                 }
             }
         }
         // update language files here
         if (count($categoriesToCache) > 0) {
             $file = new File($filename);
             $file->write("<?php\n/**\n* WoltLab Community Framework\n* language: " . $this->data['languageCode'] . "\n* encoding: " . $this->data['languageEncoding'] . "\n* category: WCF Setup\n* generated at " . gmdate("r") . "\n* \n* DO NOT EDIT THIS FILE\n*/\n");
             foreach ($categoriesToCache as $value => $name) {
                 // simple_xml returns values always UTF-8 encoded
                 // manual decoding to charset necessary
                 if ($this->data['languageEncoding'] != 'UTF-8') {
                     $name['cdata'] = StringUtil::convertEncoding('UTF-8', $this->data['languageEncoding'], $name['cdata']);
                 }
                 $file->write("\$this->items[\$this->languageID]['" . $name['name'] . "'] = '" . str_replace("'", "\\'", $name['cdata']) . "';\n");
                 // compile dynamic language variables
                 if (strpos($name['cdata'], '{') !== false) {
                     $file->write("\$this->dynamicItems[\$this->languageID]['" . $name['name'] . "'] = '" . str_replace("'", "\\'", self::getScriptingCompiler()->compileString($name['name'], $name['cdata'])) . "';\n");
                 }
             }
             $file->write("?>");
             $file->close();
         }
     }
     include_once $filename;
     $this->setLocale();
 }
コード例 #15
0
 /**
  * Creates a new PackageUpdateAuthForm object.
  * 
  * @param	PackageUpdateAuthorizationRequiredException	$exception
  */
 public function __construct($exception = null)
 {
     $this->exception = $exception;
     if ($this->exception !== null) {
         $this->packageUpdateServerID = $this->exception->getPackageUpdateServerID();
         $this->url = $this->exception->getURL();
         $this->header = $this->exception->getResponseHeader();
         // get message
         $this->message = $this->exception->getResponseContent();
         // find out response charset
         if (preg_match('/charset=([a-z0-9\\-]+)/i', $this->header, $match)) {
             $charset = strtoupper($match[1]);
             if ($charset != CHARSET) {
                 $this->message = @StringUtil::convertEncoding($charset, CHARSET, $this->message);
             }
         }
         // format message
         $this->message = nl2br(preg_replace("/\n{3,}/", "\n\n", StringUtil::unifyNewlines(StringUtil::trim(strip_tags($this->message)))));
     }
     parent::__construct();
 }
コード例 #16
0
 /**
  * @see Action::readParameters()
  */
 public function readParameters()
 {
     parent::readParameters();
     // get object id
     if (isset($_REQUEST['objectID'])) {
         $this->objectID = intval($_REQUEST['objectID']);
     }
     // get quote(s)
     if (isset($_REQUEST['text'])) {
         $this->text = $_REQUEST['text'];
     }
     if (is_array($this->text)) {
         $this->text = ArrayUtil::unifyNewlines(ArrayUtil::trim($this->text));
         if (CHARSET != 'UTF-8') {
             $this->text = ArrayUtil::convertEncoding('UTF-8', CHARSET, $this->text);
         }
     } else {
         $this->text = StringUtil::unifyNewlines(StringUtil::trim($this->text));
         if (CHARSET != 'UTF-8') {
             $this->text = StringUtil::convertEncoding('UTF-8', CHARSET, $this->text);
         }
     }
 }
 /**
  * Installs admin tools functions, categories and options.
  */
 public function install()
 {
     AbstractXMLPackageInstallationPlugin::install();
     try {
         $sql = "SELECT\t\tfunction.functionID, function.functionName,  package.packageDir\n\t\t\tFROM\t\twcf" . WCF_N . "_package_dependency package_dependency,\n\t\t\t\t\t\twcf" . WCF_N . "_admin_tools_function function\t\t\t\t\t\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\tON\t\t\t(package.packageID = function.packageID)\n\t\t\tWHERE \t\tfunction.packageID = package_dependency.dependency\n\t\t\t\t\tAND package_dependency.packageID = " . $this->installation->getPackageID() . "\n\t\t\tORDER BY\tpackage_dependency.priority";
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             $this->functions[$row['functionName']] = $row['functionID'];
         }
     } catch (DatabaseException $e) {
         // do nothing. this should only crash if this is the installation of the admin tools itself.
     }
     if (!($xml = $this->getXML())) {
         return;
     }
     // create an array with the import and delete instructions from the xml file
     $optionsXML = $xml->getElementTree('data');
     // install or uninstall categories and options.
     foreach ($optionsXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // handle the import instructions
             if ($block['name'] == 'import') {
                 // loop through categories and options
                 foreach ($block['children'] as $child) {
                     // handle functions
                     if ($child['name'] == 'functions') {
                         // loop thorugh all functions
                         foreach ($child['children'] as $function) {
                             // check required category name
                             if (!isset($function['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for option function is missing", 13023);
                             }
                             // default values
                             $functionName = $classPath = "";
                             $executeAsCronjob = $saveSettings = 0;
                             // make xml tags-names (keys in array) to lower case
                             $this->keysToLowerCase($function);
                             // get function data from children
                             foreach ($function['children'] as $data) {
                                 if (!isset($data['cdata'])) {
                                     continue;
                                 }
                                 $function[$data['name']] = $data['cdata'];
                             }
                             // get and secure values
                             $functionName = escapeString($function['attrs']['name']);
                             if (isset($function['classpath'])) {
                                 $classPath = escapeString($function['classpath']);
                             }
                             if (isset($function['savesettings'])) {
                                 $saveSettings = intval($function['savesettings']);
                             }
                             if (isset($function['executeascronjob'])) {
                                 $executeAsCronjob = intval($function['executeascronjob']);
                             }
                             $functionData = array('functionName' => $functionName, 'classPath' => $classPath, 'saveSettings' => $saveSettings, 'executeAsCronjob' => $executeAsCronjob);
                             // save function
                             $this->saveFunction($functionData, $function);
                         }
                     } else {
                         if ($child['name'] == 'categories') {
                             // loop through all categories
                             foreach ($child['children'] as $category) {
                                 // check required category name
                                 if (!isset($category['attrs']['name'])) {
                                     throw new SystemException("Required 'name' attribute for option category is missing", 13023);
                                 }
                                 // default values
                                 $categoryName = $parentCategoryName = $permissions = $options = $function = '';
                                 $showOrder = null;
                                 $functionID = 0;
                                 // make xml tags-names (keys in array) to lower case
                                 $this->keysToLowerCase($category);
                                 // get category data from children (parent, showorder, icon and menuicon)
                                 foreach ($category['children'] as $data) {
                                     if (!isset($data['cdata'])) {
                                         continue;
                                     }
                                     $category[$data['name']] = $data['cdata'];
                                 }
                                 // get and secure values
                                 $categoryName = escapeString($category['attrs']['name']);
                                 if (isset($category['permissions'])) {
                                     $permissions = $category['permissions'];
                                 }
                                 if (isset($category['options'])) {
                                     $options = $category['options'];
                                 }
                                 if (isset($category['parent'])) {
                                     $parentCategoryName = escapeString($category['parent']);
                                 }
                                 if (!empty($category['showorder'])) {
                                     $showOrder = intval($category['showorder']);
                                 }
                                 if (!empty($category['function'])) {
                                     $function = $category['function'];
                                     if (!isset($this->functions[$function])) {
                                         throw new SystemException("Unable to find function with " . (empty($function) ? "empty " : "") . "name '" . $function . "' for category with name '" . $categoryName . "'.", 13011);
                                     }
                                     $functionID = $this->functions[$function];
                                 }
                                 if ($showOrder !== null || $this->installation->getAction() != 'update') {
                                     $showOrder = $this->getShowOrder($showOrder, $parentCategoryName, 'parentCategoryName', '_category');
                                 }
                                 // if a parent category was set and this parent is not in database
                                 // or it is a category from a package from other package environment: don't install further.
                                 if ($parentCategoryName != '') {
                                     $sql = "SELECT\tCOUNT(categoryID) AS count\n\t\t\t\t\t\t\t\t\t\t\tFROM\twcf" . WCF_N . "_" . $this->tableName . "_category\n\t\t\t\t\t\t\t\t\t\t\tWHERE\tcategoryName = '" . escapeString($parentCategoryName) . "'";
                                     /*	AND packageID IN (
                                     		 SELECT	dependency
                                     		 FROM	wcf".WCF_N."_package_dependency
                                     		 WHERE	packageID = ".$this->installation->getPackageID()."
                                     		 )";*/
                                     $parentCategoryCount = WCF::getDB()->getFirstRow($sql);
                                     // unable to find parent category in dependency-packages: abort installation
                                     if ($parentCategoryCount['count'] == 0) {
                                         throw new SystemException("Unable to find parent 'option category' with name '" . $parentCategoryName . "' for category with name '" . $categoryName . "'.", 13011);
                                     }
                                 }
                                 // save category
                                 $categoryData = array('categoryName' => $categoryName, 'parentCategoryName' => $parentCategoryName, 'showOrder' => $showOrder, 'permissions' => $permissions, 'options' => $options, 'functionID' => $functionID);
                                 $this->saveCategory($categoryData, $category);
                             }
                         } elseif ($child['name'] == 'options') {
                             // <option>
                             foreach ($child['children'] as $option) {
                                 // extract <category> <optiontype> <optionvalue> <visible> etc
                                 foreach ($option['children'] as $_child) {
                                     $option[$_child['name']] = $_child['cdata'];
                                 }
                                 // convert character encoding
                                 if (CHARSET != 'UTF-8') {
                                     if (isset($option['defaultvalue'])) {
                                         $option['defaultvalue'] = StringUtil::convertEncoding('UTF-8', CHARSET, $option['defaultvalue']);
                                     }
                                     if (isset($option['selectoptions'])) {
                                         $option['selectoptions'] = StringUtil::convertEncoding('UTF-8', CHARSET, $option['selectoptions']);
                                     }
                                 }
                                 // check required category name
                                 if (!isset($option['categoryname'])) {
                                     throw new SystemException("Required category for option is missing", 13023);
                                 }
                                 $categoryName = escapeString($option['categoryname']);
                                 // store option name
                                 $option['name'] = $option['attrs']['name'];
                                 // children info already stored with name => cdata
                                 // shrink array
                                 unset($option['children']);
                                 if (!preg_match("/^[\\w-\\.]+\$/", $option['name'])) {
                                     $matches = array();
                                     preg_match_all("/(\\W)/", $option['name'], $matches);
                                     throw new SystemException("The user option '" . $option['name'] . "' has at least one non-alphanumeric character (underscore is permitted): (" . implode("), ( ", $matches[1]) . ").", 13024);
                                 }
                                 $this->saveOption($option, $categoryName);
                             }
                         }
                     }
                 }
             } else {
                 if ($block['name'] == 'delete' && $this->installation->getAction() == 'update') {
                     $functionNames = '';
                     $optionNames = '';
                     $categoryNames = '';
                     foreach ($block['children'] as $deleteTag) {
                         // check required attributes
                         if (!isset($deleteTag['attrs']['name'])) {
                             throw new SystemException("Required 'name' attribute for '" . $deleteTag['name'] . "'-tag is missing", 13023);
                         }
                         if ($deleteTag['name'] == 'function') {
                             // build functionnames string
                             if (!empty($functionNames)) {
                                 $functionNames .= ',';
                             }
                             $functionNames .= "'" . escapeString($deleteTag['attrs']['name']) . "'";
                         } elseif ($deleteTag['name'] == 'option') {
                             // build optionnames string
                             if (!empty($optionNames)) {
                                 $optionNames .= ',';
                             }
                             $optionNames .= "'" . escapeString($deleteTag['attrs']['name']) . "'";
                         } elseif ($deleteTag['name'] == 'optioncategory') {
                             // build categorynames string
                             if (!empty($categoryNames)) {
                                 $categoryNames .= ',';
                             }
                             $categoryNames .= "'" . escapeString($deleteTag['attrs']['name']) . "'";
                         }
                     }
                     // delete functions
                     if (!empty($functionNames)) {
                         $this->deleteFunctions($functionNames);
                     }
                     // delete options
                     if (!empty($optionNames)) {
                         $this->deleteOptions($optionNames);
                     }
                     // elete categories
                     if (!empty($categoryNames)) {
                         $this->deleteCategories($categoryNames);
                     }
                 }
             }
         }
     }
 }
コード例 #18
0
 /**
  * Appends information about the source image to the thumbnail.
  * 
  * @param	string		$thumbnail
  * @return	string
  */
 protected function appendSourceInfo($thumbnail)
 {
     if (!function_exists('imageCreateFromString') || !function_exists('imageCreateTrueColor')) {
         return $thumbnail;
     }
     $imageSrc = imageCreateFromString($thumbnail);
     // get image size
     $width = imageSX($imageSrc);
     $height = imageSY($imageSrc);
     // increase height
     $heightDst = $height + self::$sourceInfoLineHeight * 2;
     // create new image
     $imageDst = imageCreateTrueColor($width, $heightDst);
     imageAlphaBlending($imageDst, false);
     // set background color
     $background = imageColorAllocate($imageDst, 102, 102, 102);
     imageFill($imageDst, 0, 0, $background);
     // copy image
     imageCopy($imageDst, $imageSrc, 0, 0, 0, 0, $width, $height);
     imageSaveAlpha($imageDst, true);
     // get font size
     $font = 2;
     $fontWidth = imageFontWidth($font);
     $fontHeight = imageFontHeight($font);
     $fontColor = imageColorAllocate($imageDst, 255, 255, 255);
     // write source info
     $line1 = $this->sourceName;
     // imageString supports only ISO-8859-1 encoded strings
     if (CHARSET != 'ISO-8859-1') {
         $line1 = StringUtil::convertEncoding(CHARSET, 'ISO-8859-1', $line1);
     }
     // truncate text if necessary
     $maxChars = floor($width / $fontWidth);
     if (strlen($line1) > $maxChars) {
         $line1 = $this->truncateSourceName($line1, $maxChars);
     }
     $line2 = $this->sourceWidth . 'x' . $this->sourceHeight . ' ' . FileUtil::formatFilesize($this->sourceSize);
     // write line 1
     // calculate text position
     $textX = 0;
     $textY = 0;
     if ($fontHeight < self::$sourceInfoLineHeight) {
         $textY = intval(round((self::$sourceInfoLineHeight - $fontHeight) / 2));
     }
     if (strlen($line1) * $fontWidth < $width) {
         $textX = intval(round(($width - strlen($line1) * $fontWidth) / 2));
     }
     imageString($imageDst, $font, $textX, $height + $textY, $line1, $fontColor);
     // write line 2
     // calculate text position
     $textX = 0;
     $textY = 0;
     if ($fontHeight < self::$sourceInfoLineHeight) {
         $textY = self::$sourceInfoLineHeight + intval(round((self::$sourceInfoLineHeight - $fontHeight) / 2));
     }
     if (strlen($line2) * $fontWidth < $width) {
         $textX = intval(round(($width - strlen($line2) * $fontWidth) / 2));
     }
     imageString($imageDst, $font, $textX, $height + $textY, $line2, $fontColor);
     // output image
     ob_start();
     if ($this->imageType == 1 && function_exists('imageGIF')) {
         @imageGIF($imageDst);
         $this->mimeType = 'image/gif';
     } else {
         if (($this->imageType == 1 || $this->imageType == 3) && function_exists('imagePNG')) {
             @imagePNG($imageDst);
             $this->mimeType = 'image/png';
         } else {
             if (function_exists('imageJPEG')) {
                 @imageJPEG($imageDst, null, 90);
                 $this->mimeType = 'image/jpeg';
             } else {
                 return false;
             }
         }
     }
     @imageDestroy($imageDst);
     $thumbnail = ob_get_contents();
     ob_end_clean();
     return $thumbnail;
 }
コード例 #19
0
 /**
  * Exports this language.
  */
 public function export($packageIDArray = array(), $exportCustomValues = false)
 {
     // bom
     echo "";
     // header
     echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<language xmlns=\"http://www.woltlab.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.woltlab.com/XSD/language.xsd\" languagecode=\"" . $this->getLanguageCode() . "\">\n";
     // get items
     $items = array();
     if (count($packageIDArray)) {
         $sql = "SELECT\t\tlanguageItem, " . ($exportCustomValues ? "CASE WHEN languageUseCustomValue > 0 THEN languageCustomItemValue ELSE languageItemValue END AS languageItemValue" : "languageItemValue") . ", languageCategory\n\t\t\t\tFROM\t\twcf" . WCF_N . "_language_item language_item\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_language_category language_category\n\t\t\t\tON\t\t(language_category.languageCategoryID = language_item.languageCategoryID)\n\t\t\t\tWHERE \t\tlanguage_item.packageID IN (" . implode(',', $packageIDArray) . ")\n\t\t\t\t\t\tAND language_item.languageID = " . $this->languageID;
     } else {
         $sql = "SELECT\t\tlanguageItem, " . ($exportCustomValues ? "CASE WHEN languageUseCustomValue > 0 THEN languageCustomItemValue ELSE languageItemValue END AS languageItemValue" : "languageItemValue") . ", languageCategory\n\t\t\t\tFROM\t\twcf" . WCF_N . "_package_dependency package_dependency,\n\t\t\t\t\t\twcf" . WCF_N . "_language_item language_item\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_language_category language_category\n\t\t\t\tON\t\t(language_category.languageCategoryID = language_item.languageCategoryID)\n\t\t\t\tWHERE \t\tlanguage_item.packageID = package_dependency.dependency\n\t\t\t\t\t\tAND language_item.languageID = " . $this->languageID . "\n\t\t\t\t\t\tAND package_dependency.packageID = " . PACKAGE_ID . "\n\t\t\t\tORDER BY \tpackage_dependency.priority ASC";
     }
     $result = WCF::getDB()->sendQuery($sql);
     while ($row = WCF::getDB()->fetchArray($result)) {
         $items[$row['languageCategory']][$row['languageItem']] = $row['languageItemValue'];
     }
     // sort categories
     ksort($items);
     foreach ($items as $category => $categoryItems) {
         // sort items
         ksort($categoryItems);
         // category header
         echo "\t<category name=\"" . $category . "\">\n";
         // items
         foreach ($categoryItems as $item => $value) {
             if (CHARSET != 'UTF-8') {
                 $value = StringUtil::convertEncoding(CHARSET, 'UTF-8', $value);
             }
             echo "\t\t<item name=\"" . $item . "\"><![CDATA[" . StringUtil::escapeCDATA($value) . "]]></item>\n";
         }
         // category footer
         echo "\t</category>\n";
     }
     // footer
     echo "</language>";
 }
コード例 #20
0
 /**
  * Converts the encoding of an title into the charset used from the database
  * 
  * @param string $title			the title to be converted
  * @param string $fromCharset	the charset of the title, using 'auto' if not set
  */
 protected static function normalizeTitle($title, $fromCharset = 'auto')
 {
     //remove uneccessary empty characters und convert html special chars
     $title = StringUtil::convertEncoding($fromCharset, WCF::getDB()->getCharset(), $title);
     //return title converted to the used charset.
     return StringUtil::decodeHTML(StringUtil::trim($title));
 }
コード例 #21
0
 /**
  * Gets localized package information strings.
  * 
  * @param 	string		$key
  */
 protected function getLocalizedInformation($key)
 {
     if (isset($this->packageInfo[$key][LANGUAGE_CODE])) {
         $this->packageInfo[$key] = $this->packageInfo[$key][LANGUAGE_CODE];
     } else {
         if (isset($this->packageInfo[$key]['default'])) {
             $this->packageInfo[$key] = $this->packageInfo[$key]['default'];
         } else {
             $this->packageInfo[$key] = array_shift($this->packageInfo[$key]);
         }
     }
     // convert utf-8 to charset
     if (CHARSET != 'UTF-8') {
         $this->packageInfo[$key] = StringUtil::convertEncoding('UTF-8', CHARSET, $this->packageInfo[$key]);
     }
 }
コード例 #22
0
 /**
  * Generates the vcard.
  */
 protected function generate()
 {
     $this->content .= "BEGIN:VCARD\r\n";
     $this->content .= "VERSION:2.1\r\n";
     // name
     if ($this->user->name || $this->user->surname) {
         $this->content .= "N:" . $this->user->surname . ";" . $this->user->name . "\r\n";
         $this->content .= "FN:" . $this->user->name . " " . $this->user->surname . "\r\n";
     }
     // telephone
     if ($this->user->telephone) {
         $this->content .= "TEL;VOICE:" . $this->user->telephone . "\r\n";
     }
     // gender
     if ($this->user->gender) {
         $this->content .= "X-WAB-GENDER:" . (1 - $this->user->gender) . "\r\n";
     }
     // username
     $this->content .= "NICKNAME:" . $this->user->username . "\r\n";
     // occupation
     if ($this->user->occupation) {
         $this->content .= "TITLE;" . $this->user->occupation . "\r\n";
     }
     // email
     if (!$this->user->hideEmailAddress) {
         $this->content .= "EMAIL;INTERNET:" . $this->user->email . "\r\n";
     }
     // homepage
     if ($this->user->homepage) {
         $this->content .= "URL:" . $this->user->homepage . "\r\n";
     }
     // birthday
     if ($this->user->birthday) {
         $this->content .= "BDAY;value=date:" . $this->user->birthday . "\r\n";
     }
     // location
     if ($this->user->location) {
         $this->content .= "item2.ADR;type=HOME:;;" . $this->user->street . ";" . $this->user->location . ";" . $this->user->state . ";" . $this->user->zipcode . ";" . $this->user->country . "\r\n";
     }
     // fire event
     EventHandler::fireAction($this, 'generate');
     $this->content .= "END:VCARD";
     // vCard format does not support utf-8?
     if (CHARSET != 'ISO-8859-1') {
         $this->content = StringUtil::convertEncoding(CHARSET, 'ISO-8859-1', $this->content);
     }
 }
コード例 #23
0
 /**
  * Converts a array of strings to requested character encoding.
  * @see mb_convert_encoding()
  * 
  * @param 	string		$inCharset
  * @param 	string		$outCharset
  * @param 	string		$array
  * @return 	string		$array
  */
 public static function convertEncoding($inCharset, $outCharset, $array)
 {
     if (!is_array($array)) {
         return StringUtil::convertEncoding($inCharset, $outCharset, $array);
     } else {
         foreach ($array as $key => $val) {
             $array[$key] = self::convertEncoding($inCharset, $outCharset, $val);
         }
         return $array;
     }
 }
コード例 #24
0
 /**
  * Shows the license agreement.
  */
 protected function showLicense()
 {
     if (isset($_POST['send'])) {
         if (isset($_POST['accepted'])) {
             $this->gotoNextStep('showSystemRequirements');
             exit;
         } else {
             WCF::getTPL()->assign('missingAcception', true);
         }
     }
     if (file_exists(TMP_DIR . TMP_FILE_PREFIX . 'license_' . self::$selectedLanguageCode . '.txt')) {
         $license = file_get_contents(TMP_DIR . TMP_FILE_PREFIX . 'license_' . self::$selectedLanguageCode . '.txt');
     } else {
         $license = file_get_contents(TMP_DIR . TMP_FILE_PREFIX . 'license_en.txt');
     }
     if (self::$charset != 'UTF-8') {
         $license = StringUtil::convertEncoding('UTF-8', self::$charset, $license);
     }
     WCF::getTPL()->assign('license', $license);
     WCF::getTPL()->assign('nextStep', 'showLicense');
     WCF::getTPL()->display('stepShowLicense');
 }
コード例 #25
0
 /**
  * Parse a rss feed.
  * 
  * @param	string		$sourceURL
  * @return	array
  */
 public static function parseFeed($sourceURL)
 {
     $newsItems = array();
     $filename = FileUtil::downloadFileFromHttp($sourceURL, 'feed');
     // open & parse file
     $xml = new XML($filename);
     $data = $xml->getElementTree('channel');
     $items = $data['children'][0]['children'];
     foreach ($items as $item) {
         if ($item['name'] != 'item') {
             continue;
         }
         $newsItem = array('title' => '', 'author' => '', 'link' => '', 'guid' => '', 'pubDate' => '', 'description' => '');
         foreach ($item['children'] as $child) {
             if (!isset($child['cdata'])) {
                 continue;
             }
             $newsItem[$child['name']] = $child['cdata'];
         }
         // convert encodings
         if (CHARSET != 'UTF-8') {
             $newsItem['title'] = StringUtil::convertEncoding('UTF-8', CHARSET, $newsItem['title']);
             $newsItem['author'] = StringUtil::convertEncoding('UTF-8', CHARSET, $newsItem['author']);
             $newsItem['link'] = StringUtil::convertEncoding('UTF-8', CHARSET, $newsItem['link']);
             $newsItem['guid'] = StringUtil::convertEncoding('UTF-8', CHARSET, $newsItem['guid']);
             $newsItem['description'] = StringUtil::convertEncoding('UTF-8', CHARSET, $newsItem['description']);
         }
         @($newsItem['pubDate'] = intval(strtotime($newsItem['pubDate'])));
         $newsItems[] = $newsItem;
     }
     // delete tmp file
     @unlink($filename);
     return $newsItems;
 }
コード例 #26
0
 /**
  * Parses a stream containing info from a packages_update.xml.
  *
  * @param	string		$content
  * @return	array		$allNewPackages
  */
 protected static function parsePackageUpdateXML($content)
 {
     // load xml document
     $xmlObj = new XML();
     $xmlObj->loadString($content);
     // load the <section> tag (which must be the root element).
     $xml = $xmlObj->getElementTree('section');
     $encoding = $xmlObj->getEncoding();
     unset($xmlObj);
     // loop through <package> tags inside the <section> tag.
     $allNewPackages = array();
     foreach ($xml['children'] as $child) {
         // name attribute is missing, thus this package is not valid
         if (!isset($child['attrs']['name']) || !$child['attrs']['name']) {
             throw new SystemException("required 'name' attribute for 'package' tag is missing", 13001);
         }
         // the "name" attribute of this <package> tag must be a valid package identifier.
         if (!Package::isValidPackageName($child['attrs']['name'])) {
             throw new SystemException("'" . $child['attrs']['name'] . "' is not a valid package name.", 18004);
         }
         $package = $child['attrs']['name'];
         // parse packages_update.xml and fill $packageInfo.
         $packageInfo = self::parsePackageUpdateXMLBlock($child, $package);
         // convert enconding
         if ($encoding != CHARSET) {
             $packageInfo['packageName'] = StringUtil::convertEncoding($encoding, CHARSET, $packageInfo['packageName']);
             $packageInfo['packageDescription'] = StringUtil::convertEncoding($encoding, CHARSET, $packageInfo['packageDescription']);
             $packageInfo['author'] = StringUtil::convertEncoding($encoding, CHARSET, $packageInfo['author']);
             $packageInfo['authorURL'] = StringUtil::convertEncoding($encoding, CHARSET, $packageInfo['authorURL']);
         }
         $allNewPackages[$child['attrs']['name']] = $packageInfo;
     }
     unset($xml);
     return $allNewPackages;
 }
 /**
  * Prompts for license confirmation
  *
  * @return	bool
  */
 protected function promptLicenseConfirmation()
 {
     $errorType = '';
     $languageCode = $this->defaultLanguage;
     if (isset($this->licenseTexts[WCF::getLanguage()->getLanguageCode()])) {
         $languageCode = WCF::getLanguage()->getLanguageCode();
     }
     if (WCF::getLanguage()->getLanguageCode() == 'de-informal' && $languageCode != 'de-informal' && isset($this->licenseTexts['de'])) {
         $languageCode = 'de';
     }
     if (isset($_POST['send'])) {
         if (isset($_POST['languageCode'])) {
             if (array_key_exists($_POST['languageCode'], $this->licenseTexts)) {
                 $languageCode = $_POST['languageCode'];
             }
         }
         if (!isset($_POST['langChooser'])) {
             if (isset($_POST['licenseAccepted'])) {
                 if (intval(StringUtil::trim($_POST['licenseAccepted'])) == 1) {
                     return true;
                 }
             }
             $errorType = 'missingAcception';
         }
     }
     $availableLanguages = array();
     foreach ($this->licenseTexts as $langCode => $value) {
         if ($languageCode == '') {
             $languageCode = $langCode;
         }
         $availableLanguages[$langCode] = WCF::getLanguage()->get('wcf.global.language.' . $langCode) . ' (' . $langCode . ')';
     }
     $licenseText = $this->licenseTexts[$languageCode]['licenseText'];
     if (CHARSET != 'UTF-8') {
         $licenseText = StringUtil::convertEncoding('UTF-8', CHARSET, $licenseText);
     }
     WCF::getTPL()->assign(array('licenseText' => $licenseText, 'languageCode' => $languageCode, 'availableLanguages' => $availableLanguages, 'errorType' => $errorType));
     WCF::getTPL()->display('packageInstallationShowLicenseText');
     exit;
 }
コード例 #28
0
 /**
  * @see Form::save()
  */
 public function save()
 {
     $username = WCF::getUser()->username ? WCF::getUser()->username : '******';
     $sql = "INSERT INTO wcf" . WCF_N . "_ics_holiday_exporter_log" . "\n       (ihelTime, ihelCtryCode, ihelFromYear, ihelToYear, ihelUsername)" . "\nVALUES (" . TIME_NOW . ", '" . $this->country . "', " . $this->fromYear . ", " . $this->toYear . ", '" . WCF::getDB()->escapeString($username) . "')";
     WCF::getDB()->sendQuery($sql);
     $tmp = parse_url(PAGE_URL);
     $parsedUrl = $tmp['host'];
     $fName = ICSHE_FILE_PREFIX . $this->country . '_' . $this->fromYear . '-' . $this->toYear . '.ics';
     $h = $this->getHolidays();
     $this->addLine("BEGIN:VCALENDAR");
     $this->addLine("METHOD:PUBLISH");
     $this->addLine("VERSION:2.0");
     $this->addLine("PRODID:-//WBB3-Add-Ons//ICS Holiday Exporter " . $this->version . "//EN");
     $this->addLine("CALSCALE:GREGORIAN");
     foreach ($h as $k => $v) {
         $zT = gmdate("Ymd\\THis\\Z");
         $this->addLine("BEGIN:VEVENT");
         $this->addLine("DTSTART;VALUE=DATE:" . $v['DTSTART']);
         $this->addLine("DTEND;VALUE=DATE:" . $v['DTEND']);
         if (!empty($v['RRULE'])) {
             $this->addLine("RRULE:" . $v['RRULE']);
         }
         $this->addLine("DTSTAMP:" . $zT);
         $this->addLine("UID:" . md5(uniqid(rand(), true)) . "@" . $parsedUrl);
         $this->addLine("CREATED:" . $zT);
         $this->addLine("LAST-MODIFIED:" . $zT);
         $this->addLine("STATUS:CONFIRMED");
         $this->addLine("URL:" . PAGE_URL);
         $this->addLine("SUMMARY:" . $this->escLine($v['SUMMARY']));
         if (!empty($v['DESCRIPTION'])) {
             $this->addLine("DESCRIPTION:" . $this->escLine($v['DESCRIPTION']));
         }
         $this->addLine("TRANSP:TRANSPARENT");
         $this->addLine("END:VEVENT");
     }
     $this->addLine("END:VCALENDAR");
     // convert encoding
     if (CHARSET != 'UTF-8') {
         $this->content = StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->content);
     }
     // file type
     header('Content-Type: application/octet-stream');
     // file name
     header('Content-Disposition: attachment; filename="' . $fName . '"');
     // no cache headers
     header('Pragma: no-cache');
     header('Expires: 0');
     // send file
     echo $this->content;
     exit;
 }
コード例 #29
0
 /**
  * Exports this style.
  * 
  * @param	boolean 	$templates
  * @param	boolean		$images
  * @param	boolean		$icons
  */
 public function export($templates = false, $images = false, $icons = false)
 {
     // create style tar
     require_once WCF_DIR . 'lib/system/io/TarWriter.class.php';
     $styleTarName = FileUtil::getTemporaryFilename('style_', '.tgz');
     $styleTar = new TarWriter($styleTarName, true);
     // append style preview image
     if ($this->image && @file_exists(WCF_DIR . $this->image)) {
         $styleTar->add(WCF_DIR . $this->image, '', FileUtil::addTrailingSlash(dirname(WCF_DIR . $this->image)));
     }
     // create style info file
     $string = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE style SYSTEM \"http://www.woltlab.com/DTDs/SXF/style.dtd\">\n<style>\n";
     // general block
     $string .= "\t<general>\n";
     $string .= "\t\t<stylename><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->styleName) : $this->styleName) . "]]></stylename>\n";
     // style name
     if ($this->styleDescription) {
         $string .= "\t\t<description><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->styleDescription) : $this->styleDescription) . "]]></description>\n";
     }
     // style description
     if ($this->styleVersion) {
         $string .= "\t\t<version><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->styleVersion) : $this->styleVersion) . "]]></version>\n";
     }
     // style version
     if ($this->styleDate) {
         $string .= "\t\t<date><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->styleDate) : $this->styleDate) . "]]></date>\n";
     }
     // style date
     if ($this->image) {
         $string .= "\t\t<image><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', basename($this->image)) : basename($this->image)) . "]]></image>\n";
     }
     // style preview image
     if ($this->copyright) {
         $string .= "\t\t<copyright><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->copyright) : $this->copyright) . "]]></copyright>\n";
     }
     // copyright
     if ($this->license) {
         $string .= "\t\t<license><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->license) : $this->license) . "]]></license>\n";
     }
     // license
     $string .= "\t</general>\n";
     // author block
     $string .= "\t<author>\n";
     if ($this->authorName) {
         $string .= "\t\t<authorname><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->authorName) : $this->authorName) . "]]></authorname>\n";
     }
     // author name
     if ($this->authorURL) {
         $string .= "\t\t<authorurl><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $this->authorURL) : $this->authorURL) . "]]></authorurl>\n";
     }
     // author URL
     $string .= "\t</author>\n";
     // files block
     $string .= "\t<files>\n";
     $string .= "\t\t<variables>variables.xml</variables>\n";
     // variables
     if ($templates && $this->templatePackID) {
         $string .= "\t\t<templates>templates.tar</templates>\n";
     }
     // templates
     if ($images) {
         $string .= "\t\t<images>images.tar</images>\n";
     }
     // images
     if ($icons) {
         $string .= "\t\t<icons>icons.tar</icons>\n";
     }
     // icons
     $string .= "\t</files>\n";
     $string .= "</style>";
     // append style info file to style tar
     $styleTar->addString(self::INFO_FILE, $string);
     unset($string);
     // create variable list
     $string = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE variables SYSTEM \"http://www.woltlab.com/DTDs/SXF/variables.dtd\">\n<variables>\n";
     // get variables
     $variables = $this->getVariables();
     $exportImages = array();
     foreach ($variables as $name => $value) {
         // search images
         if ($images && $value) {
             if (preg_match_all('~([^/\\s\\$]+\\.(?:gif|jpg|jpeg|png))~i', $value, $matches)) {
                 $exportImages = array_merge($exportImages, $matches[1]);
             }
         }
         $string .= "\t<variable name=\"" . StringUtil::encodeHTML($name) . "\"><![CDATA[" . StringUtil::escapeCDATA(CHARSET != 'UTF-8' ? StringUtil::convertEncoding(CHARSET, 'UTF-8', $value) : $value) . "]]></variable>\n";
     }
     $string .= "</variables>";
     // append variable list to style tar
     $styleTar->addString('variables.xml', $string);
     unset($string);
     if ($templates && $this->templatePackID) {
         require_once WCF_DIR . 'lib/data/template/TemplatePack.class.php';
         $templatePack = new TemplatePack($this->templatePackID);
         // create templates tar
         $templatesTarName = FileUtil::getTemporaryFilename('templates', '.tar');
         $templatesTar = new TarWriter($templatesTarName);
         @chmod($templatesTarName, 0777);
         // append templates to tar
         // get templates
         $sql = "SELECT\t\ttemplate.*, package.package, package.packageDir,\n\t\t\t\t\t\tparent_package.package AS parentPackage, parent_package.packageDir AS parentPackageDir\n\t\t\t\tFROM\t\twcf" . WCF_N . "_template template\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\t\tON\t\t(package.packageID = template.packageID)\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package parent_package\n\t\t\t\tON\t\t(parent_package.packageID = package.parentPackageID)\n\t\t\t\tWHERE\t\ttemplate.templatePackID = " . $this->templatePackID;
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             $packageDir = 'com.woltlab.wcf';
             if (!empty($row['parentPackageDir'])) {
                 $packageDir = $row['parentPackage'];
             } else {
                 if (!empty($row['packageDir'])) {
                     $packageDir = $row['package'];
                 }
             }
             $filename = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir'] . 'templates/' . $templatePack->templatePackFolderName)) . $row['templateName'] . '.tpl';
             $templatesTar->add($filename, $packageDir, dirname($filename));
         }
         // append templates tar to style tar
         $templatesTar->create();
         $styleTar->add($templatesTarName, 'templates.tar', $templatesTarName);
         @unlink($templatesTarName);
     }
     if ($images) {
         // create images tar
         $imagesTarName = FileUtil::getTemporaryFilename('images_', '.tar');
         $imagesTar = new TarWriter($imagesTarName);
         @chmod($imagesTarName, 0777);
         // cache rtl versions
         foreach ($exportImages as $exportImage) {
             if (strpos($exportImage, '-ltr')) {
                 $exportImages[] = str_replace('-ltr', '-rtl', $exportImage);
             }
         }
         // append images to tar
         $path = WCF_DIR . $variables['global.images.location'];
         if (file_exists($path) && is_dir($path)) {
             $handle = opendir($path);
             while (($file = readdir($handle)) !== false) {
                 if (is_file($path . $file) && in_array($file, $exportImages)) {
                     $imagesTar->add($path . $file, '', $path);
                 }
             }
         }
         // append images tar to style tar
         $imagesTar->create();
         $styleTar->add($imagesTarName, 'images.tar', $imagesTarName);
         @unlink($imagesTarName);
     }
     // export icons
     $iconsLocation = FileUtil::addTrailingSlash($variables['global.icons.location']);
     if ($icons && $iconsLocation != 'icon/') {
         // create icons tar
         $iconsTarName = FileUtil::getTemporaryFilename('icons_', '.tar');
         $iconsTar = new TarWriter($iconsTarName);
         @chmod($iconsTar, 0777);
         // get package dirs
         $sql = "SELECT\tpackage, packageDir\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tstandalone = 1\n\t\t\t\t\tAND (packageDir <> '' OR package = 'com.woltlab.wcf')";
         $result = WCF::getDB()->sendQuery($sql);
         while ($row = WCF::getDB()->fetchArray($result)) {
             $iconsDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . $iconsLocation;
             $packageIcons = array();
             if (file_exists($iconsDir)) {
                 $icons = glob($iconsDir . '*.png');
                 if (is_array($icons)) {
                     foreach ($icons as $icon) {
                         $packageIcons[] = $icon;
                     }
                 }
             }
             if (count($packageIcons)) {
                 $iconsTar->add($packageIcons, $row['package'] . '/', $iconsDir);
             }
         }
         $iconsTar->create();
         $styleTar->add($iconsTarName, 'icons.tar', $iconsTarName);
         @unlink($iconsTarName);
     }
     // output file content
     $styleTar->create();
     readfile($styleTarName);
     @unlink($styleTarName);
 }
 /**
  * Installs option categories and options.
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // create an array with the import and delete instructions from the xml file
     $optionsXML = $xml->getElementTree('data');
     // install or uninstall categories and options.
     foreach ($optionsXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // handle the import instructions
             if ($block['name'] == 'import') {
                 // loop through categories and options
                 foreach ($block['children'] as $child) {
                     // handle categories
                     if ($child['name'] == 'categories') {
                         // loop through all categories
                         foreach ($child['children'] as $category) {
                             // check required category name
                             if (!isset($category['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for option category is missing", 13023);
                             }
                             // default values
                             $categoryName = $parentCategoryName = $permissions = $options = '';
                             $showOrder = null;
                             // make xml tags-names (keys in array) to lower case
                             $this->keysToLowerCase($category);
                             // get category data from children (parent, showorder, icon and menuicon)
                             foreach ($category['children'] as $data) {
                                 if (!isset($data['cdata'])) {
                                     continue;
                                 }
                                 $category[$data['name']] = $data['cdata'];
                             }
                             // get and secure values
                             $categoryName = escapeString($category['attrs']['name']);
                             if (isset($category['permissions'])) {
                                 $permissions = $category['permissions'];
                             }
                             if (isset($category['options'])) {
                                 $options = $category['options'];
                             }
                             if (isset($category['parent'])) {
                                 $parentCategoryName = escapeString($category['parent']);
                             }
                             if (!empty($category['showorder'])) {
                                 $showOrder = intval($category['showorder']);
                             }
                             if ($showOrder !== null || $this->installation->getAction() != 'update') {
                                 $showOrder = $this->getShowOrder($showOrder, $parentCategoryName, 'parentCategoryName', '_category');
                             }
                             // if a parent category was set and this parent is not in database
                             // or it is a category from a package from other package environment: don't install further.
                             if ($parentCategoryName != '') {
                                 $sql = "SELECT\tCOUNT(categoryID) AS count\n\t\t\t\t\t\t\t\t\t\t\tFROM\twcf" . WCF_N . "_" . $this->tableName . "_category\n\t\t\t\t\t\t\t\t\t\t\tWHERE\tcategoryName = '" . escapeString($parentCategoryName) . "'";
                                 /*	AND packageID IN (
                                 				SELECT	dependency
                                 				FROM	wcf".WCF_N."_package_dependency
                                 				WHERE	packageID = ".$this->installation->getPackageID()."
                                 			)";*/
                                 $parentCategoryCount = WCF::getDB()->getFirstRow($sql);
                                 // unable to find parent category in dependency-packages: abort installation
                                 if ($parentCategoryCount['count'] == 0) {
                                     throw new SystemException("Unable to find parent 'option category' with name '" . $parentCategoryName . "' for category with name '" . $categoryName . "'.", 13011);
                                 }
                             }
                             // save category
                             $categoryData = array('categoryName' => $categoryName, 'parentCategoryName' => $parentCategoryName, 'showOrder' => $showOrder, 'permissions' => $permissions, 'options' => $options);
                             $this->saveCategory($categoryData, $category);
                         }
                     } elseif ($child['name'] == 'options') {
                         // <option>
                         foreach ($child['children'] as $option) {
                             // extract <category> <optiontype> <optionvalue> <visible> etc
                             foreach ($option['children'] as $_child) {
                                 $option[$_child['name']] = $_child['cdata'];
                             }
                             // convert character encoding
                             if (CHARSET != 'UTF-8') {
                                 if (isset($option['defaultvalue'])) {
                                     $option['defaultvalue'] = StringUtil::convertEncoding('UTF-8', CHARSET, $option['defaultvalue']);
                                 }
                                 if (isset($option['selectoptions'])) {
                                     $option['selectoptions'] = StringUtil::convertEncoding('UTF-8', CHARSET, $option['selectoptions']);
                                 }
                             }
                             // check required category name
                             if (!isset($option['categoryname'])) {
                                 throw new SystemException("Required category for option is missing", 13023);
                             }
                             $categoryName = escapeString($option['categoryname']);
                             // store option name
                             $option['name'] = $option['attrs']['name'];
                             // children info already stored with name => cdata
                             // shrink array
                             unset($option['children']);
                             if (!preg_match("/^[\\w-\\.]+\$/", $option['name'])) {
                                 $matches = array();
                                 preg_match_all("/(\\W)/", $option['name'], $matches);
                                 throw new SystemException("The user option '" . $option['name'] . "' has at least one non-alphanumeric character (underscore is permitted): (" . implode("), ( ", $matches[1]) . ").", 13024);
                             }
                             $this->saveOption($option, $categoryName);
                         }
                     }
                 }
             } else {
                 if ($block['name'] == 'delete' && $this->installation->getAction() == 'update') {
                     $optionNames = '';
                     $categoryNames = '';
                     foreach ($block['children'] as $deleteTag) {
                         // check required attributes
                         if (!isset($deleteTag['attrs']['name'])) {
                             throw new SystemException("Required 'name' attribute for '" . $deleteTag['name'] . "'-tag is missing", 13023);
                         }
                         if ($deleteTag['name'] == 'option') {
                             // build optionnames string
                             if (!empty($optionNames)) {
                                 $optionNames .= ',';
                             }
                             $optionNames .= "'" . escapeString($deleteTag['attrs']['name']) . "'";
                         } elseif ($deleteTag['name'] == 'optioncategory') {
                             // build categorynames string
                             if (!empty($categoryNames)) {
                                 $categoryNames .= ',';
                             }
                             $categoryNames .= "'" . escapeString($deleteTag['attrs']['name']) . "'";
                         }
                     }
                     // delete options
                     if (!empty($optionNames)) {
                         $this->deleteOptions($optionNames);
                     }
                     // elete categories
                     if (!empty($categoryNames)) {
                         $this->deleteCategories($categoryNames);
                     }
                 }
             }
         }
     }
 }