/** * Imports a set XMLArchive * * @access public * @param string XMLArchive content to import * @param int [ Skin set parent. If omitted, it will be made a root skin ] * @param string [ Images directory to use. If omitted, default skin's image dir is used ] * @param string [ Name of skin to create. If omitted, name from skin set is used ] * @return mixed bool, or number of items added */ public function importSetXMLArchive($content, $parentID = 0, $imageDir = '', $setName = '') { //----------------------------------------- // INIT //----------------------------------------- $templates = array(); $csss = array(); $groups = array(); $defaultSkin = array(); $return = array('replacements' => 0, 'css' => 0, 'templates' => 0); //----------------------------------------- // Got anything? //----------------------------------------- if (!strstr($content, "<xmlarchive")) { $this->_addErrorMessage("The content was not a valid XMLArchive"); return FALSE; } //----------------------------------------- // Make admin group list //----------------------------------------- foreach ($this->caches['group_cache'] as $id => $data) { if ($data['g_access_cp']) { $groups[] = $id; } } //----------------------------------------- // Grab the XMLArchive class //----------------------------------------- require_once IPS_KERNEL_PATH . 'classXMLArchive.php'; $xmlArchive = new classXMLArchive(); $xmlArchive->readXML($content); if (!$xmlArchive->countFileArray()) { $this->_addErrorMessage("The XMLArchive is empty"); return FALSE; } //----------------------------------------- // Gather data //----------------------------------------- /* Info */ $infoXml = $xmlArchive->getFile('info.xml'); if (!$infoXml) { $this->_addErrorMessage("The info.xml file is empty or was not included"); return FALSE; } $info = $this->parseInfoXML($infoXml); /* Replacements */ $replacements = $this->parseReplacementsXML($xmlArchive->getFile('replacements.xml')); /* Templates */ foreach ($xmlArchive->asArray() as $path => $fileData) { if ($fileData['path'] == 'templates' && $fileData['content']) { $templates[str_replace('.xml', '', $fileData['filename'])] = $this->parseTemplatesXML($fileData['content']); } } /* Templates */ foreach ($xmlArchive->asArray() as $path => $fileData) { if ($fileData['path'] == 'css') { $csss[str_replace('.xml', '', $fileData['filename'])] = $this->parseCSSXML($fileData['content']); } } if (!is_array($info)) { $this->_addErrorMessage("The XMLArchive does not contain an info.xml file"); return FALSE; } $info['set_output_format'] = $info['set_output_format'] ? $info['set_output_format'] : 'html'; //----------------------------------------- // Find default skin //----------------------------------------- foreach ($this->registry->output->allSkins as $id => $data) { if ($data['set_is_default'] and $data['set_output_format'] == $info['set_output_format']) { $defaultSkin = $data; break; } } //----------------------------------------- // Build Set Array //----------------------------------------- $newSet = array('set_name' => $setName ? $setName : $info['set_name'] . ' (Import)', 'set_key' => '', 'set_parent_id' => $parentID, 'set_permissions' => implode(",", $groups), 'set_is_default' => 0, 'set_author_name' => $info['set_author_name'], 'set_author_url' => $info['set_author_url'], 'set_image_dir' => $imageDir ? $imageDir : $defaultSkin['set_image_dir'], 'set_emo_dir' => $defaultSkin['set_emo_dir'], 'set_css_inline' => 0, 'set_output_format' => $info['set_output_format'], 'set_css_groups' => '', 'set_hide_from_list' => 1, 'set_updated' => time()); //----------------------------------------- // Insert... //----------------------------------------- $this->DB->insert('skin_collections', $newSet); $setID = $this->DB->getInsertId(); /* Rebuild trees */ $this->rebuildTreeInformation($setID); /* Now re-load to fetch the tree information */ $newSet = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'skin_collections', 'where' => 'set_id=' . $setID)); /* Add to allSkins array for caching functions below */ $newSet['_parentTree'] = unserialize($newSet['set_parent_array']); $newSet['_childTree'] = unserialize($newSet['set_child_array']); $newSet['_userAgents'] = unserialize($newSet['set_locked_uagent']); $newSet['_cssGroupsArray'] = unserialize($newSet['set_css_groups']); $this->registry->output->allSkins[$setID] = $newSet; //----------------------------------------- // Replacements... //----------------------------------------- if (is_array($replacements)) { foreach ($replacements as $replacement) { if ($replacement['replacement_key']) { $return['replacements']++; $this->DB->insert('skin_replacements', array('replacement_key' => $replacement['replacement_key'], 'replacement_content' => $replacement['replacement_content'], 'replacement_set_id' => $setID, 'replacement_added_to' => $setID)); } } } //----------------------------------------- // CSS... //----------------------------------------- /* Fetch master CSS */ $_MASTER = $this->fetchCSS(0); $apps = new IPSApplicationsIterator(); if (is_array($csss)) { foreach ($apps as $app) { $appDir = $apps->fetchAppDir(); if (isset($csss[$appDir]) && is_array($csss[$appDir])) { foreach ($csss[$appDir] as $css) { if ($css['css_group']) { $return['css']++; $this->DB->insert('skin_css', array('css_group' => $css['css_group'], 'css_content' => $css['css_content'], 'css_position' => $css['css_position'], 'css_attributes' => $css['css_attributes'], 'css_app' => $css['css_app'], 'css_app_hide' => $css['css_app_hide'], 'css_modules' => str_replace(' ', '', $css['css_modules']), 'css_updated' => time(), 'css_set_id' => $setID, 'css_added_to' => isset($_MASTER[$css['css_group']]) ? 0 : $setID)); } } } } } //----------------------------------------- // Templates - only import apps we have... //----------------------------------------- /* Fetch all master items */ $_MASTER = $this->fetchTemplates(0, 'allNoContent'); $apps = new IPSApplicationsIterator(); if (is_array($templates)) { foreach ($apps as $app) { $appDir = $apps->fetchAppDir(); if (array_key_exists($appDir, $templates)) { foreach ($templates[$appDir] as $template) { if ($template['template_group'] and $template['template_name']) { /* Figure out if this is added by a user or not */ $isAdded = (is_array($_MASTER[$template['template_group']][strtolower($template['template_name'])]) and !$_MASTER[$template['template_group']][strtolower($template['template_name'])]['template_user_added']) ? 0 : 1; $return['templates']++; $this->DB->insert('skin_templates', array('template_set_id' => $setID, 'template_group' => $template['template_group'], 'template_content' => $template['template_content'], 'template_name' => $template['template_name'], 'template_data' => $template['template_data'], 'template_updated' => $template['template_updated'], 'template_removable' => 1, 'template_user_edited' => 1, 'template_user_added' => $isAdded, 'template_added_to' => $setID)); } } } } } //----------------------------------------- // Re-cache //----------------------------------------- $this->rebuildReplacementsCache($setID); $this->rebuildCSS($setID); $this->rebuildPHPTemplates($setID); $this->rebuildSkinSetsCache(); //----------------------------------------- // Done.... //----------------------------------------- return $return; }
/** * Imports a set XMLArchive * * @access public * @param string XMLArchive content to import * @param int [ Skin set parent. If omitted, it will be made a root skin ] * @param string [ Images directory to use. If omitted, default skin's image dir is used ] * @param string [ Name of skin to create. If omitted, name from skin set is used ] * @param bool [ Whether or not we are attempting to upgrade an existing skin ] * @return mixed bool, or number of items added */ public function importSetXMLArchive($content, $parentID = 0, $imageDir = '', $setName = '', $upgrading = FALSE) { //----------------------------------------- // INIT //----------------------------------------- $templates = array(); $csss = array(); $groups = array(); $defaultSkin = array(); $return = array('replacements' => 0, 'css' => 0, 'templates' => 0, 'upgrade' => FALSE); //----------------------------------------- // Got anything? //----------------------------------------- if (!strstr($content, "<xmlarchive")) { $this->_addErrorMessage($this->lang->words['invalidxmlarchivei']); return FALSE; } //----------------------------------------- // Make admin group list //----------------------------------------- foreach ($this->caches['group_cache'] as $id => $data) { if ($data['g_access_cp']) { $groups[] = $id; } } //----------------------------------------- // Grab the XMLArchive class //----------------------------------------- require_once IPS_KERNEL_PATH . 'classXMLArchive.php'; /*noLibHook*/ $xmlArchive = new classXMLArchive(); $xmlArchive->readXML($content); if (!$xmlArchive->countFileArray()) { $this->_addErrorMessage($this->lang->words['emptyxmlarchivei']); return FALSE; } //----------------------------------------- // Gather data //----------------------------------------- /* Info */ $infoXml = $xmlArchive->getFile('info.xml'); if (!$infoXml) { $this->_addErrorMessage($this->lang->words['noinfoxml']); return FALSE; } $info = $this->parseInfoXML($infoXml); /* Are we attempting to upgrade? */ $setID = 0; $doUpgrade = FALSE; $new_items = array('replacements' => array(), 'css' => array(), 'templates' => array()); if ($info['set_key'] && $upgrading) { foreach ($this->caches['skinsets'] as $set_id => $set_data) { if ($set_data['set_key'] == $info['set_key']) { $setID = $set_id; $doUpgrade = TRUE; $return['upgrade'] = TRUE; break; } } } /* Replacements */ $replacements = $this->parseReplacementsXML($xmlArchive->getFile('replacements.xml')); /* Templates */ foreach ($xmlArchive->asArray() as $path => $fileData) { if ($fileData['path'] == 'templates' && $fileData['content']) { $templates[str_replace('.xml', '', $fileData['filename'])] = $this->parseTemplatesXML($fileData['content']); } } /* Templates */ foreach ($xmlArchive->asArray() as $path => $fileData) { if ($fileData['path'] == 'css') { $csss[str_replace('.xml', '', $fileData['filename'])] = $this->parseCSSXML($fileData['content']); } } if (!is_array($info)) { $this->_addErrorMessage($this->lang->words['noinfoxml']); return FALSE; } $info['set_output_format'] = $info['set_output_format'] ? $info['set_output_format'] : 'html'; //----------------------------------------- // Find default skin //----------------------------------------- foreach ($this->registry->output->allSkins as $id => $data) { if ($data['set_is_default'] and $data['set_output_format'] == $info['set_output_format']) { $defaultSkin = $data; break; } } /* Make sure key in unique */ $test = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'skin_collections', 'where' => 'set_key=\'' . $this->DB->addSlashes($info['set_key']) . '\' AND set_id != ' . intval($setID))); if ($test['set_id']) { $info['set_key'] .= '_' . time(); } //----------------------------------------- // Build Set Array //----------------------------------------- $newSet = array('set_name' => $setName ? $setName : $info['set_name'] . ' (Import)', 'set_key' => $info['set_key'], 'set_parent_id' => $parentID, 'set_permissions' => implode(",", $groups), 'set_is_default' => 0, 'set_author_name' => $info['set_author_name'], 'set_author_url' => $info['set_author_url'], 'set_image_dir' => $imageDir ? $imageDir : $defaultSkin['set_image_dir'], 'set_emo_dir' => $defaultSkin['set_emo_dir'], 'set_css_inline' => 1, 'set_output_format' => $info['set_output_format'], 'set_css_groups' => '', 'set_hide_from_list' => 1, 'set_order' => intval($this->fetchHighestSetPosition()) + 1, 'set_master_key' => isset($info['set_master_key']) ? $info['set_master_key'] : 'root', 'set_updated' => time()); if ($setID) { //----------------------------------------- // Update... //----------------------------------------- $this->DB->update('skin_collections', array('set_author_name' => $info['set_author_name'], 'set_author_url' => $info['set_author_url'], 'set_updated' => time()), 'set_id=' . $setID); } else { //----------------------------------------- // Insert... //----------------------------------------- $this->DB->insert('skin_collections', $newSet); $setID = $this->DB->getInsertId(); } /* Rebuild trees */ $this->rebuildTreeInformation($setID); /* Now re-load to fetch the tree information */ $newSet = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'skin_collections', 'where' => 'set_id=' . $setID)); /* Add to allSkins array for caching functions below */ $newSet['_parentTree'] = unserialize($newSet['set_parent_array']); $newSet['_childTree'] = unserialize($newSet['set_child_array']); $newSet['_userAgents'] = unserialize($newSet['set_locked_uagent']); $newSet['_cssGroupsArray'] = unserialize($newSet['set_css_groups']); $this->registry->output->allSkins[$setID] = $newSet; //----------------------------------------- // Replacements... //----------------------------------------- if (is_array($replacements)) { foreach ($replacements as $replacement) { if ($replacement['replacement_key']) { $return['replacements']++; $existing_id = 0; /* Check if we need to update or insert */ if ($doUpgrade) { $exists = $this->DB->buildAndFetch(array('select' => 'replacement_id', 'from' => 'skin_replacements', 'where' => "replacement_key='{$replacement['replacement_key']}' AND replacement_set_id={$setID} AND replacement_added_to={$setID}")); $existing_id = $exists['replacement_id']; } if ($existing_id) { $new_items['replacements'][] = $existing_id; $this->DB->update('skin_replacements', array('replacement_content' => $replacement['replacement_content']), "replacement_id=" . $existing_id); } else { $this->DB->insert('skin_replacements', array('replacement_key' => $replacement['replacement_key'], 'replacement_content' => $replacement['replacement_content'], 'replacement_set_id' => $setID, 'replacement_added_to' => $setID)); } } } } //----------------------------------------- // CSS... //----------------------------------------- /* Fetch master CSS */ $_MASTER = $this->fetchCSS(0); if (is_array($csss)) { foreach (ipsRegistry::$applications as $appDir => $data) { if (isset($csss[$appDir]) && is_array($csss[$appDir])) { foreach ($csss[$appDir] as $css) { if ($css['css_group']) { $return['css']++; $existing_id = 0; /* Check if we need to update or insert */ if ($doUpgrade) { $exists = $this->DB->buildAndFetch(array('select' => 'css_id', 'from' => 'skin_css', 'where' => "css_group='{$css['css_group']}' AND css_app='{$css['css_app']}' AND css_set_id={$setID}")); $existing_id = $exists['css_id']; } if ($existing_id) { $new_items['css'][] = $existing_id; $this->DB->update('skin_css', array('css_content' => $css['css_content'], 'css_position' => $css['css_position'], 'css_attributes' => $css['css_attributes'], 'css_app_hide' => $css['css_app_hide'], 'css_modules' => str_replace(' ', '', $css['css_modules']), 'css_updated' => time(), 'css_added_to' => isset($_MASTER[$css['css_group']]) ? 0 : $setID), "css_id=" . $existing_id); } else { $this->DB->insert('skin_css', array('css_group' => $css['css_group'], 'css_content' => $css['css_content'], 'css_position' => $css['css_position'], 'css_attributes' => $css['css_attributes'], 'css_app' => $css['css_app'], 'css_app_hide' => $css['css_app_hide'], 'css_modules' => str_replace(' ', '', $css['css_modules']), 'css_updated' => time(), 'css_set_id' => $setID, 'css_added_to' => isset($_MASTER[$css['css_group']]) ? 0 : $setID)); } } } } } } //----------------------------------------- // Templates - only import apps we have... //----------------------------------------- /* Fetch all master items */ $_MASTER = $this->fetchTemplates(0, 'allNoContent'); if (is_array($templates)) { foreach (ipsRegistry::$applications as $appDir => $data) { if (array_key_exists($appDir, $templates)) { foreach ($templates[$appDir] as $template) { if ($template['template_group'] and $template['template_name']) { /* Figure out if this is added by a user or not */ $isAdded = (is_array($_MASTER[$template['template_group']][strtolower($template['template_name'])]) and !$_MASTER[$template['template_group']][strtolower($template['template_name'])]['template_user_added']) ? 0 : 1; $return['templates']++; $existing_id = 0; /* Check if we need to update or insert */ if ($doUpgrade) { $exists = $this->DB->buildAndFetch(array('select' => 'template_id', 'from' => 'skin_templates', 'where' => "template_set_id={$setID} AND template_group='{$template['template_group']}' AND template_name='{$template['template_name']}'")); $existing_id = $exists['template_id']; } if ($existing_id) { $new_items['templates'][] = $existing_id; $this->DB->update('skin_templates', array('template_content' => $template['template_content'], 'template_data' => $template['template_data'], 'template_updated' => $template['template_updated'] ? $template['template_updated'] : IPS_UNIX_TIME_NOW, 'template_removable' => 1, 'template_user_edited' => 1, 'template_user_added' => $isAdded, 'template_added_to' => $setID), "template_id=" . $existing_id); } else { $this->DB->insert('skin_templates', array('template_set_id' => $setID, 'template_group' => $template['template_group'], 'template_content' => $template['template_content'], 'template_name' => $template['template_name'], 'template_data' => $template['template_data'], 'template_updated' => $template['template_updated'] ? $template['template_updated'] : IPS_UNIX_TIME_NOW, 'template_removable' => 1, 'template_user_edited' => 1, 'template_user_added' => $isAdded, 'template_added_to' => $setID)); } } } } } } //----------------------------------------- // If upgrading, and there are items from an old // skin not in the new one, delete the old elements // This probably won't ever come up, but I'm anal retentive :P //----------------------------------------- if ($doUpgrade) { if (count($new_items['replacements'])) { $this->DB->delete('skin_replacements', "replacement_set_id={$setID} AND replacement_id NOT IN (" . implode(',', $new_items['replacements']) . ")"); } if (count($new_items['css'])) { $this->DB->delete('skin_css', "css_set_id={$setID} AND css_id NOT IN (" . implode(',', $new_items['css']) . ")"); } if (count($new_items['templates'])) { $this->DB->delete('skin_templates', "template_set_id={$setID} AND template_id NOT IN (" . implode(',', $new_items['templates']) . ")"); } } //----------------------------------------- // Re-cache //----------------------------------------- $this->rebuildReplacementsCache($setID); $this->rebuildCSS($setID); $this->rebuildPHPTemplates($setID); $this->rebuildSkinSetsCache(); //----------------------------------------- // Done.... //----------------------------------------- return $return; }