/**
  * Export language entries to xml file
  *
  * @param	integer	$lang_id	Language pack to export
  * @param	bool	$disk		Save to disk instead
  * @return void
  */
 public function languageExportToXML($lang_id, $disk = false)
 {
     //-----------------------------------------
     // Init
     //-----------------------------------------
     $app_dir = trim($this->request['app_dir']);
     $type = trim($this->request['type']);
     $_where = '';
     $_name = 'language.xml';
     $LATESTVERSION = IPSLib::fetchVersionNumber();
     $doPack = true;
     //-----------------------------------------
     // Filter
     //-----------------------------------------
     if ($app_dir) {
         $_where = " AND word_app='" . $app_dir . "'";
         $_name = $app_dir . '_language_pack.xml';
         $doPack = false;
     }
     if ($type) {
         if ($type == 'admin') {
             $_where .= " AND word_pack LIKE 'admin_%'";
             $_name = 'admin_' . $_name;
         } else {
             $_where .= " AND word_pack LIKE 'public_%'";
             $_name = 'public_' . $_name;
         }
         $doPack = false;
     }
     //-----------------------------------------
     // Create the XML library
     //-----------------------------------------
     require_once IPS_KERNEL_PATH . 'classXML.php';
     /*noLibHook*/
     $xml = new classXML(IPS_DOC_CHAR_SET);
     $xml->newXMLDocument();
     $xml->addElement('languageexport');
     $xml->addElement('languagegroup', 'languageexport');
     //-----------------------------------------
     // Get language pack
     //-----------------------------------------
     $data = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'core_sys_lang', 'where' => "lang_id={$lang_id}"));
     //-----------------------------------------
     // Add pack if necessary
     //-----------------------------------------
     if ($doPack) {
         $xml->addElementAsRecord('languagegroup', 'langinfo', $data);
     }
     //-----------------------------------------
     // Get the words
     //-----------------------------------------
     $this->DB->build(array('select' => '*', 'from' => 'core_sys_lang_words', 'where' => "lang_id={$lang_id}" . $_where));
     $this->DB->execute();
     //-----------------------------------------
     // Add words to export
     //-----------------------------------------
     $word_packs = array();
     $_strings = 0;
     while ($r = $this->DB->fetch()) {
         $content = array();
         $_strings++;
         if ($disk) {
             $content = array('word_app' => $r['word_app'], 'word_pack' => $r['word_pack'], 'word_key' => $r['word_key'], 'word_default' => $r['word_default']);
             if ($r['word_js']) {
                 $content['word_js'] = $r['word_js'];
             }
         } else {
             $content = array('word_app' => $r['word_app'], 'word_pack' => $r['word_pack'], 'word_key' => $r['word_key'], 'word_default' => $r['word_default'], 'word_custom' => $r['word_custom'], 'word_default_version' => $r['word_default_version'] >= 30000 ? $r['word_default_version'] : $LATESTVERSION['long'], 'word_custom_version' => $r['word_custom_version'], 'word_js' => $r['word_js']);
         }
         $xml->addElementAsRecord('languagegroup', 'lang', $content);
     }
     //-----------------------------------------
     // Got any strings?
     //-----------------------------------------
     if (!$_strings) {
         if ($disk) {
             return false;
         } else {
             $this->registry->output->global_message = $this->lang->words['l_nolangbits'];
             $this->languagesList();
             return;
         }
     }
     //-----------------------------------------
     // Write to disk or output to browser
     //-----------------------------------------
     if ($disk) {
         @unlink(IPSLib::getAppDir($app_dir) . '/xml/' . $_name);
         @file_put_contents(IPSLib::getAppDir($app_dir) . '/xml/' . $_name, $xml->fetchDocument());
         return true;
     } else {
         //-----------------------------------------
         // Create xml archive
         //-----------------------------------------
         require_once IPS_KERNEL_PATH . 'classXMLArchive.php';
         /*noLibHook*/
         $xmlArchive = new classXMLArchive();
         //-----------------------------------------
         // Add XML document
         //-----------------------------------------
         $xmlArchive->add($xml->fetchDocument(), 'language_entries.xml');
         //-----------------------------------------
         // Print to browser
         //-----------------------------------------
         $this->registry->output->showDownload($xmlArchive->getArchiveContents(), $_name);
         exit;
     }
 }
 /**
  * Export the specified emoticon directory
  *
  * @return	@e void
  */
 public function emoticonsPackExport()
 {
     /* Setup XML */
     require_once IPS_KERNEL_PATH . 'classXML.php';
     /*noLibHook*/
     $xml = new classXML(IPS_DOC_CHAR_SET);
     require_once IPS_KERNEL_PATH . 'classXMLArchive.php';
     /*noLibHook*/
     $xmlarchive = new classXMLArchive();
     /* Check the emoticon set */
     if (!$this->request['emo_set']) {
         $this->registry->output->global_message = $this->lang->words['emo_specify_exS'];
         $this->emoticonsOverview();
         return;
     }
     /* Get emoticons from the database */
     $emo_db = array();
     $this->DB->build(array('select' => '*', 'from' => 'emoticons', 'where' => "emo_set='{$this->request['emo_set']}'"));
     $this->DB->execute();
     while ($r = $this->DB->fetch()) {
         $emo_db[$r['image']] = $r;
     }
     /* Get Emoticon Folders */
     $emodirs = array();
     $emodd = array();
     $files_to_add = array();
     try {
         foreach (new DirectoryIterator(DOC_IPS_ROOT_PATH . PUBLIC_DIRECTORY . '/style_emoticons/' . $this->request['emo_set']) as $file) {
             if (!$file->isDot()) {
                 if ($emo_db[$file->getFilename()] != "") {
                     $files_to_add[] = DOC_IPS_ROOT_PATH . PUBLIC_DIRECTORY . '/style_emoticons/' . $this->request['emo_set'] . '/' . $file->getFilename();
                 }
             }
         }
     } catch (Exception $e) {
     }
     /* Add each file to the xml archive */
     foreach ($files_to_add as $f) {
         $xmlarchive->add($f);
     }
     $xml->newXMLDocument();
     $xml->addElement('emoticonexport');
     $xml->addElement('emogroup', 'emoticonexport');
     foreach ($emo_db as $r) {
         $content = array();
         $content['typed'] = $r['typed'];
         $content['image'] = $r['image'];
         $content['clickable'] = $r['clickable'];
         $xml->addElementAsRecord('emogroup', 'emoticon', $content);
     }
     /* Create the XML Document */
     $xmlData = $xml->fetchDocument();
     /* Add the xml document to the archive */
     $xmlarchive->add($xmlData, 'emoticon_data.xml');
     /* Send the archive to the browser */
     $imagearchive = $xmlarchive->getArchiveContents();
     $this->registry->output->showDownload($imagearchive, 'ipb_emoticons.xml');
 }
 /**
  * Generate XML Archive for skin set
  *
  * @access	public
  * @param	int			Skin set ID
  * @param	boolean		Modifications in this set only
  * @param	array		[Array of apps to export from. Default is all]
  * @return	string		XML
  */
 public function generateSetXMLArchive($setID = 0, $setOnly = FALSE, $appslimit = null)
 {
     //-----------------------------------------
     // INIT
     //-----------------------------------------
     $templates = array();
     $csss = array();
     $replacements = "";
     $css = "";
     $setData = $this->fetchSkinData($setID);
     //-----------------------------------------
     // Reset handlers
     //-----------------------------------------
     $this->_resetErrorHandle();
     $this->_resetMessageHandle();
     //-----------------------------------------
     // First up... fetch templates
     //-----------------------------------------
     $apps = new IPSApplicationsIterator();
     foreach ($apps as $app) {
         if (is_array($appslimit) and !in_array($apps->fetchAppDir(), $appslimit)) {
             continue;
         }
         if ($apps->isActive()) {
             $templates[$apps->fetchAppDir()] = $this->generateTemplateXML($apps->fetchAppDir(), $setID, $setOnly);
             $csss[$apps->fetchAppDir()] = $this->generateCSSXML($apps->fetchAppDir(), $setID, $setOnly);
         }
     }
     //-----------------------------------------
     // Replacements
     //-----------------------------------------
     $replacements = $this->generateReplacementsXML($setID, $setOnly);
     //-----------------------------------------
     // Information
     //-----------------------------------------
     $info = $this->generateInfoXML($setID);
     //-----------------------------------------
     // De-bug
     //-----------------------------------------
     foreach ($templates as $app_dir => $templateXML) {
         IPSDebug::addLogMessage("Template Export: {$app_dir}\n" . $templateXML, 'admin-setExport');
     }
     foreach ($csss as $app_dir => $cssXML) {
         IPSDebug::addLogMessage("CSS Export: {$app_dir}\n" . $cssXML, 'admin-setExport');
     }
     IPSDebug::addLogMessage("Replacements Export:\n" . $replacements, 'admin-setExport');
     IPSDebug::addLogMessage("Info Export:\n" . $info, 'admin-setExport');
     //-----------------------------------------
     // Create new XML archive...
     //-----------------------------------------
     require_once IPS_KERNEL_PATH . 'classXMLArchive.php';
     $xmlArchive = new classXMLArchive();
     # Templates
     foreach ($templates as $app_dir => $templateXML) {
         $xmlArchive->add($templateXML, "templates/" . $app_dir . ".xml");
     }
     # CSS
     foreach ($csss as $app_dir => $cssXML) {
         $xmlArchive->add($cssXML, "css/" . $app_dir . ".xml");
     }
     # Replacements
     $xmlArchive->add($replacements, "replacements.xml");
     # Information
     $xmlArchive->add($info, 'info.xml');
     return $xmlArchive->getArchiveContents();
 }
 /**
  * Imports a set XMLArchive
  *
  * @access	public
  * @param	string		XMLArchive content to import
  * @return	mixed		Number of items added, or bool
  */
 public function importXmlArchive($content)
 {
     /* Correct file type ? */
     if (!strstr($content, "<xmlarchive")) {
         return false;
     }
     /* Get XML class */
     require_once IPS_KERNEL_PATH . 'classXMLArchive.php';
     /*noLibHook*/
     $xmlArchive = new classXMLArchive();
     $xmlArchive->readXML($content);
     /* Got stuff? */
     if (!$xmlArchive->countFileArray()) {
         return false;
     }
     /* Write it */
     if ($xmlArchive->write($content, $this->getImageDir()) === FALSE) {
         return false;
     }
     /* Check images */
     $errors = $this->checkImages();
     if ($errors['missing'] !== false or $errors['dimensions'] !== false or $errors['writeable'] !== false) {
         return false;
     }
     /* Push changes to the app */
     $this->setStyleLastUpdated(time());
     return true;
 }
 /**
  * Create new session
  *
  * @access	public
  * @param	string		Diff session title
  * @param	string		Compare HTML
  * @param	boolean		Ignore new bits
  * @return	int			New session ID
  */
 public function createSession($title, $content, $ignoreBits = FALSE)
 {
     //-----------------------------------------
     // INIT
     //-----------------------------------------
     $templateBits = array();
     //-----------------------------------------
     // Get number for missing template bits
     //-----------------------------------------
     $_bits = $this->DB->buildAndFetch(array('select' => 'COUNT(*) as count', 'from' => 'skin_templates', 'where' => 'template_set_id=0'));
     //-----------------------------------------
     // Create session
     //-----------------------------------------
     $this->DB->allow_sub_select = 1;
     $this->DB->insert('template_diff_session', array('diff_session_togo' => intval($_bits['count']), 'diff_session_done' => 0, 'diff_session_title' => $title, 'diff_session_updated' => time(), 'diff_session_ignore_missing' => $ignoreBits === TRUE ? 1 : 0));
     $diffSesssionID = $this->DB->getInsertId();
     //-----------------------------------------
     // XML
     //-----------------------------------------
     require_once IPS_KERNEL_PATH . 'classXML.php';
     $xml = new classXML(IPS_DOC_CHAR_SET);
     //-----------------------------------------
     // Check to see if its an archive...
     //-----------------------------------------
     if (strstr($content, "<xmlarchive")) {
         /* It's an archive... */
         require IPS_KERNEL_PATH . 'classXMLArchive.php';
         $xmlArchive = new classXMLArchive(IPS_KERNEL_PATH);
         $xmlArchive->readXML($content);
         /* We just want the templates.. */
         foreach ($xmlArchive->asArray() as $path => $fileData) {
             if ($fileData['path'] == 'templates') {
                 $xml->loadXML($fileData['content']);
                 foreach ($xml->fetchElements('template') as $xmlelement) {
                     $data = $xml->fetchElementsFromRecord($xmlelement);
                     if (is_array($data)) {
                         $templateBits[] = $data;
                     }
                 }
             }
         }
     } else {
         $xml->loadXML($content);
         foreach ($xml->fetchElements('template') as $xmlelement) {
             $data = $xml->fetchElementsFromRecord($xmlelement);
             if (is_array($data)) {
                 $templateBits[] = $data;
             }
         }
     }
     //-----------------------------------------
     // Got anything?
     //-----------------------------------------
     if (!count($templateBits)) {
         return FALSE;
     }
     //-----------------------------------------
     // Build session data
     //-----------------------------------------
     foreach ($templateBits as $bit) {
         $diffKey = $diffSesssionID . ':' . $bit['template_group'] . ':' . $bit['template_name'];
         if (!$seen[$diffKey]) {
             $this->DB->allow_sub_select = 1;
             $this->DB->insert('templates_diff_import', array('diff_key' => $diffKey, 'diff_func_group' => $bit['template_group'], 'diff_func_data' => $bit['template_data'], 'diff_func_name' => $bit['template_name'], 'diff_func_content' => $bit['template_content'], 'diff_session_id' => $diffSesssionID));
             $seen[$diffKey] = 1;
         }
     }
     return $diffSesssionID;
 }
 /**
  * Generate XML Archive for skin set
  *
  * @access	public
  * @param	int			Skin set ID
  * @param	boolean		Modifications in this set only
  * @param	array		[Array of apps to export from. Default is all]
  * @return	string		XML
  */
 public function generateSetXMLArchive($setID = 0, $setOnly = FALSE, $appslimit = null)
 {
     //-----------------------------------------
     // INIT
     //-----------------------------------------
     $templates = array();
     $csss = array();
     $replacements = "";
     $css = "";
     $setData = $this->fetchSkinData($setID);
     //-----------------------------------------
     // Reset handlers
     //-----------------------------------------
     $this->_resetErrorHandle();
     $this->_resetMessageHandle();
     //-----------------------------------------
     // First up... fetch templates
     //-----------------------------------------
     foreach (ipsRegistry::$applications as $appDir => $data) {
         if (is_array($appslimit) and !in_array($appDir, $appslimit)) {
             continue;
         }
         if (!empty($data['app_enabled'])) {
             $templates[$appDir] = $this->generateTemplateXML($appDir, $setID, $setOnly);
             $csss[$appDir] = $this->generateCSSXML($appDir, $setID, $setOnly);
         }
     }
     //-----------------------------------------
     // Replacements
     //-----------------------------------------
     $replacements = $this->generateReplacementsXML($setID, $setOnly);
     //-----------------------------------------
     // Information
     //-----------------------------------------
     $info = $this->generateInfoXML($setID);
     //-----------------------------------------
     // De-bug
     //-----------------------------------------
     foreach ($templates as $app_dir => $templateXML) {
         IPSDebug::addLogMessage("Template Export: {$app_dir}\n" . $templateXML, 'admin-setExport', false, true, true);
     }
     foreach ($csss as $app_dir => $cssXML) {
         IPSDebug::addLogMessage("CSS Export: {$app_dir}\n" . $cssXML, 'admin-setExport', false, true);
     }
     IPSDebug::addLogMessage("Replacements Export:\n" . $replacements, 'admin-setExport', false, true);
     IPSDebug::addLogMessage("Info Export:\n" . $info, 'admin-setExport', false, true);
     //-----------------------------------------
     // Create new XML archive...
     //-----------------------------------------
     require_once IPS_KERNEL_PATH . 'classXMLArchive.php';
     /*noLibHook*/
     $xmlArchive = new classXMLArchive();
     /* Add in version numbers */
     $version = IPSLib::fetchVersionNumber();
     $xmlArchive->addRootTagValues(array('ipbLongVersion' => $version['long'], 'ipbHumanVersion' => $version['human']));
     # Templates
     foreach ($templates as $app_dir => $templateXML) {
         $xmlArchive->add($templateXML, "templates/" . $app_dir . ".xml");
     }
     # CSS
     foreach ($csss as $app_dir => $cssXML) {
         $xmlArchive->add($cssXML, "css/" . $app_dir . ".xml");
     }
     # Replacements
     $xmlArchive->add($replacements, "replacements.xml");
     # Information
     $xmlArchive->add($info, 'info.xml');
     return $xmlArchive->getArchiveContents();
 }