From 2d2cf97905c57bc3cde48d2ada20ba85a9796a91 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 7 Dec 2012 19:01:58 +0100 Subject: [PATCH] Optimized language handling * Force attempt to load all possible language categories for an item * Cut queries required to load items by half --- .../lib/data/language/Language.class.php | 19 ++-- .../data/language/LanguageEditor.class.php | 93 +++++++------------ .../builder/LanguageCacheBuilder.class.php | 4 +- .../system/language/LanguageFactory.class.php | 14 +++ 4 files changed, 66 insertions(+), 64 deletions(-) diff --git a/wcfsetup/install/files/lib/data/language/Language.class.php b/wcfsetup/install/files/lib/data/language/Language.class.php index cdd36b1c60..367084c8d9 100644 --- a/wcfsetup/install/files/lib/data/language/Language.class.php +++ b/wcfsetup/install/files/lib/data/language/Language.class.php @@ -87,15 +87,18 @@ class Language extends DatabaseObject { if (!isset($this->items[$item])) { // load category file $explodedItem = explode('.', $item); - if (count($explodedItem) < 2) { + if (count($explodedItem) < 3) { return $item; } - if (count($explodedItem) < 4 || !$this->loadCategory($explodedItem[0].'.'.$explodedItem[1].'.'.$explodedItem[2].'.'.$explodedItem[3])) { - if (count($explodedItem) < 3 || !$this->loadCategory($explodedItem[0].'.'.$explodedItem[1].'.'.$explodedItem[2])) { - $this->loadCategory($explodedItem[0].'.'.$explodedItem[1]); - } + // attempt to load all categories beginning with the most specific + if (isset($explodedItem[4])) { + $this->loadCategory($explodedItem[0].'.'.$explodedItem[1].'.'.$explodedItem[2].'.'.$explodedItem[3]); } + if (isset($explodedItem[3])) { + $this->loadCategory($explodedItem[0].'.'.$explodedItem[1].'.'.$explodedItem[2]); + } + $this->loadCategory($explodedItem[0].'.'.$explodedItem[1]); } // return language variable @@ -147,7 +150,11 @@ class Language extends DatabaseObject { // rebuild language file $languageCategory = LanguageFactory::getInstance()->getCategory($category); - $this->editor->updateCategory(array($languageCategory->languageCategoryID)); + if ($languageCategory === null) { + return false; + } + + $this->editor->updateCategory($languageCategory); } // include language file diff --git a/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php b/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php index cf0ba4f533..c8624da09d 100644 --- a/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php +++ b/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php @@ -45,81 +45,60 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje /** * Updates the language files for the given category. * - * @param array $categoryIDs + * @param wcf\data\language\category\LanguageCategory $languageCategory */ - public function updateCategory(array $categoryIDs = array()) { - if (empty($categoryIDs)) { - // get all categories - $sql = "SELECT languageCategoryID - FROM wcf".WCF_N."_language_category"; - $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute(); - while ($row = $statement->fetchArray()) { - $categoryIDs[] = $row['languageCategoryID']; - } - } - - $this->writeLanguageFiles($categoryIDs); + public function updateCategory(LanguageCategory $languageCategory) { + $this->writeLanguageFiles(array($languageCategory->languageCategoryID)); } /** * Write the languages files. * - * @param array $categoryIDs + * @param array $languageCategoryIDs */ - protected function writeLanguageFiles(array $categoryIDs) { - // get categories + protected function writeLanguageFiles(array $languageCategoryIDs) { $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("languageCategoryID IN (?)", array($categoryIDs)); + $conditions->add("languageID = ?", array($this->languageID)); + $conditions->add("languageCategoryID IN (?)", array($languageCategoryIDs)); - $sql = "SELECT * - FROM wcf".WCF_N."_language_category + // get language items + $sql = "SELECT languageItem, languageItemValue, languageCustomItemValue, + languageUseCustomValue, languageCategoryID + FROM wcf".WCF_N."_language_item ".$conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); - while ($category = $statement->fetchArray()) { - $categoryName = $category['languageCategory']; - $categoryID = $category['languageCategoryID']; - - $conditions = new PreparedStatementConditionBuilder(); - $conditions->add("languageID = ?", array($this->languageID)); - $conditions->add("languageCategoryID = ?", array($categoryID)); - - // get language items - $sql = "SELECT languageItem, languageItemValue, languageCustomItemValue, languageUseCustomValue - FROM wcf".WCF_N."_language_item - ".$conditions; + $items = array(); + while ($row = $statement->fetchArray()) { + $languageCategoryID = $row['languageCategoryID']; + if (!isset($items[$languageCategoryID])) { + $items[$languageCategoryID] = array(); + } - $statement2 = WCF::getDB()->prepareStatement($sql); - $statement2->execute($conditions->getParameters()); - $items = array(); - while ($row = $statement2->fetchArray()) { - if ($row['languageUseCustomValue'] == 1) { - $items[$row['languageItem']] = $row['languageCustomItemValue']; - } - else { - $items[$row['languageItem']] = $row['languageItemValue']; - } + $items[$languageCategoryID][$row['languageItem']] = ($row['languageUseCustomValue']) ? $row['languageCustomItemValue'] : $row['languageItemValue']; + } + + foreach ($items as $languageCategoryID => $languageItems) { + $category = LanguageFactory::getInstance()->getCategoryByID($languageCategoryID); + if ($category === null) { + continue; } - if (!empty($items)) { - $content = "languageCode."\n* encoding: UTF-8\n* category: ".$categoryName."\n* generated at ".gmdate("r")."\n* \n* DO NOT EDIT THIS FILE\n*/\n"; + $content = "languageCode."\n* encoding: UTF-8\n* category: ".$category->languageCategory."\n* generated at ".gmdate("r")."\n* \n* DO NOT EDIT THIS FILE\n*/\n"; + foreach ($languageItems as $languageItem => $languageItemValue) { + $content .= "\$this->items['".$languageItem."'] = '".str_replace("'", "\'", $languageItemValue)."';\n"; - foreach ($items as $languageItem => $languageItemValue) { - $content .= "\$this->items['".$languageItem."'] = '".str_replace("'", "\'", $languageItemValue)."';\n"; - - // compile dynamic language variables - if ($categoryName != 'wcf.global' && strpos($languageItemValue, '{') !== false) { - $output = LanguageFactory::getInstance()->getScriptingCompiler()->compileString($languageItem, $languageItemValue); - $content .= "\$this->dynamicItems['".$languageItem."'] = '".str_replace("'", "\'", $output['template'])."';\n"; - } + // compile dynamic language variables + if ($category->languageCategory != 'wcf.global' && strpos($languageItemValue, '{') !== false) { + $output = LanguageFactory::getInstance()->getScriptingCompiler()->compileString($languageItem, $languageItemValue); + $content .= "\$this->dynamicItems['".$languageItem."'] = '".str_replace("'", "\'", $output['template'])."';\n"; } - - $file = new File(WCF_DIR.'language/'.$this->languageID.'_'.$categoryName.'.php'); - @$file->chmod(0777); - $file->write($content . '?>'); - $file->close(); } + + $file = new File(WCF_DIR.'language/'.$this->languageID.'_'.$category->languageCategory.'.php'); + @$file->chmod(0777); + $file->write($content . '?>'); + $file->close(); } } diff --git a/wcfsetup/install/files/lib/system/cache/builder/LanguageCacheBuilder.class.php b/wcfsetup/install/files/lib/system/cache/builder/LanguageCacheBuilder.class.php index cd1fd89f32..4d90825e2f 100644 --- a/wcfsetup/install/files/lib/system/cache/builder/LanguageCacheBuilder.class.php +++ b/wcfsetup/install/files/lib/system/cache/builder/LanguageCacheBuilder.class.php @@ -26,7 +26,8 @@ class LanguageCacheBuilder implements ICacheBuilder { 'countryCodes' => array(), 'languages' => array(), 'default' => 0, - 'categories' => array() + 'categories' => array(), + 'categoryIDs' => array() ); // get languages @@ -55,6 +56,7 @@ class LanguageCacheBuilder implements ICacheBuilder { $languageCategoryList->readObjects(); foreach ($languageCategoryList->getObjects() as $languageCategory) { $data['categories'][$languageCategory->languageCategory] = $languageCategory; + $data['categoryIDs'][$languageCategory->languageCategoryID] = $languageCategory->languageCategory; } return $data; diff --git a/wcfsetup/install/files/lib/system/language/LanguageFactory.class.php b/wcfsetup/install/files/lib/system/language/LanguageFactory.class.php index b7c3709ca6..de50b103f5 100644 --- a/wcfsetup/install/files/lib/system/language/LanguageFactory.class.php +++ b/wcfsetup/install/files/lib/system/language/LanguageFactory.class.php @@ -126,6 +126,20 @@ class LanguageFactory extends SingletonFactory { return null; } + /** + * Returns language category by id. + * + * @param integer $languageCategoryID + * @return wcf\data\language\category\LanguageCategory + */ + public function getCategoryByID($languageCategoryID) { + if (isset($this->cache['categoryIDs'][$languageCategoryID])) { + return $this->cache['categories'][$this->cache['categoryIDs'][$languageCategoryID]]; + } + + return null; + } + /** * Returns a list of available language categories. * -- 2.20.1