/**
  * Imports language items from an XML file into this language.
  * Updates the relevant language files automatically.
  * 
  * @param	\wcf\util\XML	$xml
  * @param	integer		$packageID
  * @param	boolean		$updateFiles
  * @param	boolean		$updateExistingItems
  */
 public function updateFromXML(XML $xml, $packageID, $updateFiles = true, $updateExistingItems = true)
 {
     $xpath = $xml->xpath();
     $usedCategories = array();
     // fetch categories
     $categories = $xpath->query('/ns:language/ns:category');
     foreach ($categories as $category) {
         $usedCategories[$category->getAttribute('name')] = 0;
     }
     if (empty($usedCategories)) {
         return;
     }
     // select existing categories
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("languageCategory IN (?)", array(array_keys($usedCategories)));
     $sql = "SELECT\tlanguageCategoryID, languageCategory\n\t\t\tFROM\twcf" . WCF_N . "_language_category\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         $usedCategories[$row['languageCategory']] = $row['languageCategoryID'];
     }
     // create new categories
     foreach ($usedCategories as $categoryName => $categoryID) {
         if ($categoryID) {
             continue;
         }
         $category = LanguageCategoryEditor::create(array('languageCategory' => $categoryName));
         $usedCategories[$categoryName] = $category->languageCategoryID;
     }
     // loop through categories to import items
     $itemData = array();
     foreach ($categories as $category) {
         $categoryName = $category->getAttribute('name');
         $categoryID = $usedCategories[$categoryName];
         // loop through items
         $elements = $xpath->query('child::*', $category);
         foreach ($elements as $element) {
             $itemName = $element->getAttribute('name');
             $itemValue = $element->nodeValue;
             $itemData[] = $this->languageID;
             $itemData[] = $itemName;
             $itemData[] = $itemValue;
             $itemData[] = $categoryID;
             if ($packageID) {
                 $itemData[] = $packageID == -1 ? PACKAGE_ID : $packageID;
             }
         }
     }
     if (!empty($itemData)) {
         // insert/update a maximum of 50 items per run (prevents issues with max_allowed_packet)
         $step = $packageID ? 5 : 4;
         WCF::getDB()->beginTransaction();
         for ($i = 0, $length = count($itemData); $i < $length; $i += 50 * $step) {
             $parameters = array_slice($itemData, $i, 50 * $step);
             $repeat = count($parameters) / $step;
             $sql = "INSERT" . (!$updateExistingItems ? " IGNORE" : "") . " INTO\t\twcf" . WCF_N . "_language_item\n\t\t\t\t\t\t\t\t(languageID, languageItem, languageItemValue, languageCategoryID" . ($packageID ? ", packageID" : "") . ")\n\t\t\t\t\tVALUES\t\t\t" . substr(str_repeat('(?, ?, ?, ?' . ($packageID ? ', ?' : '') . '), ', $repeat), 0, -2);
             if ($updateExistingItems) {
                 if ($packageID > 0) {
                     // do not update anything if language item is owned by a different package
                     $sql .= "\tON DUPLICATE KEY\n\t\t\t\t\t\t\t\tUPDATE\t\t\tlanguageUseCustomValue = IF(packageID = " . $packageID . ", IF(languageItemValue = VALUES(languageItemValue), languageUseCustomValue, 0), languageUseCustomValue),\n\t\t\t\t\t\t\t\t\t\t\tlanguageItemValue = IF(packageID = " . $packageID . ", IF(languageItemOriginIsSystem = 0, languageItemValue, VALUES(languageItemValue)), languageItemValue),\n\t\t\t\t\t\t\t\t\t\t\tlanguageCategoryID = IF(packageID = " . $packageID . ", VALUES(languageCategoryID), languageCategoryID)";
                 } else {
                     // skip package id check during WCFSetup (packageID = 0) or if using the ACP form (packageID = -1)
                     $sql .= "\tON DUPLICATE KEY\n\t\t\t\t\t\t\t\tUPDATE\t\t\tlanguageUseCustomValue = IF(languageItemValue = VALUES(languageItemValue), languageUseCustomValue, 0),\n\t\t\t\t\t\t\t\t\t\t\tlanguageItemValue = IF(languageItemOriginIsSystem = 0, languageItemValue, VALUES(languageItemValue)),\n\t\t\t\t\t\t\t\t\t\t\tlanguageCategoryID = VALUES(languageCategoryID)";
                 }
             }
             $statement = WCF::getDB()->prepareStatement($sql);
             $statement->execute($parameters);
         }
         WCF::getDB()->commitTransaction();
     }
     // update the relevant language files
     if ($updateFiles) {
         self::deleteLanguageFiles($this->languageID);
     }
     // delete relevant template compilations
     $this->deleteCompiledTemplates();
 }
