1, 'xiffy' => 2, 'roel' => 3, '_default' => 1) * @param aMapCategoryToNucleusId * Similar to $aMapUserToNucleusId, but this array maps category names to * category ids. Please note that the category IDs need to come from the * same blog as $iBlogId * example: array('general' => 11, 'funny' => 33) * @param strCallback * name of a callback function to be called on each item. Such a callback * function should have a format like: * function myCallback(&$data) * where $data is an associative array with all item data ('title','body', * ...) */ function BlogImport($iBlogId = -1, $aOptions = array('ReadNamesOnly' => 0), $aMapUserToNucleusId = array(), $aMapCategoryToNucleusId = array(), $strCallback = '') { global $manager; $this->iBlog = $iBlogId; if ($iBlogId != -1) $this->oBlog =& $manager->getBlog($iBlogId); else $this->oBlog = 0; $this->aOptions = $aOptions; $this->aMapUserToNucleusId = $aMapUserToNucleusId; $this->aMapCategoryToNucleusId = $aMapCategoryToNucleusId; $this->strCallback = $strCallback; $this->aMapIdToNucleusId = array(); $this->bReadNamesOnly = $this->aOptions['ReadNamesOnly'] == 1; $this->aCategoryNames = array(); $this->aAuthorNames = array(); // disable magic_quotes_runtime if it's turned on set_magic_quotes_runtime(0); // debugging mode? $this->bDebug = 0; // XML file pointer $this->fp = 0; // to maintain track of where we are inside the XML file $this->inXml = 0; $this->inData = 0; $this->inItem = 0; $this->inComment = 0; $this->aCurrentItem = $this->_blankItem(); $this->aCurrentComment = $this->_blankComment(); // character data pile $this->cdata = ''; // 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); // TODO: add data checking $this->bValid = 1; // data structures $this->strErrorMessage = ''; } /** * Gets the import library version */ function getVersion() { return '0.2'; } /** * Returns an array with all the author names used in the file (only * the authors of items are included) * * @require importXmlFile should be called prior to calling this */ function getAuthorNames() { return $this->aAuthorNames; } /** * Returns an array with all the category names used in the file * * @require importXmlFile should be called prior to calling this */ function getCategoryNames() { return $this->aCategoryNames; } /** * Imports an XML file into a given blog * * also fills $this->aMapIdToNucleusId * array with info for each item having a Nucleus ID that is different * from the original ID * example: array(9999 => 1, 1234 => 2, 12 => 3) * * @param strXmlFile * Location of the XML file. The XML file must be in the correct * Nucleus import format * @returns * 0 on failure. Use getLastError() to get error message * 1 on success * */ function importXmlFile($strXmlFile) { $this->resetErrorMessage(); flush(); if (!$this->bValid) return $this->setErrorMessage('BlogImport object is invalid'); if (!@file_exists($strXmlFile)) return $this->setErrorMessage($strXmlFile . ' does not exist'); if (!@is_readable($strXmlFile)) return $this->setErrorMessage($strXmlFile . ' is not readable'); // open file $this->fp = @fopen($strXmlFile, 'r'); if (!$this->fp) return $this->setErrorMessage('Failed to open file/URL'); // here we go! $this->inXml = 1; // parse file contents while ($buffer = fread($this->fp, 4096)) { $err = xml_parse( $this->parser, $buffer, feof($this->fp) ); if (!$err && $this->bDebug) echo 'ERROR: ', xml_error_string(xml_get_error_code($this->parser)), '
'; } // all done $this->inXml = 0; fclose($this->fp); return 1; } /** * Identical to importXmlFile, but takes an almost-ready-for-addition array * * @param aData * Array with item data, as prepared by import_fromXML * * @returns * 0 on failure. Use getLastError() to get error message * 1 on success */ function importOneItem(&$aData) { $this->resetErrorMessage(); // - do some logic to determine nucleus users and categories // * find member id // * find blog id // * find category id $aData['nucleus_blogid'] = $this->iBlog; $aData['nucleus_catid'] = $this->_findCategoryId($aData['category']); $aData['nucleus_memberid'] = $this->_findMemberId($aData['author']); if ($aData['nucleus_memberid'] == 0) { $aData['nucleus_memberid'] = $this->aMapUserToNucleusId['_default']; } // - apply logic to comments foreach (array_keys($aData['comments']) as $key) { // * find member id $aData['comments'][$key]['nucleus_memberid'] = $this->_findMemberId($aData['comments'][$key]['author']); // * extract authorid if ($aData['comments'][$key]['nucleus_memberid'] == 0) { $url = $aData['comments'][$key]['url']; $email = $aData['comments'][$key]['email']; $authid = $aData['comments'][$key]['authorid']; if (!$authid && $url) $aData['comments'][$key]['authorid'] = $url; else if (!$authid && $email) $aData['comments'][$key]['authorid'] = $email; } } // - call callback if ($this->strCallback && function_exists($this->strCallback)) { call_user_func_array($this->strCallback, array(&$aData)); } if ($this->bDebug) { echo '
';
			print_r($aData);
			echo '
'; } // - insert item into nucleus database $iNewId = $this->sql_addToItem( $aData['title'], $aData['body'], $aData['extended'], $aData['nucleus_blogid'], $aData['nucleus_memberid'], $aData['timestamp'], ($aData['itemstatus'] == 'open') ? 0 : 1, $aData['nucleus_catid'], $aData['posvotes'], $aData['negvotes'] ); // - store id mapping if needed $aData['nucleus_id'] = $iNewId; if ($aData['nucleus_id'] != $aData['id']) $this->aMapIdToNucleusId[$aData['id']] = $aData['nucleus_id']; // - insert comments into nucleus database foreach ($aData['comments'] as $comment) { $cId = $this->sql_addToComments( $comment['author'], $comment['authorid'], $comment['body'], $aData['nucleus_blogid'], $aData['nucleus_id'], $comment['nucleus_memberid'], $comment['timestamp'], $comment['host'], $comment['ip'] ); } echo ' .'; // progress indicator flush(); return 1; } function getHtmlCode($what) { ob_start(); switch($what) { // ---------------------------------------------------------------------------------------- case 'NucleusMemberOptions': $res = DB::getResult('SELECT mname as text, mnumber as value FROM '.sql_table('member')); foreach ( $res as $row ) { echo ''; } break; // ---------------------------------------------------------------------------------------- case 'NucleusBlogSelect': $query = 'SELECT bname as text, bnumber as value FROM '.sql_table('blog'); $template['name'] = 'blogid'; $template['selected'] = $CONF['DefaultBlog']; echo showlist($query,'select',$template); break; // ---------------------------------------------------------------------------------------- case 'ConvertSelectMembers': ?>

Assign Members to Authors

Below is a list of all the authors that Nucleus could discover (only authors that have posted at least one entry are listed). Please assign a Nucleus Member to all of these authors.

getAuthorNames(); // get HTML code for selection list $optionsHtml = $this->getHtmlCode('NucleusMemberOptions'); $idx = 0; while ($a_name = array_pop($authors)) { ?>
Author Nucleus Member Blog Admin?
Default Member

Assign Categories

Below is a list of all the categories that Nucleus could discover (only categories that have been used at least once are listed). Please assign a Nucleus Category to all of these categories.

getCategoryNames(); // get HTML code for selection list $optionsHtml = $this->getHtmlCode('NucleusCategoryOptions'); $idx = 0; while ($a_name = array_pop($catnames)) { ?>
Category Nucleus Category

Choose Destination Weblog

There are two options: you can either choose an existing blog to add the entries into, or you can choose to create a new weblog.

getHtmlCode('NucleusBlogSelect'); ?>

Do the conversion!

Note: Clicking the button once is enough, even if it takes a while to complete.
Creating new blog'; echo '

Your new weblog has been created.

'; return $nucleus_blogid; } else { return $blogid; } } function getFromRequest($what) { $aResult = array(); switch ($what) { case 'authors': $authorcount = intPostVar('authorcount'); $author = requestArray('author'); $memberid = requestIntArray('memberid'); $isadmin = requestIntArray('admin'); for ($i=0;$i<$authorcount;$i++) { $authorname = undoMagic($author[$i]); // add authors to team $this->oBlog->addTeamMember(intval($memberid[$i]),intval($isadmin[$i])); $aResult[$authorname] = $memberid[$i]; } $this->aMapUserToNucleusId = $aResult; break; case 'categories': // TODO $this->aMapCategoryToNucleusId = $aResult; break; } return $aResult; } function _findCategoryId($name) { $catid = @$this->aMapCategoryToNucleusId[$name]; if (!$catid && $this->oBlog) // get default category for weblog $catid = $this->oBlog->getDefaultCategory(); return $catid; } function _findMemberId($name) { $memberid = intval(@$this->aMapUserToNucleusId[$name]); return $memberid; } /** * Returns the last error message. Use it to find out the reason for failure */ function getLastError() { return $this->strErrorMessage; } function resetErrorMessage() { $this->strErrorMessage = ''; } function setErrorMessage($strMsg) { $this->strErrorMessage = $strMsg; return 0; } /** * Called by XML parser for each new start element encountered */ function startElement($parser, $name, $attrs) { if ($this->bDebug) echo 'START: ', $name, '
'; switch ($name) { case 'blog': $this->inData = 1; $this->strImportFileVersion = $attrs['version']; // TODO: check version number break; case 'item': $this->inItem = 1; $this->aCurrentItem = $this->_blankItem($attrs['id']); if (@$attrs['commentsOnly'] == 'true') $this->aCurrentItem['commentsOnly'] = 1; else $this->aCurrentItem['commentsOnly'] = 0; break; case 'timestamp': if ($this->inItem || $this->inComment) { // store time format $this->currentTSFormat = $attrs['type']; } break; case 'author': case 'title': case 'body': case 'extended': case 'category': case 'itemstatus': case 'posvotes': case 'negvotes': // nothing to do break; case 'comment': if ($this->inItem) { $this->inComment = 1; $this->aCurrentComment = $this->_blankComment($attrs['id']); } break; case 'email': case 'url': case 'authorid': case 'host': case 'ip': // nothing to do break; default: echo 'UNEXPECTED TAG: ' , $name , '
'; 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->bDebug) echo 'END: ', $name, '
'; switch ($name) { case 'blog': $this->inData = 0; break; case 'item': if (!$this->bReadNamesOnly) { // write to database // TODO: check if succes or failure $this->importOneItem($this->aCurrentItem); } $this->inItem = 0; // initialize item structure $this->aCurrentItem = $this->_blankItem(); break; case 'timestamp': $timestamp = $this->getTime($this->getCharacterData(), $this->currentTSFormat); if ($this->inComment) $this->aCurrentComment['timestamp'] = $timestamp; else if ($this->inItem) $this->aCurrentItem['timestamp'] = $timestamp; break; case 'author': if ($this->inItem && !$this->inComment) $this->_addAuthorName($this->getCharacterData()); if ($this->inComment) $this->aCurrentComment['author'] = $this->getCharacterData(); else if ($this->inItem) $this->aCurrentItem['author'] = $this->getCharacterData(); break; case 'title': if ($this->inComment) $this->aCurrentComment['title'] = $this->getCharacterData(); else if ($this->inItem) $this->aCurrentItem['title'] = $this->getCharacterData(); break; case 'body': if ($this->inComment) $this->aCurrentComment['body'] = $this->getCharacterData(); else if ($this->inItem) $this->aCurrentItem['body'] = $this->getCharacterData(); break; case 'extended': if ($this->inItem) $this->aCurrentItem['extended'] = $this->getCharacterData(); break; case 'category': $this->_addCategoryName($this->getCharacterData()); if ($this->inItem && !$this->aCurrentItem['category']) { $this->aCurrentItem['category'] = $this->getCharacterData(); } break; case 'itemstatus': if ($this->inItem) $this->aCurrentItem['itemstatus'] = $this->getCharacterData(); break; case 'posvotes': if ($this->inItem) $this->aCurrentItem['posvotes'] = $this->getCharacterData(); break; case 'negvotes': if ($this->inItem) $this->aCurrentItem['negvotes'] = $this->getCharacterData(); break; case 'comment': if ($this->inComment) { array_push($this->aCurrentItem['comments'], $this->aCurrentComment); $this->aCurrentComment = $this->_blankComment(); $this->inComment = 0; } break; case 'email': if ($this->inComment) $this->aCurrentComment['email'] = $this->getCharacterData(); break; case 'url': if ($this->inComment) $this->aCurrentComment['url'] = $this->getCharacterData(); break; case 'authorid': if ($this->inComment) $this->aCurrentComment['authorid'] = $this->getCharacterData(); break; case 'host': if ($this->inComment) $this->aCurrentComment['host'] = $this->getCharacterData(); break; case 'ip': if ($this->inComment) $this->aCurrentComment['ip'] = $this->getCharacterData(); break; default: echo 'UNEXPECTED TAG: ' , $name, '
'; break; } $this->clearCharacterData(); } /** * Called by XML parser for data inside elements */ function characterData ($parser, $data) { if ($this->bDebug) echo 'NEW DATA: ', Entity::hsc($data), '
'; $this->cdata .= $data; } /** * Returns the data collected so far */ function getCharacterData() { return $this->cdata; } /** * Clears the data buffer */ function clearCharacterData() { $this->cdata = ''; } /** * Parses a given string into a unix timestamp. * * @param strTime * String, formatted as given in $strFormat * @param strFormat * Multiple date formats are supported: * 'unix': plain unix timestamp (numeric) * 'blogger': for blogger import: MM/DD/YYYY hh:MM:SS AM */ function getTime($strTime, $strFormat = 'unix') { $strFormat = strtolower($strFormat); switch($strFormat) { case 'unix': return intval($strTime); case 'blogger': // 7/24/2000 11:27:13 AM if (eregi("(.*)/(.*)/(.*) (.*):(.*):(.*) (.*)",$strTime,$regs) != false) { if (($regs[7] == "PM") && ($regs[4] != "12")) $regs[4] += 12; return mktime($regs[4],$regs[5],$regs[6],$regs[1],$regs[2],$regs[3]); } else { return 0; } } } function _blankItem($id = -1) { return array( 'id' => $id, 'commentsOnly' => 0, 'timestamp' => time(), 'author' => '', 'title' => '', 'body' => '', 'extended' => '', 'category' => '', 'itemstatus' => 'open', 'posvotes' => 0, 'negvotes' => 0, 'comments' => array() ); } function _blankComment($id = -1) { return array( 'id' => $id, 'timestamp' => time(), 'author' => '', 'title' => '', 'body' => '', 'email' => '', 'url' => '', 'authorid' => '', 'host' => '', 'ip' => '' ); } function _addAuthorName($name) { if (!in_array($name, $this->aAuthorNames)) array_push($this->aAuthorNames, $name); } function _addCategoryName($name) { if (!in_array($name, $this->aCategoryNames)) array_push($this->aCategoryNames, $name); } function sql_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) { $title = DB::quoteValue(trim($title)); $body = DB::quoteValue(trim($body)); $more = DB::quoteValue(trim($more)); $timestamp = DB::formatDateTime($timestamp); $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) ' . "VALUES ($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $karmapos, $karmaneg, $category)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } return DB::getInsertId(); } function sql_addToBlog($name, $shortname, $ownerid) { $name = DB::quoteValue($name); $shortname = DB::quoteValue($shortname); // create new category first DB::execute('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another category')"); $defcat = DB::getInsertId(); $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ($name, $shortname, 1, 0, $defcat)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } $id = DB::getInsertId(); // update category row so it links to blog DB::execute('UPDATE ' . sql_table('category') . ' SET cblog=' . intval($id). ' WHERE catid=' . intval($defcat)); BlogImport::sql_addToTeam($id,$ownerid,1); return $id; } function sql_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') { $name = DB::quoteValue($name); $url = DB::quoteValue($url); $body = DB::quoteValue(trim($body)); $host = DB::quoteValue($host); $ip = DB::quoteValue($ip); $timestamp = DB::formatDateTime($timestamp); $query = 'INSERT INTO '.sql_table('comment') . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) ' . "VALUES ($name, $url, $memberid, $body, $itemid, $timestamp, $host, $blogid, $ip)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } return DB::getInsertId(); } function sql_addToTeam($blogid, $memberid, $admin) { $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) ' . "VALUES ($memberid, $blogid, $admin)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } return DB::getInsertId(); } } // some sort of version checking $ver = convert_getNucleusVersion(); if ($ver > 250) convert_doError("You should check the Nucleus website for updates to this convert tool. This one might not work with your current Nucleus installation."); // make sure the request variables get reqistered in the global scope // Doing this should be avoided on code rewrite (this is a potential security risk) if ((phpversion() >= "4.1.0") && (ini_get("register_globals") == 0)) { @import_request_variables("gp",''); } /** this function gets the nucleus version, even if the getNucleusVersion * function does not exist yet * return 96 for all versions < 100 */ function convert_getNucleusVersion() { if (!function_exists('getNucleusVersion')) return 96; return getNucleusVersion(); } // TODO: remove this function (replaced by BlogImport::sql_addToItem) function convert_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) { $title = DB::quoteValue(trim($title)); $body = DB::quoteValue(trim($body)); $more = DB::quoteValue(trim($more)); $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) ' . "VALUES ($title, $body, $more, $blogid, $authorid, '$timestamp', $closed, $karmapos, $karmaneg, $category)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } return DB::getInsertId(); } // TODO: remove this function (replaced by BlogImport::sql_addToBlog) function convert_addToBlog($name, $shortname, $ownerid) { $name = DB::quoteValue($name); $shortname = DB::quoteValue($shortname); // create new category first DB::execute('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another categort')"); $defcat = DB::getInsertId(); $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ($name, $shortname, 1, 0, $defcat)"; if ( DB::execute($query) === FALSE ) { die('Error while executing query: ' . $query); } $id = DB::getInsertId(); convert_addToTeam($id,$ownerid,1); return $id; } // TODO: remove this function (replaced by BlogImport::sql_addToComments) function convert_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') { $name = DB::quoteValue($name); $url = DB::quoteValue($url); $body = DB::quoteValue(trim($body)); $host = DB::quoteValue($host); $ip = DB::quoteValue($ip); $query = 'INSERT INTO '.sql_table('comment') . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) ' . "VALUES ($name, $url, $memberid, $body, $itemid, '$timestamp', $host, $blogid, $ip)"; if ( DB::execute($query) === FALSE ) { die("Error while executing query: " . $query); } return DB::getInsertId(); } // TODO: remove this function (replaced by BlogImport::sql_addToTeam) function convert_addToTeam($blogid, $memberid, $admin) { $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) ' . "VALUES ($memberid, $blogid, $admin)"; if ( DB::execute($query) === FALSE ) { die("Error while executing query: " . $query); } return DB::getInsertId(); } function convert_showLogin($type) { convert_head(); ?>

Please Log in First

Enter your data below:

Nucleus Convert

Error!

Message was:

Go Back