/**
  * Installs scm.
  *
  * @see	AbstractXMLPackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     $scmXML = $xml->getElementTree('data');
     foreach ($scmXML['children'] as $key => $block) {
         if (!empty($block['children'])) {
             switch ($block['name']) {
                 // install (or update existing) scm
                 case 'import':
                     foreach ($block['children'] as $scm) {
                         foreach ($scm['children'] as $child) {
                             // continue with next children if current tree is empty
                             if (!isset($child['cdata'])) {
                                 continue;
                             }
                             $scm[$child['name']] = $child['cdata'];
                         }
                         // break operation if we encounter missing attribute
                         if (!isset($scm['attrs']['name'])) {
                             throw new SystemException('Required "name" attribute for scm item tag is missing.');
                         }
                         $scmName = $scm['attrs']['name'];
                         // insert into db
                         $sql = "INSERT INTO\twcf" . WCF_N . "_" . $this->tableName . "\r\n\t\t\t\t\t\t\t\t\t   \t(packageID, scm)\r\n\t\t\t\t\t\t\t\tVALUES\t\t(" . $this->installation->getPackageID() . ", '" . strtolower($scmName) . "')\r\n\t\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE scm = VALUES(scm)";
                         WCF::getDB()->sendQuery($sql);
                         // clear cache
                         SCMHelper::clearCache();
                     }
                     break;
                     // delete scm
                 // delete scm
                 case 'delete':
                     if ($package->getAction() == 'update') {
                         $itemNames = '';
                         foreach ($block['children'] as $scm) {
                             if (!isset($scm['attrs']['name'])) {
                                 throw new SystemException('Required "name" attribute for scm tag is missing.');
                             }
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($scm['attrs']['name']) . "'";
                         }
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_" . $this->tableName . "\r\n\t\t\t\t\t\t\t \t\tWHERE\t\tscm IN (" . $itemNames . ")\r\n\t\t\t\t\t\t\t\t\t\t&&\tpackageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                             // clear cache
                             SCMHelper::clearCache();
                         }
                     }
                     break;
             }
         }
     }
 }
 /**
  * Returns true if the uninstalling package got to uninstall languages, categories or items.
  * 
  * @return 	boolean 			hasUnistall
  */
 public function hasUninstall()
 {
     if (parent::hasUninstall()) {
         return true;
     }
     $sql = "SELECT\tCOUNT(languageID) as count\n\t\t\tFROM\twcf" . WCF_N . "_language_to_packages\n\t\t\tWHERE\tpackageID = " . $this->installation->getPackageID();
     $languageCount = WCF::getDB()->getFirstRow($sql);
     return $languageCount['count'] > 0;
 }
 /**
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $xmlContent = $xml->getElementTree('data');
     // Loop through the array and install or uninstall items.
     foreach ($xmlContent['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $item) {
                     // Extract item properties.
                     foreach ($item['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $item[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($item['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for smiley tag is missing.", 13023);
                     }
                     // default values
                     $title = $path = '';
                     $showOrder = null;
                     // get values
                     $name = $item['attrs']['name'];
                     if (isset($item['title'])) {
                         $title = $item['title'];
                     }
                     if (isset($item['path'])) {
                         $path = $item['path'];
                     }
                     if (isset($item['showorder'])) {
                         $showOrder = intval($item['showorder']);
                     }
                     $showOrder = $this->getShowOrder($showOrder);
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_smiley\n\t\t\t\t\t\t\t\t\t\t\t(packageID, smileyPath, smileyTitle, smileyCode, showOrder)\n\t\t\t\t\t\t\tVALUES\t\t\t\t(" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($path) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($title) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($name) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $showOrder . ")\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tsmileyPath = VALUES(smileyPath),\n\t\t\t\t\t\t\t\t\t\t\tsmileyTitle = VALUES(smileyTitle),\n\t\t\t\t\t\t\t\t\t\t\tshowOrder = VALUES(showOrder)";
                     WCF::getDB()->sendQuery($sql);
                 }
             }
         }
     }
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     $xml = $this->getXML();
     $availableFiles = $this->getAvailableFiles();
     if (!$xml) {
         return;
     }
     $xml = $xml->getElementTree('data');
     foreach ($xml['children'] as $key => $block) {
         if (count($block['children'])) {
             if ($block['name'] === 'delete') {
                 if ($this->installation->getAction() === 'update') {
                     $files = array();
                     foreach ($block['children'] as $fileInfo) {
                         if (!isset($fileInfo['attrs']['name'])) {
                             throw new SystemException("Required 'name' attribute for 'file'-tag is missing.");
                         }
                         if (!in_array($fileInfo['attrs']['name'], $availableFiles)) {
                             throw new SystemException('A package can delete its own files only');
                         }
                         $files[] = $fileInfo['attrs']['name'];
                     }
                     if (count($files)) {
                         $fileNamesStr = "'" . implode("','", array_map('escapeString', $files)) . "'";
                         $sql = "DELETE FROM\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t\t\t\t\tWHERE\t\tfilename IN (" . $fileNamesStr . ")\n\t\t\t\t\t\t\t\t\t\tAND packageID = " . $this->installation->getPackageID();
                         WCF::getDB()->sendQuery($sql);
                         $this->deleteFiles($files);
                     }
                 } else {
                     throw new SystemException('Files can be deleted during update only');
                 }
             }
         }
     }
 }
 /** 
  * Deletes languages, categories or items which where installed by the package.
  */
 public function uninstall()
 {
     parent::uninstall();
     // delete language to package relation
     $sql = "DELETE FROM\twcf" . WCF_N . "_language_to_packages\n\t\t\tWHERE\t\tpackageID = " . $this->installation->getPackageID();
     WCF::getDB()->sendQuery($sql);
     // delete language items
     // Get all items and their categories
     // which where installed from this package.
     $sql = "SELECT\tlanguageItemID, languageCategoryID, languageID\n\t\t\tFROM\twcf" . WCF_N . "_language_item\n\t\t\tWHERE\tpackageID = " . $this->installation->getPackageID();
     $result = WCF::getDB()->sendQuery($sql);
     $itemIDs = array();
     $categoryIDs = array();
     while ($row = WCF::getDB()->fetchArray($result)) {
         $itemIDs[] = $row['languageItemID'];
         // Store categories
         $categoryIDs[$row['languageCategoryID']] = true;
     }
     if (count($itemIDs) > 0) {
         $sql = "DELETE\tFROM wcf" . WCF_N . "_language_item\n\t\t\t\tWHERE\tlanguageItemID IN (" . implode(", ", $itemIDs) . ")\n\t\t\t\tAND\tpackageID = " . $this->installation->getPackageID();
         WCF::getDB()->sendQuery($sql);
         $this->deleteEmptyCategories(array_keys($categoryIDs), $this->installation->getPackageID());
     }
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $acpMenuXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall acp-menu items.
     foreach ($acpMenuXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through acp-menu items and create or update them.
                 foreach ($block['children'] as $acpMenuItem) {
                     // Extract item properties.
                     foreach ($acpMenuItem['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $acpMenuItem[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($acpMenuItem['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for 'menu item'-tag is missing.", 13023);
                     }
                     // default values
                     $menuItemLink = $parentMenuItem = $menuItemIcon = $permissions = $options = '';
                     $showOrder = null;
                     // make xml tags-names (keys in array) to lower case
                     $this->keysToLowerCase($acpMenuItem);
                     // get values
                     $menuItem = $acpMenuItem['attrs']['name'];
                     if (isset($acpMenuItem['link'])) {
                         $menuItemLink = $acpMenuItem['link'];
                     }
                     if (isset($acpMenuItem['parent'])) {
                         $parentMenuItem = $acpMenuItem['parent'];
                     }
                     if (isset($acpMenuItem['icon'])) {
                         $menuItemIcon = $acpMenuItem['icon'];
                     }
                     if (!empty($acpMenuItem['showorder'])) {
                         $showOrder = intval($acpMenuItem['showorder']);
                     }
                     $showOrder = $this->getShowOrder($showOrder, $parentMenuItem, 'parentMenuItem');
                     if (isset($acpMenuItem['permissions'])) {
                         $permissions = $acpMenuItem['permissions'];
                     }
                     if (isset($acpMenuItem['options'])) {
                         $options = $acpMenuItem['options'];
                     }
                     // If a parent link was set and this parent is not in database
                     // or it is a link from a package from other package environment: don't install further.
                     if (!empty($parentMenuItem)) {
                         $sql = "SELECT\tCOUNT(menuItemID) as count\n\t\t\t\t\t\t\t\tFROM \twcf" . WCF_N . "_acp_menu_item\n\t\t\t\t\t\t\t\tWHERE\tmenuItem = '" . escapeString($parentMenuItem) . "'";
                         $menuItemCount = WCF::getDB()->getFirstRow($sql);
                         if ($menuItemCount['count'] == 0) {
                             throw new SystemException("Unable to find parent 'menu item' with name '" . $parentMenuItem . "' for 'menu item' with name '" . $menuItem . "'.", 13011);
                         }
                     }
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_acp_menu_item\n\t\t\t\t\t\t\t\t\t\t\t(packageID, menuItem, parentMenuItem, menuItemLink, menuItemIcon, showOrder, permissions, options)\n\t\t\t\t\t\t\tVALUES\t\t\t\t(" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItem) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($parentMenuItem) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItemLink) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItemIcon) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $showOrder . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($permissions) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($options) . "')\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tparentMenuItem = VALUES(parentMenuItem),\n\t\t\t\t\t\t\t\t\t\t\tmenuItemLink = VALUES(menuItemLink),\n\t\t\t\t\t\t\t\t\t\t\tmenuItemIcon = VALUES(menuItemIcon),\n\t\t\t\t\t\t\t\t\t\t\tshowOrder = VALUES(showOrder),\n\t\t\t\t\t\t\t\t\t\t\tpermissions = VALUES(permissions),\n\t\t\t\t\t\t\t\t\t\t\toptions = VALUES(options)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through acp-menu items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $acpMenuItem) {
                             // check required attributes
                             if (!isset($acpMenuItem['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for '" . $acpMenuItem['name'] . "'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma seperated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($acpMenuItem['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_acp_menu_item\n\t\t\t\t\t\t\t\tWHERE\t\tmenuItem IN (" . $itemNames . ")\n\t\t\t\t\t\t\t\t\t\tAND packageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $headerMenuXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall items.
     foreach ($headerMenuXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $headerMenuItem) {
                     // Extract item properties.
                     foreach ($headerMenuItem['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $headerMenuItem[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($headerMenuItem['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for page menu item tag is missing.", 13023);
                     }
                     // default values
                     $menuItemLink = $menuItemIconS = $menuItemIconM = $permissions = $options = '';
                     $menuPosition = 'header';
                     $showOrder = null;
                     // get values
                     $menuItem = $headerMenuItem['attrs']['name'];
                     if (isset($headerMenuItem['link'])) {
                         $menuItemLink = $headerMenuItem['link'];
                     }
                     if (isset($headerMenuItem['icon'])) {
                         $menuItemIconM = $headerMenuItem['icon'];
                     }
                     // wcf1.0 fallback
                     if (isset($headerMenuItem['iconmedium'])) {
                         $menuItemIconM = $headerMenuItem['iconmedium'];
                     }
                     if (isset($headerMenuItem['iconsmall'])) {
                         $menuItemIconS = $headerMenuItem['iconsmall'];
                     }
                     if (isset($headerMenuItem['showorder'])) {
                         $showOrder = intval($headerMenuItem['showorder']);
                     }
                     $showOrder = $this->getShowOrder($showOrder);
                     if (isset($headerMenuItem['permissions'])) {
                         $permissions = $headerMenuItem['permissions'];
                     }
                     if (isset($headerMenuItem['options'])) {
                         $options = $headerMenuItem['options'];
                     }
                     if (isset($headerMenuItem['position'])) {
                         $menuPosition = $headerMenuItem['position'];
                     }
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_page_menu_item\n\t\t\t\t\t\t\t\t\t\t\t(packageID, menuItem, menuItemLink, menuItemIconS, menuItemIconM, showOrder, permissions, options, menuPosition)\n\t\t\t\t\t\t\tVALUES\t\t\t\t(" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItem) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItemLink) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItemIconS) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuItemIconM) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $showOrder . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($permissions) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($options) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($menuPosition) . "')\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tmenuItemLink = VALUES(menuItemLink),\n\t\t\t\t\t\t\t\t\t\t\tmenuItemIconS = VALUES(menuItemIconS),\n\t\t\t\t\t\t\t\t\t\t\tmenuItemIconM = VALUES(menuItemIconM),\n\t\t\t\t\t\t\t\t\t\t\tshowOrder = VALUES(showOrder),\n\t\t\t\t\t\t\t\t\t\t\tpermissions = VALUES(permissions),\n\t\t\t\t\t\t\t\t\t\t\toptions = VALUES(options),\n\t\t\t\t\t\t\t\t\t\t\tmenuPosition = VALUES(menuPosition)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $menuItem) {
                             // check required attributes
                             if (!isset($menuItem['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for page menu item tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($menuItem['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_page_menu_item\n\t\t\t\t\t\t\t\tWHERE\t\tpackageID = " . $this->installation->getPackageID() . "\n\t\t\t\t\t\t\t\t\t\tAND menuItem IN (" . $itemNames . ")";
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * @see	 PackageInstallationPlugin::uninstall()
  */
 public function uninstall()
 {
     parent::uninstall();
     // clear cache immediately
     require_once WCF_DIR . 'lib/data/dynamic/page/module/template/DynamicPageModuleTemplateEditor.class.php';
     DynamicPageModuleTemplateEditor::clearCache();
 }
 /**
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $feedSourceXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall items.
     foreach ($feedSourceXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $feedSourceItem) {
                     // Extract item properties.
                     foreach ($feedSourceItem['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $feedSourceItem[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($feedSourceItem['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for feed source item tag is missing.", 13023);
                     }
                     // default values
                     $sourceURL = $updateCycle = '';
                     // get values
                     $sourceName = $feedSourceItem['attrs']['name'];
                     if (isset($feedSourceItem['url'])) {
                         $sourceURL = $feedSourceItem['url'];
                     }
                     if (isset($feedSourceItem['cycle'])) {
                         $updateCycle = $feedSourceItem['cycle'];
                     }
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_feed_source\n\t\t\t\t\t\t\t\t\t\t\t(packageID, sourceName, sourceURL, updateCycle)\n\t\t\t\t\t\t\tVALUES\t\t\t\t(" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($sourceName) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($sourceURL) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($updateCycle) . "')\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tsourceURL = VALUES(sourceURL),\n\t\t\t\t\t\t\t\t\t\t\tupdateCycle = VALUES(updateCycle)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $sourceItem) {
                             // check required attributes
                             if (!isset($sourceItem['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for feed source item tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma sparated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($sourceItem['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_feed_source\n\t\t\t\t\t\t\t\tWHERE\t\tpackageID = " . $this->installation->getPackageID() . "\n\t\t\t\t\t\t\t\t\t\tAND sourceName IN (" . $itemNames . ")";
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $xml = $xml->getElementTree('data');
     require_once WCF_DIR . 'lib/data/cronjobs/CronjobEditor.class.php';
     // Loop through the array and install or uninstall cronjobs.
     foreach ($xml['children'] as $key => $block) {
         if (count($block['children'])) {
             // TODO: handle delete block first
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $cronjobInfo) {
                     // Extract item properties.
                     foreach ($cronjobInfo['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $cronjobInfo[$child['name']] = $child['cdata'];
                     }
                     // default values.
                     $classPath = $description = $startMinute = $startHour = $startDom = $startMonth = $startDow = '';
                     $execMultiple = $canBeEdited = $canBeDisabled = 0;
                     $active = 1;
                     // make xml tags-names (keys in array) to lower case
                     $this->keysToLowerCase($cronjobInfo);
                     // get values.
                     if (isset($cronjobInfo['classpath'])) {
                         $classPath = $cronjobInfo['classpath'];
                     }
                     if (isset($cronjobInfo['description'])) {
                         $description = $cronjobInfo['description'];
                     }
                     if (isset($cronjobInfo['startminute'])) {
                         $startMinute = $cronjobInfo['startminute'];
                     }
                     if (isset($cronjobInfo['starthour'])) {
                         $startHour = $cronjobInfo['starthour'];
                     }
                     if (isset($cronjobInfo['startdom'])) {
                         $startDom = $cronjobInfo['startdom'];
                     }
                     if (isset($cronjobInfo['startmonth'])) {
                         $startMonth = $cronjobInfo['startmonth'];
                     }
                     if (isset($cronjobInfo['startdow'])) {
                         $startDow = $cronjobInfo['startdow'];
                     }
                     if (isset($cronjobInfo['execmultiple'])) {
                         $execMultiple = intval($cronjobInfo['execmultiple']);
                     }
                     if (isset($cronjobInfo['active'])) {
                         $active = intval($cronjobInfo['active']);
                     }
                     if (isset($cronjobInfo['canbeedited'])) {
                         $canBeEdited = intval($cronjobInfo['canbeedited']);
                     }
                     if (isset($cronjobInfo['canbedisabled'])) {
                         $canBeDisabled = intval($cronjobInfo['canbedisabled']);
                     }
                     // validate values
                     CronjobEditor::validate($startMinute, $startHour, $startDom, $startMonth, $startDow);
                     // save cronjob
                     $sql = "INSERT INTO\twcf" . WCF_N . "_cronjobs \n\t\t\t\t\t\t\t\t\t(classPath, packageID, description, \n\t\t\t\t\t\t\t\t\tstartMinute, startHour, startDom, \n\t\t\t\t\t\t\t\t\tstartMonth, startDow, nextExec, execMultiple, \n\t\t\t\t\t\t\t\t\tactive, canBeEdited, canBeDisabled) \n\t\t\t\t\t\t\tVALUES \n\t\t\t\t\t\t\t\t\t('" . escapeString($classPath) . "', \n\t\t\t\t\t\t\t\t\t" . $this->installation->getPackageID() . ", \n\t\t\t\t\t\t\t\t\t'" . escapeString($description) . "', \n\t\t\t\t\t\t\t\t\t'" . escapeString($startMinute) . "', \n\t\t\t\t\t\t\t\t\t'" . escapeString($startHour) . "', \n\t\t\t\t\t\t\t\t\t'" . escapeString($startDom) . "', \n\t\t\t\t\t\t\t\t\t'" . escapeString($startMonth) . "', \n\t\t\t\t\t\t\t\t\t'" . escapeString($startDow) . "', \n\t\t\t\t\t\t\t\t\t" . TIME_NOW . ", \n\t\t\t\t\t\t\t\t\t" . escapeString($execMultiple) . ",\n\t\t\t\t\t\t\t\t\t" . escapeString($active) . ",\n\t\t\t\t\t\t\t\t\t" . escapeString($canBeEdited) . ", \n\t\t\t\t\t\t\t\t\t" . escapeString($canBeDisabled) . ")";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through items and delete them.
                         $cronjobNames = '';
                         foreach ($block['children'] as $cronjobInfo) {
                             // check required attributes
                             if (!isset($cronjobInfo['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for 'cronjob'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($cronjobNames)) {
                                 $cronjobNames .= ',';
                             }
                             $cronjobNames .= "'" . escapeString($cronjobInfo['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($cronjobNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_cronjobs\n\t\t\t\t\t\t\t\tWHERE\t\tclassPath IN (" . $cronjobNames . ")\n\t\t\t\t\t\t\t\t\t\tAND packageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * @see PackageInstallationPlugin::uninstall()
  */
 public function uninstall()
 {
     // delete attributes
     $sql = "DELETE FROM\twcf" . WCF_N . "_bbcode_attribute\n\t\t\tWHERE\t\tbbcodeID IN (\n\t\t\t\t\t\tSELECT\tbbcodeID\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_bbcode\n\t\t\t\t\t\tWHERE\tpackageID = " . $this->installation->getPackageID() . "\n\t\t\t\t\t)";
     WCF::getDB()->sendQuery($sql);
     parent::uninstall();
 }
 /**
  * Uninstalls option categories and options.
  */
 public function uninstall()
 {
     // delete options
     parent::uninstall();
     // delete categories
     $sql = "DELETE FROM\twcf" . WCF_N . "_" . $this->tableName . "_category\n\t\t\tWHERE\t\tpackageID = " . $this->installation->getpackageID();
     WCF::getDB()->sendQuery($sql);
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $suspensionTypeXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall items.
     foreach ($suspensionTypeXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $suspensionType) {
                     // Extract item properties.
                     foreach ($suspensionType['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $suspensionType[$child['name']] = $child['cdata'];
                     }
                     // default values
                     $name = $classFile = '';
                     // get values
                     if (isset($suspensionType['name'])) {
                         $name = $suspensionType['name'];
                     }
                     if (isset($suspensionType['classfile'])) {
                         $classFile = $suspensionType['classfile'];
                     }
                     // insert items
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_user_infraction_suspension_type\r\n\t\t\t\t\t\t\t\t\t\t\t(packageID, suspensionType, classFile)\r\n\t\t\t\t\t\t\tVALUES\t\t\t\t(" . $this->installation->getPackageID() . ",\r\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($name) . "',\r\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($classFile) . "')\r\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tclassFile = VALUES(classFile)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete' && $this->installation->getAction() == 'update') {
                     // Loop through items and delete them.
                     $nameArray = array();
                     foreach ($block['children'] as $suspensionType) {
                         // Extract item properties.
                         foreach ($suspensionType['children'] as $child) {
                             if (!isset($child['cdata'])) {
                                 continue;
                             }
                             $suspensionType[$child['name']] = $child['cdata'];
                         }
                         if (empty($suspensionType['name'])) {
                             throw new SystemException("Required 'name' attribute for suspension type is missing", 13023);
                         }
                         $nameArray[] = $suspensionType['name'];
                     }
                     if (count($nameArray)) {
                         $sql = "DELETE FROM\twcf" . WCF_N . "_user_infraction_suspension_type\r\n\t\t\t\t\t\t\tWHERE\t\tpackageID = " . $this->installation->getPackageID() . "\n\t\t\t\t\t\t\t\t\tAND suspensionType IN ('" . implode("','", array_map('escapeString', $nameArray)) . "')";
                         WCF::getDB()->sendQuery($sql);
                     }
                 }
             }
         }
     }
 }
 /**
  * @see	 PackageInstallationPlugin::uninstall()
  */
 public function uninstall()
 {
     parent::uninstall();
     $this->updateStyleFiles();
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $acpMenuXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall acp-menu items.
     foreach ($acpMenuXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through acp-menu items and create or update them.
                 foreach ($block['children'] as $acpMenuItem) {
                     // Extract item properties.
                     foreach ($acpMenuItem['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $acpMenuItem[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($acpMenuItem['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for statistic type is missing", 13023);
                     }
                     if (!isset($acpMenuItem['tablename'])) {
                         throw new SystemException("Required 'tablename' attribute for statistic type is missing", 13023);
                     }
                     if (!isset($acpMenuItem['datefieldname'])) {
                         throw new SystemException("Required 'datefieldname' attribute for statistic type is missing", 13023);
                     }
                     // default values
                     $userFieldName = '';
                     // get values
                     $name = $acpMenuItem['attrs']['name'];
                     $tableName = $acpMenuItem['tablename'];
                     $dateFieldName = $acpMenuItem['datefieldname'];
                     if (isset($acpMenuItem['userfieldname'])) {
                         $userFieldName = $acpMenuItem['userfieldname'];
                     }
                     // fix table name
                     $standalonePackage = $this->installation->getPackage();
                     if ($standalonePackage->getParentPackageID()) {
                         // package is a plugin; get parent package
                         $standalonePackage = $standalonePackage->getParentPackage();
                     }
                     if ($standalonePackage->isStandalone() == 1) {
                         // package is standalone
                         $packageAbbr = $standalonePackage->getAbbreviation();
                         $tablePrefix = WCF_N . '_' . $standalonePackage->getInstanceNo() . '_';
                         // Replace the variable xyz1_1 with $tablePrefix in the table names.
                         $tableName = str_replace($packageAbbr . '1_1_', $packageAbbr . $tablePrefix, $tableName);
                     }
                     // replace wcf1_ with the actual WCF_N value
                     $tableName = str_replace("wcf1_", "wcf" . WCF_N . "_", $tableName);
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_stat_type\n\t\t\t\t\t\t\t\t\t\t\t(typeName, packageID, tableName, dateFieldName, userFieldName)\n\t\t\t\t\t\t\tVALUES\t\t\t\t('" . escapeString($name) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($tableName) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($dateFieldName) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($userFieldName) . "')\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \ttableName = VALUES(tableName),\n\t\t\t\t\t\t\t\t\t\t\tdateFieldName = VALUES(dateFieldName),\n\t\t\t\t\t\t\t\t\t\t\tuserFieldName = VALUES(userFieldName)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through acp-menu items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $acpMenuItem) {
                             // check required attributes
                             if (!isset($acpMenuItem['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for 'stattype'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($acpMenuItem['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_stat_type\n\t\t\t\t\t\t\t\tWHERE\t\tpackageID = " . $this->installation->getPackageID() . "\n\t\t\t\t\t\t\t\t\t\tAND typeName IN (" . $itemNames . ")";
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $xml = $xml->getElementTree('data');
     // Loop through the array and install or uninstall acp-menu items.
     foreach ($xml['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $taggable) {
                     // Extract item properties.
                     foreach ($taggable['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $taggable[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($taggable['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for 'taggable'-tag is missing.", 13023);
                     }
                     // default values
                     $typeName = $classPath = '';
                     // get values
                     $typeName = $taggable['attrs']['name'];
                     if (isset($taggable['classpath'])) {
                         $classPath = $taggable['classpath'];
                     }
                     // check if the taggable exist already and was installed by this package
                     $sql = "SELECT\ttaggableID\n\t\t\t\t\t\t\tFROM \twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t\t\t\tWHERE \tname = '" . escapeString($typeName) . "'\n\t\t\t\t\t\t\tAND\tpackageID = " . $this->installation->getPackageID();
                     $row = WCF::getDB()->getFirstRow($sql);
                     if (empty($row['taggableID'])) {
                         $sql = "INSERT INTO\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t\t\t\t\t\t\t(packageID, name, classPath)\n\t\t\t\t\t\t\t\tVALUES\t\t(" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t'" . escapeString($typeName) . "',\n\t\t\t\t\t\t\t\t\t\t'" . escapeString($classPath) . "')";
                         WCF::getDB()->sendQuery($sql);
                     } else {
                         $sql = "UPDATE  wcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t\t\t\t\tSET\tclassPath = '" . escapeString($classPath) . "'\n\t\t\t\t\t\t\t\tWHERE\ttaggableID = " . $row['taggableID'];
                         WCF::getDB()->sendQuery($sql);
                     }
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $taggable) {
                             // check required attributes
                             if (!isset($taggable['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for 'taggable'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($taggable['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t\t\t\t\tWHERE\t\tname IN (" . $itemNames . ")\n\t\t\t\t\t\t\t\tAND \t\tpackageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * 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);
                     }
                 }
             }
         }
     }
 }
 /**
  * @see	 PackageInstallationPlugin::uninstall()
  */
 public function uninstall()
 {
     parent::uninstall();
     // clear cache immediately
     WCF::getCache()->clear(WCF_DIR . 'cache', 'cache.eventListener-*.php');
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $xml = $xml->getElementTree('data');
     // Loop through the array and install or uninstall acp-menu items.
     foreach ($xml['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through items and create or update them.
                 foreach ($block['children'] as $containerType) {
                     // Extract item properties.
                     foreach ($containerType['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $containerType[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($containerType['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for 'act'-tag is missing.", 13023);
                     }
                     // default values
                     $typeName = $url = '';
                     $isPrivate = 0;
                     // get values
                     $typeName = $containerType['attrs']['name'];
                     if (isset($containerType['url'])) {
                         $url = $containerType['url'];
                     }
                     if (isset($containerType['private'])) {
                         $isPrivate = intval($containerType['private']);
                     }
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_attachment_container_type\n\t\t\t\t\t\t\t\t\t\t\t(containerType, isPrivate, url, packageID)\n\t\t\t\t\t\t\tVALUES\t\t\t\t('" . escapeString($typeName) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $isPrivate . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($url) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $this->installation->getPackageID() . ")\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tisPrivate = VALUES(isPrivate),\n\t\t\t\t\t\t\t\t\t\t\turl = VALUES(url)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $containerType) {
                             // check required attributes
                             if (!isset($containerType['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for 'act'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($containerType['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_attachment_container_type\n\t\t\t\t\t\t\t\tWHERE\t\tcontainerType IN (" . $itemNames . ")\n\t\t\t\t\t\t\t\t\t\tAND packageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }
 /** 
  * @see PackageInstallationPlugin::install()
  */
 public function install()
 {
     parent::install();
     if (!($xml = $this->getXML())) {
         return;
     }
     // Create an array with the data blocks (import or delete) from the xml file.
     $acpMenuXML = $xml->getElementTree('data');
     // Loop through the array and install or uninstall acp-menu items.
     foreach ($acpMenuXML['children'] as $key => $block) {
         if (count($block['children'])) {
             // Handle the import instructions
             if ($block['name'] == 'import') {
                 // Loop through acp-menu items and create or update them.
                 foreach ($block['children'] as $acpMenuItem) {
                     // Extract item properties.
                     foreach ($acpMenuItem['children'] as $child) {
                         if (!isset($child['cdata'])) {
                             continue;
                         }
                         $acpMenuItem[$child['name']] = $child['cdata'];
                     }
                     // check required attributes
                     if (!isset($acpMenuItem['attrs']['name'])) {
                         throw new SystemException("Required 'name' attribute for page location is missing", 13023);
                     }
                     if (!isset($acpMenuItem['pattern'])) {
                         throw new SystemException("Required 'pattern' attribute for page location is missing", 13023);
                     }
                     // default values
                     $classPath = '';
                     // get values
                     $name = $acpMenuItem['attrs']['name'];
                     $pattern = $acpMenuItem['pattern'];
                     if (isset($acpMenuItem['classpath'])) {
                         $classPath = $acpMenuItem['classpath'];
                     }
                     // Insert or update items.
                     // Update through the mysql "ON DUPLICATE KEY"-syntax.
                     $sql = "INSERT INTO\t\t\twcf" . WCF_N . "_page_location\n\t\t\t\t\t\t\t\t\t\t\t(locationName, locationPattern, packageID, classPath)\n\t\t\t\t\t\t\tVALUES\t\t\t\t('" . escapeString($name) . "',\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($pattern) . "',\n\t\t\t\t\t\t\t\t\t\t\t" . $this->installation->getPackageID() . ",\n\t\t\t\t\t\t\t\t\t\t\t'" . escapeString($classPath) . "')\n\t\t\t\t\t\t\tON DUPLICATE KEY UPDATE \tlocationPattern = VALUES(locationPattern),\n\t\t\t\t\t\t\t\t\t\t\tclassPath = VALUES(classPath)";
                     WCF::getDB()->sendQuery($sql);
                 }
             } else {
                 if ($block['name'] == 'delete') {
                     if ($this->installation->getAction() == 'update') {
                         // Loop through acp-menu items and delete them.
                         $itemNames = '';
                         foreach ($block['children'] as $acpMenuItem) {
                             // check required attributes
                             if (!isset($acpMenuItem['attrs']['name'])) {
                                 throw new SystemException("Required 'name' attribute for 'pagelocation'-tag is missing.", 13023);
                             }
                             // Create a string with all item names which should be deleted (comma separated).
                             if (!empty($itemNames)) {
                                 $itemNames .= ',';
                             }
                             $itemNames .= "'" . escapeString($acpMenuItem['attrs']['name']) . "'";
                         }
                         // Delete items.
                         if (!empty($itemNames)) {
                             $sql = "DELETE FROM\twcf" . WCF_N . "_page_location\n\t\t\t\t\t\t\t\tWHERE\t\tlocationName IN (" . $itemNames . ")\n\t\t\t\t\t\t\t\t\t\tAND packageID = " . $this->installation->getPackageID();
                             WCF::getDB()->sendQuery($sql);
                         }
                     }
                 }
             }
         }
     }
 }