Beispiel #2
0
	/**
	 * Imports language items from an XML file into this language.
	 * Updates the relevant language files automatically.
	 * 
	 * @param	wcf\util\XML	$xml
	 * @param	integer		$packageID
	 * @param	boolean		$updateFiles
	 */
	public function updateFromXML(XML $xml, $packageID, $updateFiles = true) {
		$xpath = $xml->xpath();
		$usedCategories = array();
		
		// fetch categories
		$categories = $xpath->query('/ns:language/ns:category');
		foreach ($categories as $category) {
			$usedCategories[$category->getAttribute('name')] = 0;
		}
		
		if (empty($usedCategories)) return;
		
		// select existing categories
		$conditions = new PreparedStatementConditionBuilder();
		$conditions->add("languageCategory IN (?)", array(array_keys($usedCategories)));
		
		$sql = "SELECT	languageCategoryID, languageCategory
			FROM	wcf".WCF_N."_language_category
			".$conditions;
		$statement = WCF::getDB()->prepareStatement($sql);
		$statement->execute($conditions->getParameters());
		while ($row = $statement->fetchArray()) {
			$usedCategories[$row['languageCategory']] = $row['languageCategoryID'];
		}
		
		// create new categories
		foreach ($usedCategories as $categoryName => $categoryID) {
			if ($categoryID) continue;
			
			$category = LanguageCategoryEditor::create(array(
				'languageCategory' => $categoryName
			));
			$usedCategories[$categoryName] = $category->languageCategoryID;
		}
		
		// loop through categories to import items
		$items = array();
		foreach ($categories as $category) {
			$categoryName = $category->getAttribute('name');
			$categoryID = $usedCategories[$categoryName];
			
			// loop through items
			$elements = $xpath->query('child::*', $category);
			foreach ($elements as $element) {
				$itemName = $element->getAttribute('name');
				$itemValue = $element->nodeValue;
				
				$items[$itemName] = array(
					'name' => $itemName,
					'value' => $itemValue,
					'categoryID' => $categoryID
				);
			}
		}
		
		if (!empty($items)) {
			$existingItems = $statementParameters = array();
			
			// find existing items
			$itemList = new LanguageItemList();
			$itemList->getConditionBuilder()->add("language_item.languageItem IN (?)", array(array_keys($items)));
			$itemList->getConditionBuilder()->add("language_item.languageID = ?", array($this->languageID));
			$itemList->readObjects();
			
			foreach ($itemList->getObjects() as $languageItem) {
				$existingItems[$languageItem->languageItem] = $languageItem;
			}
			
			foreach ($items as $item) {
				if (isset($existingItems[$item['name']])) {
					// update existing item
					$itemEditor = new LanguageItemEditor($existingItems[$item['name']]);
					$itemEditor->update(array(
						'languageItemValue' => $item['value'],
						'languageCategoryID' => $item['categoryID'],
						'languageUseCustomValue' => 0,
						'languageItem' => $item['name']
					));
				}
				else {
					// store item for later insert
					$statementParameters[] = $item;
				}
			}
			
			if (!empty($statementParameters)) {
				if ($packageID) {
					$sql = "INSERT INTO	wcf".WCF_N."_language_item
								(languageID, languageItem, languageItemValue, languageCategoryID, packageID)
						VALUES		(?, ?, ?, ?, ?)";
					$statement = WCF::getDB()->prepareStatement($sql);
					
					foreach ($statementParameters as $item) {
						$statement->execute(array(
							$this->languageID,
							$item['name'],
							$item['value'],
							$item['categoryID'],
							$packageID
						));
					}
				}
				else {
					$sql = "INSERT INTO	wcf".WCF_N."_language_item
								(languageID, languageItem, languageItemValue, languageCategoryID)
						VALUES		(?, ?, ?, ?)";
					$statement = WCF::getDB()->prepareStatement($sql);
					
					foreach ($statementParameters as $item) {
						$statement->execute(array(
							$this->languageID,
							$item['name'],
							$item['value'],
							$item['categoryID']
						));
					}
				}
			}
		}
		
		// update the relevant language files
		if ($updateFiles) {
			self::deleteLanguageFiles($this->languageID);
		}
		
		// delete relevant template compilations
		$this->deleteCompiledTemplates();
	}