-<?php\r
-/**\r
- * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
- * Copyright (C) 2002-2004 The Nucleus Group\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- * (see nucleus/documentation/index.html#license for more info)\r
- *\r
- * This class contains two classes that can be used for importing and \r
- * exporting Nucleus skins: SKINIMPORT and SKINEXPORT\r
- */\r
-\r
-class SKINIMPORT {\r
-\r
- // hardcoded value (see constructor). When 1, interesting info about the\r
- // parsing process is sent to the output\r
- var $debug;\r
- \r
- // parser/file pointer\r
- var $parser;\r
- var $fp;\r
- \r
- // which data has been read?\r
- var $metaDataRead;\r
- var $allRead; \r
- \r
- // extracted data\r
- var $skins;\r
- var $templates;\r
- var $info;\r
- \r
- // to maintain track of where we are inside the XML file\r
- var $inXml;\r
- var $inData;\r
- var $inMeta;\r
- var $inSkin;\r
- var $inTemplate;\r
- var $currentName;\r
- var $currentPartName;\r
- var $cdata; \r
- \r
- \r
- \r
- /**\r
- * constructor initializes data structures\r
- */\r
- function SKINIMPORT() {\r
- // disable magic_quotes_runtime if it's turned on\r
- set_magic_quotes_runtime(0);\r
- \r
- // debugging mode?\r
- $this->debug = 0;\r
- \r
- $this->reset();\r
- \r
- }\r
- \r
- function reset() {\r
- if ($this->parser)\r
- xml_parser_free($this->parser);\r
- \r
- // XML file pointer\r
- $this->fp = 0; \r
- \r
- // which data has been read?\r
- $this->metaDataRead = 0;\r
- $this->allRead = 0;\r
-\r
- // to maintain track of where we are inside the XML file\r
- $this->inXml = 0;\r
- $this->inData = 0;\r
- $this->inMeta = 0;\r
- $this->inSkin = 0;\r
- $this->inTemplate = 0;\r
- $this->currentName = '';\r
- $this->currentPartName = '';\r
- \r
- // character data pile\r
- $this->cdata = '';\r
- \r
- // list of skinnames and templatenames (will be array of array)\r
- $this->skins = array();\r
- $this->templates = array();\r
- \r
- // extra info included in the XML files (e.g. installation notes)\r
- $this->info = '';\r
- \r
- // init XML parser\r
- $this->parser = xml_parser_create();\r
- xml_set_object($this->parser, $this);\r
- xml_set_element_handler($this->parser, 'startElement', 'endElement');\r
- xml_set_character_data_handler($this->parser, 'characterData');\r
- xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);\r
-\r
- } \r
- \r
- /**\r
- * Reads an XML file into memory\r
- *\r
- * @param $filename\r
- * Which file to read\r
- * @param $metaOnly\r
- * Set to 1 when only the metadata needs to be read (optional, default 0)\r
- */\r
- function readFile($filename, $metaOnly = 0) {\r
- // open file\r
- $this->fp = @fopen($filename, 'r');\r
- if (!$this->fp) return 'Failed to open file/URL';\r
-\r
- // here we go!\r
- $this->inXml = 1;\r
-\r
- while (!feof($this->fp)) {\r
- $tempbuffer .= fread($this->fp, 4096);\r
- }\r
- fclose($this->fp);\r
-\r
-/*\r
- [2004-08-04] dekarma - Took this out since it messes up good XML if it has skins/templates\r
- with CDATA sections. need to investigate consequences.\r
- see bug [ 999914 ] Import fails (multiple skins in XML/one of them with CDATA)\r
- \r
- // backwards compatibility with the non-wellformed skinbackup.xml files\r
- // generated by v2/v3 (when CDATA sections were present in skins)\r
- // split up those CDATA sections into multiple ones\r
- $tempbuffer = preg_replace_callback(\r
- "/(<!\[CDATA\[[^]]*?<!\[CDATA\[[^]]*)((?:\]\].*?<!\[CDATA.*?)*)(\]\])(.*\]\])/ms",\r
- create_function(\r
- '$matches',\r
- 'return $matches[1] . preg_replace("/(\]\])(.*?<!\[CDATA)/ms","]]]]><![CDATA[$2",$matches[2])."]]]]><![CDATA[".$matches[4];'\r
- ),\r
- $tempbuffer\r
- ); \r
-*/\r
- $temp = tmpfile();\r
- fwrite($temp, $tempbuffer);\r
- rewind($temp);\r
-\r
- while ( ($buffer = fread($temp, 4096) ) && (!$metaOnly || ($metaOnly && !$this->metaDataRead))) {\r
- $err = xml_parse( $this->parser, $buffer, feof($temp) );\r
- if (!$err && $this->debug)\r
- echo 'ERROR: ', xml_error_string(xml_get_error_code($this->parser)), '<br />';\r
- }\r
-\r
- // all done\r
- $this->inXml = 0;\r
- fclose($temp);\r
- } \r
- \r
- /**\r
- * Returns the list of skin names\r
- */\r
- function getSkinNames() {\r
- return array_keys($this->skins);\r
- }\r
-\r
- /**\r
- * Returns the list of template names\r
- */\r
- function getTemplateNames() {\r
- return array_keys($this->templates);\r
- } \r
- \r
- /**\r
- * Returns the extra information included in the XML file\r
- */\r
- function getInfo() {\r
- return $this->info;\r
- }\r
- \r
- /**\r
- * Writes the skins and templates to the database \r
- *\r
- * @param $allowOverwrite\r
- * set to 1 when allowed to overwrite existing skins with the same name\r
- * (default = 0)\r
- */\r
- function writeToDatabase($allowOverwrite = 0) {\r
- $existingSkins = $this->checkSkinNameClashes();\r
- $existingTemplates = $this->checkTemplateNameClashes();\r
- \r
- // if not allowed to overwrite, check if any nameclashes exists\r
- if (!$allowOverwrite) {\r
- if ((sizeof($existingSkins) > 0) || (sizeof($existingTemplates) > 0))\r
- return 'Name clashes detected, re-run with allowOverwrite = 1 to force overwrite';\r
- }\r
- \r
- foreach ($this->skins as $skinName => $data) {\r
- // 1. if exists: delete all part data, update desc data\r
- // if not exists: create desc\r
- if (in_array($skinName, $existingSkins)) {\r
- $skinObj = SKIN::createFromName($skinName);\r
- \r
- // delete all parts of the skin\r
- $skinObj->deleteAllParts();\r
- \r
- // update general info\r
- $skinObj->updateGeneralInfo($skinName, $data['description'], $data['type'], $data['includeMode'], $data['includePrefix']);\r
- } else {\r
- $skinid = SKIN::createNew($skinName, $data['description'], $data['type'], $data['includeMode'], $data['includePrefix']);\r
- $skinObj = new SKIN($skinid);\r
- }\r
- \r
- // 2. add parts\r
- foreach ($data['parts'] as $partName => $partContent) {\r
- $skinObj->update($partName, $partContent);\r
- }\r
- }\r
- \r
- foreach ($this->templates as $templateName => $data) {\r
- // 1. if exists: delete all part data, update desc data\r
- // if not exists: create desc\r
- if (in_array($templateName, $existingTemplates)) {\r
- $templateObj = TEMPLATE::createFromName($templateName);\r
- \r
- // delete all parts of the template\r
- $templateObj->deleteAllParts();\r
- \r
- // update general info\r
- $templateObj->updateGeneralInfo($templateName, $data['description']);\r
- } else {\r
- $templateid = TEMPLATE::createNew($templateName, $data['description']);\r
- $templateObj = new TEMPLATE($templateid);\r
- }\r
- \r
- // 2. add parts\r
- foreach ($data['parts'] as $partName => $partContent) {\r
- $templateObj->update($partName, $partContent);\r
- } \r
- }\r
- \r
- \r
- }\r
- \r
- /**\r
- * returns an array of all the skin nameclashes (empty array when no name clashes)\r
- */\r
- function checkSkinNameClashes() {\r
- $clashes = array();\r
- \r
- foreach ($this->skins as $skinName => $data) {\r
- if (SKIN::exists($skinName))\r
- array_push($clashes, $skinName);\r
- }\r
- \r
- return $clashes;\r
- }\r
- \r
- /**\r
- * returns an array of all the template nameclashes \r
- * (empty array when no name clashes)\r
- */\r
- function checkTemplateNameClashes() {\r
- $clashes = array();\r
- \r
- foreach ($this->templates as $templateName => $data) {\r
- if (TEMPLATE::exists($templateName))\r
- array_push($clashes, $templateName);\r
- }\r
- \r
- return $clashes;\r
- }\r
- \r
- /**\r
- * Called by XML parser for each new start element encountered\r
- */\r
- function startElement($parser, $name, $attrs) {\r
- if ($this->debug) echo 'START: ', $name, '<br />';\r
- \r
- switch ($name) {\r
- case 'nucleusskin':\r
- $this->inData = 1;\r
- break;\r
- case 'meta':\r
- $this->inMeta = 1;\r
- break;\r
- case 'info':\r
- // no action needed\r
- break;\r
- case 'skin':\r
- if (!$this->inMeta) {\r
- $this->inSkin = 1;\r
- $this->currentName = $attrs['name'];\r
- $this->skins[$this->currentName]['type'] = $attrs['type'];\r
- $this->skins[$this->currentName]['includeMode'] = $attrs['includeMode'];\r
- $this->skins[$this->currentName]['includePrefix'] = $attrs['includePrefix']; \r
- $this->skins[$this->currentName]['parts'] = array(); \r
- } else {\r
- $this->skins[$attrs['name']] = array(); \r
- $this->skins[$attrs['name']]['parts'] = array(); \r
- }\r
- break;\r
- case 'template':\r
- if (!$this->inMeta) {\r
- $this->inTemplate = 1;\r
- $this->currentName = $attrs['name'];\r
- $this->templates[$this->currentName]['parts'] = array(); \r
- } else {\r
- $this->templates[$attrs['name']] = array(); \r
- $this->templates[$attrs['name']]['parts'] = array(); \r
- }\r
- break;\r
- case 'description':\r
- // no action needed\r
- break;\r
- case 'part':\r
- $this->currentPartName = $attrs['name'];\r
- break;\r
- default:\r
- echo 'UNEXPECTED TAG: ' , $name , '<br />';\r
- break;\r
- }\r
- \r
- // character data never contains other tags\r
- $this->clearCharacterData(); \r
- \r
- }\r
-\r
- /**\r
- * Called by the XML parser for each closing tag encountered\r
- */\r
- function endElement($parser, $name) {\r
- if ($this->debug) echo 'END: ', $name, '<br />';\r
- \r
- switch ($name) {\r
- case 'nucleusskin':\r
- $this->inData = 0;\r
- $this->allRead = 1;\r
- break;\r
- case 'meta':\r
- $this->inMeta = 0;\r
- $this->metaDataRead = 1;\r
- break;\r
- case 'info':\r
- $this->info = $this->getCharacterData();\r
- case 'skin':\r
- if (!$this->inMeta) $this->inSkin = 0;\r
- break;\r
- case 'template':\r
- if (!$this->inMeta) $this->inTemplate = 0; \r
- break;\r
- case 'description':\r
- if ($this->inSkin) {\r
- $this->skins[$this->currentName]['description'] = $this->getCharacterData();\r
- } else {\r
- $this->templates[$this->currentName]['description'] = $this->getCharacterData(); \r
- }\r
- break;\r
- case 'part':\r
- if ($this->inSkin) {\r
- $this->skins[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();\r
- } else {\r
- $this->templates[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData(); \r
- }\r
- break;\r
- default:\r
- echo 'UNEXPECTED TAG: ' , $name, '<br />';\r
- break;\r
- }\r
- $this->clearCharacterData();\r
-\r
- }\r
- \r
- /**\r
- * Called by XML parser for data inside elements\r
- */\r
- function characterData ($parser, $data) {\r
- if ($this->debug) echo 'NEW DATA: ', htmlspecialchars($data), '<br />';\r
- $this->cdata .= $data;\r
- }\r
- \r
- /**\r
- * Returns the data collected so far\r
- */\r
- function getCharacterData() {\r
- return $this->cdata;\r
- }\r
- \r
- /**\r
- * Clears the data buffer\r
- */\r
- function clearCharacterData() {\r
- $this->cdata = '';\r
- }\r
- \r
- /**\r
- * Static method that looks for importable XML files in subdirs of the given dir\r
- */\r
- function searchForCandidates($dir) {\r
- $candidates = array();\r
-\r
- $dirhandle = opendir($dir);\r
- while ($filename = readdir($dirhandle)) {\r
- if (@is_dir($dir . $filename) && ($filename != '.') && ($filename != '..')) {\r
- $xml_file = $dir . $filename . '/skinbackup.xml';\r
- if (file_exists($xml_file) && is_readable($xml_file)) {\r
- $candidates[$filename] = $filename; //$xml_file;\r
- } \r
-\r
- // backwards compatibility \r
- $xml_file = $dir . $filename . '/skindata.xml';\r
- if (file_exists($xml_file) && is_readable($xml_file)) {\r
- $candidates[$filename] = $filename; //$xml_file;\r
- } \r
- }\r
- }\r
- closedir($dirhandle);\r
- \r
- return $candidates;\r
- \r
- }\r
- \r
- \r
-}\r
-\r
-\r
-class SKINEXPORT {\r
-\r
- var $templates;\r
- var $skins;\r
- var $info;\r
- \r
- /**\r
- * Constructor initializes data structures\r
- */\r
- function SKINEXPORT() {\r
- // list of templateIDs to export\r
- $this->templates = array();\r
- \r
- // list of skinIDs to export\r
- $this->skins = array();\r
- \r
- // extra info to be in XML file\r
- $this->info = '';\r
- }\r
- \r
- /**\r
- * Adds a template to be exported\r
- *\r
- * @param id\r
- * template ID\r
- * @result false when no such ID exists\r
- */\r
- function addTemplate($id) {\r
- if (!TEMPLATE::existsID($id)) return 0;\r
- \r
- $this->templates[$id] = TEMPLATE::getNameFromId($id);\r
- \r
- return 1;\r
- }\r
- \r
- /**\r
- * Adds a skin to be exported\r
- *\r
- * @param id \r
- * skin ID\r
- * @result false when no such ID exists\r
- */ \r
- function addSkin($id) {\r
- if (!SKIN::existsID($id)) return 0;\r
- \r
- $this->skins[$id] = SKIN::getNameFromId($id);\r
- \r
- return 1;\r
- }\r
- \r
- /**\r
- * Sets the extra info to be included in the exported file\r
- */\r
- function setInfo($info) {\r
- $this->info = $info;\r
- }\r
- \r
- \r
- /**\r
- * Outputs the XML contents of the export file\r
- *\r
- * @param $setHeaders\r
- * set to 0 if you don't want to send out headers\r
- * (optional, default 1)\r
- */\r
- function export($setHeaders = 1) {\r
- if ($setHeaders) {\r
- // make sure the mimetype is correct, and that the data does not show up \r
- // in the browser, but gets saved into and XML file (popup download window)\r
- header('Content-Type: text/xml');\r
- header('Content-Disposition: attachment; filename="skinbackup.xml"');\r
- header('Expires: 0');\r
- header('Pragma: no-cache');\r
- }\r
- \r
- echo "<nucleusskin>\n";\r
- \r
- // meta\r
- echo "\t<meta>\n";\r
- // skins\r
- foreach ($this->skins as $skinId => $skinName) {\r
- echo "\t\t", '<skin name="',htmlspecialchars($skinName),'" />',"\n";\r
- }\r
- // templates\r
- foreach ($this->templates as $templateId => $templateName) {\r
- echo "\t\t", '<template name="',htmlspecialchars($templateName),'" />',"\n";\r
- }\r
- // extra info\r
- if ($this->info)\r
- echo "\t\t<info><![CDATA[",$this->info,"]]></info>\n";\r
- echo "\t</meta>\n\n\n";\r
- \r
- // contents skins\r
- foreach ($this->skins as $skinId => $skinName) {\r
- $skinId = intval($skinId);\r
- $skinObj = new SKIN($skinId);\r
- \r
- echo "\t", '<skin name="',htmlspecialchars($skinName),'" type="',htmlspecialchars($skinObj->getContentType()),'" includeMode="',htmlspecialchars($skinObj->getIncludeMode()),'" includePrefix="',htmlspecialchars($skinObj->getIncludePrefix()),'">',"\n";\r
- \r
- echo "\t\t", '<description>',htmlspecialchars($skinObj->getDescription()),'</description>',"\n";\r
- \r
- $res = sql_query('SELECT stype, scontent FROM '.sql_table('skin').' WHERE sdesc='.$skinId);\r
- while ($partObj = mysql_fetch_object($res)) {\r
- echo "\t\t",'<part name="',htmlspecialchars($partObj->stype),'">';\r
- echo '<![CDATA[', $this->escapeCDATA($partObj->scontent),']]>';\r
- echo "</part>\n\n";\r
- }\r
- \r
- echo "\t</skin>\n\n\n";\r
- }\r
- \r
- // contents templates\r
- foreach ($this->templates as $templateId => $templateName) {\r
- $templateId = intval($templateId);\r
- \r
- echo "\t",'<template name="',htmlspecialchars($templateName),'">',"\n";\r
- \r
- echo "\t\t",'<description>',htmlspecialchars(TEMPLATE::getDesc($templateId)),'</description>',"\n"; \r
- \r
- $res = sql_query('SELECT tpartname, tcontent FROM '.sql_table('template').' WHERE tdesc='.$templateId);\r
- while ($partObj = mysql_fetch_object($res)) {\r
- echo "\t\t",'<part name="',htmlspecialchars($partObj->tpartname),'">';\r
- echo '<![CDATA[', $this->escapeCDATA($partObj->tcontent) ,']]>';\r
- echo '</part>',"\n\n";\r
- }\r
- \r
- echo "\t</template>\n\n\n";\r
- } \r
- \r
- echo '</nucleusskin>';\r
- }\r
- \r
- /**\r
- * Escapes CDATA content so it can be included in another CDATA section\r
- */\r
- function escapeCDATA($cdata)\r
- {\r
- return preg_replace('/]]>/', ']]]]><![CDATA[>', $cdata);\r
- \r
- }\r
-}\r
-\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2010 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * This class contains two classes that can be used for importing and
+ * exporting Nucleus skins: SKINIMPORT and SKINEXPORT
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2010 The Nucleus Group
+ * @version $Id$
+ * @version $NucleusJP: skinie.php,v 1.9.2.1 2007/09/05 07:46:30 kimitake Exp $
+ */
+
+class SKINIMPORT {
+
+ // hardcoded value (see constructor). When 1, interesting info about the
+ // parsing process is sent to the output
+ var $debug;
+
+ // parser/file pointer
+ var $parser;
+ var $fp;
+
+ // which data has been read?
+ var $metaDataRead;
+ var $allRead;
+
+ // extracted data
+ var $skins;
+ var $templates;
+ var $info;
+
+ // to maintain track of where we are inside the XML file
+ var $inXml;
+ var $inData;
+ var $inMeta;
+ var $inSkin;
+ var $inTemplate;
+ var $currentName;
+ var $currentPartName;
+ var $cdata;
+
+
+
+ /**
+ * constructor initializes data structures
+ */
+ function SKINIMPORT() {
+ // disable magic_quotes_runtime if it's turned on
+ set_magic_quotes_runtime(0);
+
+ // debugging mode?
+ $this->debug = 0;
+
+ $this->reset();
+
+ }
+
+ function reset() {
+ if ($this->parser)
+ xml_parser_free($this->parser);
+
+ // XML file pointer
+ $this->fp = 0;
+
+ // which data has been read?
+ $this->metaDataRead = 0;
+ $this->allRead = 0;
+
+ // to maintain track of where we are inside the XML file
+ $this->inXml = 0;
+ $this->inData = 0;
+ $this->inMeta = 0;
+ $this->inSkin = 0;
+ $this->inTemplate = 0;
+ $this->currentName = '';
+ $this->currentPartName = '';
+
+ // character data pile
+ $this->cdata = '';
+
+ // list of skinnames and templatenames (will be array of array)
+ $this->skins = array();
+ $this->templates = array();
+
+ // extra info included in the XML files (e.g. installation notes)
+ $this->info = '';
+
+ // init XML parser
+ $this->parser = xml_parser_create();
+ xml_set_object($this->parser, $this);
+ xml_set_element_handler($this->parser, 'startElement', 'endElement');
+ xml_set_character_data_handler($this->parser, 'characterData');
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+
+ }
+
+ /**
+ * Reads an XML file into memory
+ *
+ * @param $filename
+ * Which file to read
+ * @param $metaOnly
+ * Set to 1 when only the metadata needs to be read (optional, default 0)
+ */
+ function readFile($filename, $metaOnly = 0) {
+ // open file
+ $this->fp = @fopen($filename, 'r');
+ if (!$this->fp) {
+ return _SKINIE_ERROR_FAILEDOPEN_FILEURL;
+ }
+
+ // here we go!
+ $this->inXml = 1;
+
+ $tempbuffer = null;
+
+ while (!feof($this->fp)) {
+ $tempbuffer .= fread($this->fp, 4096);
+ }
+ fclose($this->fp);
+
+/*
+ [2004-08-04] dekarma - Took this out since it messes up good XML if it has skins/templates
+ with CDATA sections. need to investigate consequences.
+ see bug [ 999914 ] Import fails (multiple skins in XML/one of them with CDATA)
+
+ // backwards compatibility with the non-wellformed skinbackup.xml files
+ // generated by v2/v3 (when CDATA sections were present in skins)
+ // split up those CDATA sections into multiple ones
+ $tempbuffer = preg_replace_callback(
+ "/(<!\[CDATA\[[^]]*?<!\[CDATA\[[^]]*)((?:\]\].*?<!\[CDATA.*?)*)(\]\])(.*\]\])/ms",
+ create_function(
+ '$matches',
+ 'return $matches[1] . preg_replace("/(\]\])(.*?<!\[CDATA)/ms","]]]]><![CDATA[$2",$matches[2])."]]]]><![CDATA[".$matches[4];'
+ ),
+ $tempbuffer
+ );
+*/
+ $temp = tmpfile();
+// fwrite($temp, $tempbuffer);
+ if (!function_exists('mb_convert_encoding')) {
+ fwrite($temp, $tempbuffer);
+ } else {
+ if (strtoupper(_CHARSET) == 'ISO-8859-1') {
+ fwrite($temp, $tempbuffer);
+ } else {
+ mb_detect_order("ASCII, JIS, SJIS, UTF-8, EUC-JP, ISO-8859-1");
+ $temp_encode = mb_detect_encoding($tempbuffer);
+ fwrite($temp, mb_convert_encoding($tempbuffer, 'UTF-8', $temp_encode));
+ }
+ }
+ rewind($temp);
+
+ while ( ($buffer = fread($temp, 4096) ) && (!$metaOnly || ($metaOnly && !$this->metaDataRead))) {
+ $err = xml_parse( $this->parser, $buffer, feof($temp) );
+ if (!$err && $this->debug) {
+ echo _ERROR . ': ' . xml_error_string(xml_get_error_code($this->parser)) . '<br />';
+ }
+ }
+
+ // all done
+ $this->inXml = 0;
+ fclose($temp);
+ }
+
+ /**
+ * Returns the list of skin names
+ */
+ function getSkinNames() {
+ return array_keys($this->skins);
+ }
+
+ /**
+ * Returns the list of template names
+ */
+ function getTemplateNames() {
+ return array_keys($this->templates);
+ }
+
+ /**
+ * Returns the extra information included in the XML file
+ */
+ function getInfo() {
+ return $this->info;
+ }
+
+ /**
+ * Writes the skins and templates to the database
+ *
+ * @param $allowOverwrite
+ * set to 1 when allowed to overwrite existing skins with the same name
+ * (default = 0)
+ */
+ function writeToDatabase($allowOverwrite = 0) {
+ $existingSkins = $this->checkSkinNameClashes();
+ $existingTemplates = $this->checkTemplateNameClashes();
+
+ // if not allowed to overwrite, check if any nameclashes exists
+ if (!$allowOverwrite) {
+ if ((sizeof($existingSkins) > 0) || (sizeof($existingTemplates) > 0)) {
+ return _SKINIE_NAME_CLASHES_DETECTED;
+ }
+ }
+
+ foreach ($this->skins as $skinName => $data) {
+ // 1. if exists: delete all part data, update desc data
+ // if not exists: create desc
+ if (in_array($skinName, $existingSkins)) {
+ $skinObj = SKIN::createFromName($skinName);
+
+ // delete all parts of the skin
+ $skinObj->deleteAllParts();
+
+ // update general info
+ $skinObj->updateGeneralInfo(
+ $skinName,
+ $data['description'],
+ $data['type'],
+ $data['includeMode'],
+ $data['includePrefix']
+ );
+ } else {
+ $skinid = SKIN::createNew(
+ $skinName,
+ $data['description'],
+ $data['type'],
+ $data['includeMode'],
+ $data['includePrefix']
+ );
+ $skinObj = new SKIN($skinid);
+ }
+
+ // 2. add parts
+ foreach ($data['parts'] as $partName => $partContent) {
+ $skinObj->update($partName, $partContent);
+ }
+ }
+
+ foreach ($this->templates as $templateName => $data) {
+ // 1. if exists: delete all part data, update desc data
+ // if not exists: create desc
+ if (in_array($templateName, $existingTemplates)) {
+ $templateObj = TEMPLATE::createFromName($templateName);
+
+ // delete all parts of the template
+ $templateObj->deleteAllParts();
+
+ // update general info
+ $templateObj->updateGeneralInfo($templateName, $data['description']);
+ } else {
+ $templateid = TEMPLATE::createNew($templateName, $data['description']);
+ $templateObj = new TEMPLATE($templateid);
+ }
+
+ // 2. add parts
+ foreach ($data['parts'] as $partName => $partContent) {
+ $templateObj->update($partName, $partContent);
+ }
+ }
+
+
+ }
+
+ /**
+ * returns an array of all the skin nameclashes (empty array when no name clashes)
+ */
+ function checkSkinNameClashes() {
+ $clashes = array();
+
+ foreach ($this->skins as $skinName => $data) {
+ if (SKIN::exists($skinName)) {
+ array_push($clashes, $skinName);
+ }
+ }
+
+ return $clashes;
+ }
+
+ /**
+ * returns an array of all the template nameclashes
+ * (empty array when no name clashes)
+ */
+ function checkTemplateNameClashes() {
+ $clashes = array();
+
+ foreach ($this->templates as $templateName => $data) {
+ if (TEMPLATE::exists($templateName)) {
+ array_push($clashes, $templateName);
+ }
+ }
+
+ return $clashes;
+ }
+
+ /**
+ * Called by XML parser for each new start element encountered
+ */
+ function startElement($parser, $name, $attrs) {
+ foreach($attrs as $key=>$value) {
+ $attrs[$key] = htmlspecialchars($value, ENT_QUOTES);
+ }
+
+ if ($this->debug) {
+ echo 'START: ' . htmlspecialchars($name, ENT_QUOTES) . '<br />';
+ }
+
+ switch ($name) {
+ case 'nucleusskin':
+ $this->inData = 1;
+ break;
+ case 'meta':
+ $this->inMeta = 1;
+ break;
+ case 'info':
+ // no action needed
+ break;
+ case 'skin':
+ if (!$this->inMeta) {
+ $this->inSkin = 1;
+ $this->currentName = $attrs['name'];
+ $this->skins[$this->currentName]['type'] = $attrs['type'];
+ $this->skins[$this->currentName]['includeMode'] = $attrs['includeMode'];
+ $this->skins[$this->currentName]['includePrefix'] = $attrs['includePrefix'];
+ $this->skins[$this->currentName]['parts'] = array();
+ } else {
+ $this->skins[$attrs['name']] = array();
+ $this->skins[$attrs['name']]['parts'] = array();
+ }
+ break;
+ case 'template':
+ if (!$this->inMeta) {
+ $this->inTemplate = 1;
+ $this->currentName = $attrs['name'];
+ $this->templates[$this->currentName]['parts'] = array();
+ } else {
+ $this->templates[$attrs['name']] = array();
+ $this->templates[$attrs['name']]['parts'] = array();
+ }
+ break;
+ case 'description':
+ // no action needed
+ break;
+ case 'part':
+ $this->currentPartName = $attrs['name'];
+ break;
+ default:
+ echo _SKINIE_SEELEMENT_UNEXPECTEDTAG . htmlspecialchars($name, ENT_QUOTES) . '<br />';
+ break;
+ }
+
+ // character data never contains other tags
+ $this->clearCharacterData();
+
+ }
+
+ /**
+ * Called by the XML parser for each closing tag encountered
+ */
+ function endElement($parser, $name) {
+ if ($this->debug) {
+ echo 'END: ' . htmlspecialchars($name, ENT_QUOTES) . '<br />';
+ }
+
+ switch ($name) {
+ case 'nucleusskin':
+ $this->inData = 0;
+ $this->allRead = 1;
+ break;
+ case 'meta':
+ $this->inMeta = 0;
+ $this->metaDataRead = 1;
+ break;
+ case 'info':
+ $this->info = $this->getCharacterData();
+ case 'skin':
+ if (!$this->inMeta) {
+ $this->inSkin = 0;
+ }
+ break;
+ case 'template':
+ if (!$this->inMeta) {
+ $this->inTemplate = 0;
+ }
+ break;
+ case 'description':
+ if ($this->inSkin) {
+ $this->skins[$this->currentName]['description'] = $this->getCharacterData();
+ } else {
+ $this->templates[$this->currentName]['description'] = $this->getCharacterData();
+ }
+ break;
+ case 'part':
+ if ($this->inSkin) {
+ $this->skins[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();
+ } else {
+ $this->templates[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();
+ }
+ break;
+ default:
+ echo _SKINIE_SEELEMENT_UNEXPECTEDTAG . htmlspecialchars($name, ENT_QUOTES) . '<br />';
+ break;
+ }
+ $this->clearCharacterData();
+
+ }
+
+ /**
+ * Called by XML parser for data inside elements
+ */
+ function characterData ($parser, $data) {
+ if ($this->debug) {
+ echo 'NEW DATA: ' . htmlspecialchars($data, ENT_QUOTES) . '<br />';
+ }
+ $this->cdata .= $data;
+ }
+
+ /**
+ * Returns the data collected so far
+ */
+ function getCharacterData() {
+// echo $this->cdata;
+ if ( (strtoupper(_CHARSET) == 'UTF-8')
+ or (strtoupper(_CHARSET) == 'ISO-8859-1')
+ or (!function_exists('mb_convert_encoding')) ) {
+ return $this->cdata;
+ } else {
+ return mb_convert_encoding($this->cdata, _CHARSET ,'UTF-8');
+ }
+ }
+
+ /**
+ * Clears the data buffer
+ */
+ function clearCharacterData() {
+ $this->cdata = '';
+ }
+
+ /**
+ * Static method that looks for importable XML files in subdirs of the given dir
+ */
+ function searchForCandidates($dir) {
+ $candidates = array();
+
+ $dirhandle = opendir($dir);
+ while ($filename = readdir($dirhandle)) {
+ if (@is_dir($dir . $filename) && ($filename != '.') && ($filename != '..')) {
+ $xml_file = $dir . $filename . '/skinbackup.xml';
+ if (file_exists($xml_file) && is_readable($xml_file)) {
+ $candidates[$filename] = $filename; //$xml_file;
+ }
+
+ // backwards compatibility
+ $xml_file = $dir . $filename . '/skindata.xml';
+ if (file_exists($xml_file) && is_readable($xml_file)) {
+ $candidates[$filename] = $filename; //$xml_file;
+ }
+ }
+ }
+ closedir($dirhandle);
+
+ return $candidates;
+
+ }
+
+
+}
+
+
+class SKINEXPORT {
+
+ var $templates;
+ var $skins;
+ var $info;
+
+ /**
+ * Constructor initializes data structures
+ */
+ function SKINEXPORT() {
+ // list of templateIDs to export
+ $this->templates = array();
+
+ // list of skinIDs to export
+ $this->skins = array();
+
+ // extra info to be in XML file
+ $this->info = '';
+ }
+
+ /**
+ * Adds a template to be exported
+ *
+ * @param id
+ * template ID
+ * @result false when no such ID exists
+ */
+ function addTemplate($id) {
+ if (!TEMPLATE::existsID($id)) {
+ return 0;
+ }
+
+
+ $this->templates[$id] = TEMPLATE::getNameFromId($id);
+
+ return 1;
+ }
+
+ /**
+ * Adds a skin to be exported
+ *
+ * @param id
+ * skin ID
+ * @result false when no such ID exists
+ */
+ function addSkin($id) {
+ if (!SKIN::existsID($id)) {
+ return 0;
+ }
+
+ $this->skins[$id] = SKIN::getNameFromId($id);
+
+ return 1;
+ }
+
+ /**
+ * Sets the extra info to be included in the exported file
+ */
+ function setInfo($info) {
+ $this->info = $info;
+ }
+
+
+ /**
+ * Outputs the XML contents of the export file
+ *
+ * @param $setHeaders
+ * set to 0 if you don't want to send out headers
+ * (optional, default 1)
+ */
+ function export($setHeaders = 1) {
+ if ($setHeaders) {
+ // make sure the mimetype is correct, and that the data does not show up
+ // in the browser, but gets saved into and XML file (popup download window)
+ header('Content-Type: text/xml');
+ header('Content-Disposition: attachment; filename="skinbackup.xml"');
+ header('Expires: 0');
+ header('Pragma: no-cache');
+ }
+
+ echo "<nucleusskin>\n";
+
+ // meta
+ echo "\t<meta>\n";
+ // skins
+ foreach ($this->skins as $skinId => $skinName) {
+ $skinName = htmlspecialchars($skinName, ENT_QUOTES);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $skinName = mb_convert_encoding($skinName, 'UTF-8', _CHARSET);
+ }
+ echo "\t\t" . '<skin name="' . htmlspecialchars($skinName, ENT_QUOTES) . '" />' . "\n";
+ }
+ // templates
+ foreach ($this->templates as $templateId => $templateName) {
+ $templateName = htmlspecialchars($templateName, ENT_QUOTES);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $templateName = mb_convert_encoding($templateName, 'UTF-8', _CHARSET);
+ }
+ echo "\t\t" . '<template name="' . htmlspecialchars($templateName, ENT_QUOTES) . '" />' . "\n";
+ }
+ // extra info
+ if ($this->info) {
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $skin_info = mb_convert_encoding($this->info, 'UTF-8', _CHARSET);
+ } else {
+ $skin_info = $this->info;
+ }
+ echo "\t\t<info><![CDATA[" . $skin_info . "]]></info>\n";
+ }
+ echo "\t</meta>\n\n\n";
+
+ // contents skins
+ foreach ($this->skins as $skinId => $skinName) {
+ $skinId = intval($skinId);
+ $skinObj = new SKIN($skinId);
+ $skinName = htmlspecialchars($skinName, ENT_QUOTES);
+ $contentT = htmlspecialchars($skinObj->getContentType(), ENT_QUOTES);
+ $incMode = htmlspecialchars($skinObj->getIncludeMode(), ENT_QUOTES);
+ $incPrefx = htmlspecialchars($skinObj->getIncludePrefix(), ENT_QUOTES);
+ $skinDesc = htmlspecialchars($skinObj->getDescription(), ENT_QUOTES);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $skinName = mb_convert_encoding($skinName, 'UTF-8', _CHARSET);
+ $contentT = mb_convert_encoding($contentT, 'UTF-8', _CHARSET);
+ $incMode = mb_convert_encoding($incMode, 'UTF-8', _CHARSET);
+ $incPrefx = mb_convert_encoding($incPrefx, 'UTF-8', _CHARSET);
+ $skinDesc = mb_convert_encoding($skinDesc, 'UTF-8', _CHARSET);
+ }
+
+ echo "\t" . '<skin name="' . $skinName . '" type="' . $contentT . '" includeMode="' . $incMode . '" includePrefix="' . $incPrefx . '">' . "\n";
+
+ echo "\t\t" . '<description>' . $skinDesc . '</description>' . "\n";
+
+ $que = 'SELECT'
+ . ' stype,'
+ . ' scontent '
+ . 'FROM '
+ . sql_table('skin')
+ . ' WHERE'
+ . ' sdesc = ' . $skinId;
+ $res = sql_query($que);
+ while ($partObj = sql_fetch_object($res)) {
+ $type = htmlspecialchars($partObj->stype, ENT_QUOTES);
+ $cdata = $this->escapeCDATA($partObj->scontent);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $type = mb_convert_encoding($type, 'UTF-8', _CHARSET);
+ $cdata = mb_convert_encoding($cdata, 'UTF-8', _CHARSET);
+ }
+ echo "\t\t" . '<part name="' . $type . '">';
+ echo '<![CDATA[' . $cdata . ']]>';
+ echo "</part>\n\n";
+ }
+
+ echo "\t</skin>\n\n\n";
+ }
+
+ // contents templates
+ foreach ($this->templates as $templateId => $templateName) {
+ $templateId = intval($templateId);
+ $templateName = htmlspecialchars($templateName, ENT_QUOTES);
+ $templateDesc = htmlspecialchars(TEMPLATE::getDesc($templateId), ENT_QUOTES);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $templateName = mb_convert_encoding($templateName, 'UTF-8', _CHARSET);
+ $templateDesc = mb_convert_encoding($templateDesc, 'UTF-8', _CHARSET);
+ }
+
+ echo "\t" . '<template name="' . $templateName . '">' . "\n";
+
+ echo "\t\t" . '<description>' . $templateDesc . "</description>\n";
+
+ $que = 'SELECT'
+ . ' tpartname,'
+ . ' tcontent'
+ . ' FROM '
+ . sql_table('template')
+ . ' WHERE'
+ . ' tdesc = ' . $templateId;
+ $res = sql_query($que);
+ while ($partObj = sql_fetch_object($res)) {
+ $type = htmlspecialchars($partObj->tpartname, ENT_QUOTES);
+ $cdata = $this->escapeCDATA($partObj->tcontent);
+ if (strtoupper(_CHARSET) != 'UTF-8') {
+ $type = mb_convert_encoding($type, 'UTF-8', _CHARSET);
+ $cdata = mb_convert_encoding($cdata, 'UTF-8', _CHARSET);
+ }
+ echo "\t\t" . '<part name="' . $type . '">';
+ echo '<![CDATA[' . $cdata . ']]>';
+ echo '</part>' . "\n\n";
+ }
+
+ echo "\t</template>\n\n\n";
+ }
+
+ echo '</nucleusskin>';
+ }
+
+ /**
+ * Escapes CDATA content so it can be included in another CDATA section
+ */
+ function escapeCDATA($cdata)
+ {
+ return preg_replace('/]]>/', ']]]]><![CDATA[>', $cdata);
+
+ }
+}
+
?>
\ No newline at end of file