Optimized language handling
authorAlexander Ebert <ebert@woltlab.com>
Fri, 7 Dec 2012 18:01:58 +0000 (19:01 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 7 Dec 2012 18:01:58 +0000 (19:01 +0100)
 * Force attempt to load all possible language categories for an item
 * Cut queries required to load items by half

wcfsetup/install/files/lib/data/language/Language.class.php
wcfsetup/install/files/lib/data/language/LanguageEditor.class.php
wcfsetup/install/files/lib/system/cache/builder/LanguageCacheBuilder.class.php
wcfsetup/install/files/lib/system/language/LanguageFactory.class.php

index cdd36b1c60373aec4a558c2cfedeedf4491f06a1..367084c8d9674e85544e54b178e75417293f2d43 100644 (file)
@@ -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
index cf0ba4f5338297cd513c7a974493fce9df3fb2ee..c8624da09d5944e767ec173df77ce73ec383ac85 100644 (file)
@@ -45,81 +45,60 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje
        /**
         * Updates the language files for the given category.
         * 
-        * @param       array<integer>          $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<integer>          $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 = "<?php\n/**\n* WoltLab Community Framework\n* language: ".$this->languageCode."\n* encoding: UTF-8\n* category: ".$categoryName."\n* generated at ".gmdate("r")."\n* \n* DO NOT EDIT THIS FILE\n*/\n";
+                       $content = "<?php\n/**\n* WoltLab Community Framework\n* language: ".$this->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();
                }
        }
        
index cd1fd89f32f638d1feecdbcda4d2650dad2ebe02..4d90825e2f620791ec47bec42a3b969c95dd8091 100644 (file)
@@ -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;
index b7c3709ca63217120475e9b30875b6a37d15ffd6..de50b103f593534254f1b8da7678d805963fda9b 100644 (file)
@@ -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.
         *