3 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4 * Copyright (C) 2002-2006 The Nucleus Group
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * (see nucleus/documentation/index.html#license for more info)
13 * @license http://nucleuscms.org/license.txt GNU General Public License
14 * @copyright Copyright (C) 2002-2006 The Nucleus Group
15 * @version $Id: functions.inc.php 1624 2012-01-09 11:36:20Z sakamocchi $
18 // try to set a long timeout time
19 @set_time_limit(1200);
22 * Generic class that can import XML files with either blog items or comments
23 * to be imported into a Nucleus blog
29 * Creates a new BlogImport object
33 * Nucleus blogid to which the content of the XML file must be added
36 * $aOptions['PreserveIds'] = 1 (NOT IMPLEMENTED)
37 * try to use the same ID for the nucleus item as the ID listed
39 * $aOptions['ReadNamesOnly']
40 * Reads all category names and author names (items
41 * only) into $aAuthorNames and $aCategoryNames
42 * @param aMapUserToNucleusId
43 * Array with mapping from user names (as listed in the XML file) to
44 * Nucleus member Ids. '_default' lists the default user.
45 * example: array('karma' => 1, 'xiffy' => 2, 'roel' => 3, '_default' => 1)
46 * @param aMapCategoryToNucleusId
47 * Similar to $aMapUserToNucleusId, but this array maps category names to
48 * category ids. Please note that the category IDs need to come from the
49 * same blog as $iBlogId
50 * example: array('general' => 11, 'funny' => 33)
52 * name of a callback function to be called on each item. Such a callback
53 * function should have a format like:
54 * function myCallback(&$data)
55 * where $data is an associative array with all item data ('title','body',
58 function BlogImport($iBlogId = -1, $aOptions = array('ReadNamesOnly' => 0), $aMapUserToNucleusId = array(), $aMapCategoryToNucleusId = array(), $strCallback = '') {
61 $this->iBlog = $iBlogId;
63 $this->oBlog =& $manager->getBlog($iBlogId);
66 $this->aOptions = $aOptions;
67 $this->aMapUserToNucleusId = $aMapUserToNucleusId;
68 $this->aMapCategoryToNucleusId = $aMapCategoryToNucleusId;
69 $this->strCallback = $strCallback;
70 $this->aMapIdToNucleusId = array();
72 $this->bReadNamesOnly = $this->aOptions['ReadNamesOnly'] == 1;
73 $this->aCategoryNames = array();
74 $this->aAuthorNames = array();
77 // disable magic_quotes_runtime if it's turned on
78 set_magic_quotes_runtime(0);
86 // to maintain track of where we are inside the XML file
91 $this->aCurrentItem = $this->_blankItem();
92 $this->aCurrentComment = $this->_blankComment();
94 // character data pile
98 $this->parser = xml_parser_create();
99 xml_set_object($this->parser, $this);
100 xml_set_element_handler($this->parser, 'startElement', 'endElement');
101 xml_set_character_data_handler($this->parser, 'characterData');
102 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
104 // TODO: add data checking
108 $this->strErrorMessage = '';
113 * Gets the import library version
115 function getVersion() {
120 * Returns an array with all the author names used in the file (only
121 * the authors of items are included)
123 * @require importXmlFile should be called prior to calling this
125 function getAuthorNames() {
126 return $this->aAuthorNames;
130 * Returns an array with all the category names used in the file
132 * @require importXmlFile should be called prior to calling this
134 function getCategoryNames() {
135 return $this->aCategoryNames;
139 * Imports an XML file into a given blog
141 * also fills $this->aMapIdToNucleusId
142 * array with info for each item having a Nucleus ID that is different
143 * from the original ID
144 * example: array(9999 => 1, 1234 => 2, 12 => 3)
147 * Location of the XML file. The XML file must be in the correct
148 * Nucleus import format
150 * 0 on failure. Use getLastError() to get error message
154 function importXmlFile($strXmlFile) {
155 $this->resetErrorMessage();
160 return $this->setErrorMessage('BlogImport object is invalid');
161 if (!@file_exists($strXmlFile))
162 return $this->setErrorMessage($strXmlFile . ' does not exist');
163 if (!@is_readable($strXmlFile))
164 return $this->setErrorMessage($strXmlFile . ' is not readable');
167 $this->fp = @fopen($strXmlFile, 'r');
169 return $this->setErrorMessage('Failed to open file/URL');
174 // parse file contents
175 while ($buffer = fread($this->fp, 4096)) {
176 $err = xml_parse( $this->parser, $buffer, feof($this->fp) );
177 if (!$err && $this->bDebug)
178 echo 'ERROR: ', xml_error_string(xml_get_error_code($this->parser)), '<br />';
189 * Identical to importXmlFile, but takes an almost-ready-for-addition array
192 * Array with item data, as prepared by import_fromXML
195 * 0 on failure. Use getLastError() to get error message
198 function importOneItem(&$aData) {
199 $this->resetErrorMessage();
201 // - do some logic to determine nucleus users and categories
204 // * find category id
205 $aData['nucleus_blogid'] = $this->iBlog;
206 $aData['nucleus_catid'] = $this->_findCategoryId($aData['category']);
207 $aData['nucleus_memberid'] = $this->_findMemberId($aData['author']);
208 if ($aData['nucleus_memberid'] == 0) {
209 $aData['nucleus_memberid'] = $this->aMapUserToNucleusId['_default'];
212 // - apply logic to comments
213 foreach (array_keys($aData['comments']) as $key) {
215 $aData['comments'][$key]['nucleus_memberid']
216 = $this->_findMemberId($aData['comments'][$key]['author']);
217 // * extract authorid
218 if ($aData['comments'][$key]['nucleus_memberid'] == 0) {
219 $url = $aData['comments'][$key]['url'];
220 $email = $aData['comments'][$key]['email'];
221 $authid = $aData['comments'][$key]['authorid'];
223 if (!$authid && $url)
224 $aData['comments'][$key]['authorid'] = $url;
225 else if (!$authid && $email)
226 $aData['comments'][$key]['authorid'] = $email;
231 if ($this->strCallback && function_exists($this->strCallback)) {
232 call_user_func_array($this->strCallback, array(&$aData));
241 // - insert item into nucleus database
242 $iNewId = $this->sql_addToItem(
246 $aData['nucleus_blogid'],
247 $aData['nucleus_memberid'],
249 ($aData['itemstatus'] == 'open') ? 0 : 1,
250 $aData['nucleus_catid'],
255 // - store id mapping if needed
256 $aData['nucleus_id'] = $iNewId;
257 if ($aData['nucleus_id'] != $aData['id'])
258 $this->aMapIdToNucleusId[$aData['id']] = $aData['nucleus_id'];
260 // - insert comments into nucleus database
261 foreach ($aData['comments'] as $comment) {
262 $cId = $this->sql_addToComments(
264 $comment['authorid'],
266 $aData['nucleus_blogid'],
267 $aData['nucleus_id'],
268 $comment['nucleus_memberid'],
269 $comment['timestamp'],
275 echo ' .'; // progress indicator
281 function getHtmlCode($what) {
284 // ----------------------------------------------------------------------------------------
285 case 'NucleusMemberOptions':
286 $res = DB::getResult('SELECT mname as text, mnumber as value FROM '.sql_table('member'));
287 foreach ( $res as $row )
289 echo '<option value="'.Entity::hsc($row['value']).'">'.Entity::hsc($row['text']).'</option>';
292 // ----------------------------------------------------------------------------------------
293 case 'NucleusBlogSelect':
294 $query = 'SELECT bname as text, bnumber as value FROM '.sql_table('blog');
295 $template['name'] = 'blogid';
296 $template['selected'] = $CONF['DefaultBlog'];
297 echo showlist($query,'select',$template);
299 // ----------------------------------------------------------------------------------------
300 case 'ConvertSelectMembers':
302 <h2>Assign Members to Authors</h2>
305 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.
312 <th>Nucleus Member</th>
318 $authors = $this->getAuthorNames();
320 // get HTML code for selection list
321 $optionsHtml = $this->getHtmlCode('NucleusMemberOptions');
323 while ($a_name = array_pop($authors)) {
327 <strong><?php echo $a_name?></strong>
328 <input name="author[<?php echo $idx?>]" value="<?php echo Entity::hsc($a_name)?>" type="hidden" />
331 <select name="memberid[<?php echo $idx?>]">
332 <?php echo $optionsHtml; ?>
336 <input name="admin[<?php echo $idx?>]" type="checkbox" value="1" id="admin<?php echo $idx?>" /><label for="admin<?php echo $idx?>">Blog Admin</label>
344 <td><em>Default Member</em></td>
346 <input name="author[<?php echo $idx?>]" value="_default" type="hidden" />
347 <select name="memberid[<?php echo $idx?>]">
348 <?php echo $optionsHtml; ?>
350 <td><input name="admin[<?php echo $idx?>]" type="hidden" value="0" id="admin<?php echo $idx?>" /></td>
355 <input type="hidden" name="authorcount" value="<?php echo ++$idx?>" />
358 // ----------------------------------------------------------------------------------------
359 case 'ConvertSelectCategories':
361 <h2>Assign Categories</h2>
364 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.
371 <th>Nucleus Category</th>
376 $catnames = $this->getCategoryNames();
378 // get HTML code for selection list
379 $optionsHtml = $this->getHtmlCode('NucleusCategoryOptions');
381 while ($a_name = array_pop($catnames)) {
385 <strong><?php echo $a_name?></strong>
386 <input name="category[<?php echo $idx?>]" value="<?php echo Entity::hsc($a_name)?>" type="hidden" />
389 <select name="catid[<?php echo $idx?>]">
390 <?php echo $optionsHtml; ?>
398 <input type="hidden" name="catcount" value="<?php echo $idx?>" />
401 // ----------------------------------------------------------------------------------------
402 case 'ConvertSelectBlog':
404 <h2>Choose Destination Weblog</h2>
407 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.
411 <input name="createnew" value="0" type="radio" checked='checked' id="createnew_no" /><label for="createnew_no">Choose existing weblog to add to:</label>
413 <?php echo $this->getHtmlCode('NucleusBlogSelect'); ?>
416 <input name="createnew" value="1" type="radio" id="createnew_yes" /><label for="createnew_yes">Create new weblog</label>
418 <li>New blog name: <input name="newblogname" /></li>
420 <select name="newowner">
421 <?php echo $this->getHtmlCode('NucleusMemberOptions'); ?>
428 // ----------------------------------------------------------------------------------------
431 <h2>Do the conversion!</h2>
434 <input type="submit" value="Step 3: Do the conversion!" />
435 <input type="hidden" name="action" value="doConversion" />
439 <strong>Note:</strong> Clicking the button once is enough, even if it takes a while to complete.
444 $htmlCode = ob_get_contents();
450 * Create blog if needed
451 * (request vars: blogid, createnew, newblogname, newowner)
455 function getBlogIdFromRequest() {
456 $createnew = intPostVar('createnew');
457 $newowner = intPostVar('newowner');
458 $newblogname = postVar('newblogname');
459 $blogid = intPostVar('blogid');
461 if ($createnew == 1) {
462 // choose unique name
463 $shortname = 'import';
464 if (Blog::exists($shortname)) {
466 while (Blog::exists($shortname . $idx))
468 $shortname = $shortname . $idx;
471 $nucleus_blogid = BlogImport::sql_addToBlog($newblogname, $shortname, $newowner);
473 echo '<h2>Creating new blog</h2>';
474 echo '<p>Your new weblog has been created.</p>';
476 return $nucleus_blogid;
483 function getFromRequest($what) {
488 $authorcount = intPostVar('authorcount');
490 $author = requestArray('author');
491 $memberid = requestIntArray('memberid');
492 $isadmin = requestIntArray('admin');
494 for ($i=0;$i<$authorcount;$i++) {
495 $authorname = undoMagic($author[$i]);
497 // add authors to team
498 $this->oBlog->addTeamMember(intval($memberid[$i]),intval($isadmin[$i]));
500 $aResult[$authorname] = $memberid[$i];
503 $this->aMapUserToNucleusId = $aResult;
507 $this->aMapCategoryToNucleusId = $aResult;
514 function _findCategoryId($name) {
515 $catid = @$this->aMapCategoryToNucleusId[$name];
516 if (!$catid && $this->oBlog)
517 // get default category for weblog
518 $catid = $this->oBlog->getDefaultCategory();
522 function _findMemberId($name) {
523 $memberid = intval(@$this->aMapUserToNucleusId[$name]);
528 * Returns the last error message. Use it to find out the reason for failure
530 function getLastError() {
531 return $this->strErrorMessage;
533 function resetErrorMessage() {
534 $this->strErrorMessage = '';
536 function setErrorMessage($strMsg) {
537 $this->strErrorMessage = $strMsg;
542 * Called by XML parser for each new start element encountered
544 function startElement($parser, $name, $attrs) {
545 if ($this->bDebug) echo 'START: ', $name, '<br />';
550 $this->strImportFileVersion = $attrs['version'];
551 // TODO: check version number
555 $this->aCurrentItem = $this->_blankItem($attrs['id']);
556 if (@$attrs['commentsOnly'] == 'true')
557 $this->aCurrentItem['commentsOnly'] = 1;
559 $this->aCurrentItem['commentsOnly'] = 0;
562 if ($this->inItem || $this->inComment) {
564 $this->currentTSFormat = $attrs['type'];
579 $this->inComment = 1;
580 $this->aCurrentComment = $this->_blankComment($attrs['id']);
591 echo 'UNEXPECTED TAG: ' , $name , '<br />';
595 // character data never contains other tags
596 $this->clearCharacterData();
601 * Called by the XML parser for each closing tag encountered
603 function endElement($parser, $name) {
604 if ($this->bDebug) echo 'END: ', $name, '<br />';
611 if (!$this->bReadNamesOnly) {
613 // TODO: check if succes or failure
614 $this->importOneItem($this->aCurrentItem);
618 // initialize item structure
619 $this->aCurrentItem = $this->_blankItem();
622 $timestamp = $this->getTime($this->getCharacterData(), $this->currentTSFormat);
623 if ($this->inComment)
624 $this->aCurrentComment['timestamp'] = $timestamp;
625 else if ($this->inItem)
626 $this->aCurrentItem['timestamp'] = $timestamp;
629 if ($this->inItem && !$this->inComment)
630 $this->_addAuthorName($this->getCharacterData());
631 if ($this->inComment)
632 $this->aCurrentComment['author'] = $this->getCharacterData();
633 else if ($this->inItem)
634 $this->aCurrentItem['author'] = $this->getCharacterData();
637 if ($this->inComment)
638 $this->aCurrentComment['title'] = $this->getCharacterData();
639 else if ($this->inItem)
640 $this->aCurrentItem['title'] = $this->getCharacterData();
643 if ($this->inComment)
644 $this->aCurrentComment['body'] = $this->getCharacterData();
645 else if ($this->inItem)
646 $this->aCurrentItem['body'] = $this->getCharacterData();
650 $this->aCurrentItem['extended'] = $this->getCharacterData();
653 $this->_addCategoryName($this->getCharacterData());
654 if ($this->inItem && !$this->aCurrentItem['category']) {
655 $this->aCurrentItem['category'] = $this->getCharacterData();
660 $this->aCurrentItem['itemstatus'] = $this->getCharacterData();
664 $this->aCurrentItem['posvotes'] = $this->getCharacterData();
668 $this->aCurrentItem['negvotes'] = $this->getCharacterData();
671 if ($this->inComment) {
672 array_push($this->aCurrentItem['comments'], $this->aCurrentComment);
673 $this->aCurrentComment = $this->_blankComment();
674 $this->inComment = 0;
678 if ($this->inComment)
679 $this->aCurrentComment['email'] = $this->getCharacterData();
682 if ($this->inComment)
683 $this->aCurrentComment['url'] = $this->getCharacterData();
686 if ($this->inComment)
687 $this->aCurrentComment['authorid'] = $this->getCharacterData();
690 if ($this->inComment)
691 $this->aCurrentComment['host'] = $this->getCharacterData();
694 if ($this->inComment)
695 $this->aCurrentComment['ip'] = $this->getCharacterData();
698 echo 'UNEXPECTED TAG: ' , $name, '<br />';
701 $this->clearCharacterData();
706 * Called by XML parser for data inside elements
708 function characterData ($parser, $data) {
709 if ($this->bDebug) echo 'NEW DATA: ', Entity::hsc($data), '<br />';
710 $this->cdata .= $data;
714 * Returns the data collected so far
716 function getCharacterData() {
721 * Clears the data buffer
723 function clearCharacterData() {
728 * Parses a given string into a unix timestamp.
731 * String, formatted as given in $strFormat
733 * Multiple date formats are supported:
734 * 'unix': plain unix timestamp (numeric)
735 * 'blogger': for blogger import: MM/DD/YYYY hh:MM:SS AM
737 function getTime($strTime, $strFormat = 'unix') {
738 $strFormat = strtolower($strFormat);
741 return intval($strTime);
743 // 7/24/2000 11:27:13 AM
744 if (eregi("(.*)/(.*)/(.*) (.*):(.*):(.*) (.*)",$strTime,$regs) != false) {
745 if (($regs[7] == "PM") && ($regs[4] != "12"))
748 return mktime($regs[4],$regs[5],$regs[6],$regs[1],$regs[2],$regs[3]);
756 function _blankItem($id = -1) {
760 'timestamp' => time(),
766 'itemstatus' => 'open',
769 'comments' => array()
773 function _blankComment($id = -1) {
776 'timestamp' => time(),
788 function _addAuthorName($name) {
789 if (!in_array($name, $this->aAuthorNames))
790 array_push($this->aAuthorNames, $name);
793 function _addCategoryName($name) {
794 if (!in_array($name, $this->aCategoryNames))
795 array_push($this->aCategoryNames, $name);
798 function sql_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) {
799 $title = DB::quoteValue(trim($title));
800 $body = DB::quoteValue(trim($body));
801 $more = DB::quoteValue(trim($more));
802 $timestamp = DB::formatDateTime($timestamp);
804 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) '
805 . "VALUES ($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $karmapos, $karmaneg, $category)";
807 if ( DB::execute($query) === FALSE )
809 die('Error while executing query: ' . $query);
812 return DB::getInsertId();
815 function sql_addToBlog($name, $shortname, $ownerid) {
816 $name = DB::quoteValue($name);
817 $shortname = DB::quoteValue($shortname);
819 // create new category first
820 DB::execute('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another category')");
821 $defcat = DB::getInsertId();
823 $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ($name, $shortname, 1, 0, $defcat)";
824 if ( DB::execute($query) === FALSE )
826 die('Error while executing query: ' . $query);
828 $id = DB::getInsertId();
830 // update category row so it links to blog
831 DB::execute('UPDATE ' . sql_table('category') . ' SET cblog=' . intval($id). ' WHERE catid=' . intval($defcat));
833 BlogImport::sql_addToTeam($id,$ownerid,1);
839 function sql_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') {
840 $name = DB::quoteValue($name);
841 $url = DB::quoteValue($url);
842 $body = DB::quoteValue(trim($body));
843 $host = DB::quoteValue($host);
844 $ip = DB::quoteValue($ip);
845 $timestamp = DB::formatDateTime($timestamp);
847 $query = 'INSERT INTO '.sql_table('comment')
848 . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) '
849 . "VALUES ($name, $url, $memberid, $body, $itemid, $timestamp, $host, $blogid, $ip)";
851 if ( DB::execute($query) === FALSE )
853 die('Error while executing query: ' . $query);
856 return DB::getInsertId();
859 function sql_addToTeam($blogid, $memberid, $admin) {
861 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
862 . "VALUES ($memberid, $blogid, $admin)";
864 if ( DB::execute($query) === FALSE )
866 die('Error while executing query: ' . $query);
869 return DB::getInsertId();
874 // some sort of version checking
875 $ver = convert_getNucleusVersion();
877 convert_doError("You should check the Nucleus website for updates to this convert tool. This one might not work with your current Nucleus installation.");
879 // make sure the request variables get reqistered in the global scope
880 // Doing this should be avoided on code rewrite (this is a potential security risk)
881 if ((phpversion() >= "4.1.0") && (ini_get("register_globals") == 0)) {
882 @import_request_variables("gp",'');
885 /** this function gets the nucleus version, even if the getNucleusVersion
886 * function does not exist yet
887 * return 96 for all versions < 100
889 function convert_getNucleusVersion() {
890 if (!function_exists('getNucleusVersion')) return 96;
891 return getNucleusVersion();
894 // TODO: remove this function (replaced by BlogImport::sql_addToItem)
895 function convert_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) {
896 $title = DB::quoteValue(trim($title));
897 $body = DB::quoteValue(trim($body));
898 $more = DB::quoteValue(trim($more));
900 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) '
901 . "VALUES ($title, $body, $more, $blogid, $authorid, '$timestamp', $closed, $karmapos, $karmaneg, $category)";
903 if ( DB::execute($query) === FALSE )
905 die('Error while executing query: ' . $query);
908 return DB::getInsertId();
912 // TODO: remove this function (replaced by BlogImport::sql_addToBlog)
913 function convert_addToBlog($name, $shortname, $ownerid) {
914 $name = DB::quoteValue($name);
915 $shortname = DB::quoteValue($shortname);
917 // create new category first
918 DB::execute('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another categort')");
919 $defcat = DB::getInsertId();
921 $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ($name, $shortname, 1, 0, $defcat)";
922 if ( DB::execute($query) === FALSE )
924 die('Error while executing query: ' . $query);
926 $id = DB::getInsertId();
928 convert_addToTeam($id,$ownerid,1);
933 // TODO: remove this function (replaced by BlogImport::sql_addToComments)
934 function convert_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') {
935 $name = DB::quoteValue($name);
936 $url = DB::quoteValue($url);
937 $body = DB::quoteValue(trim($body));
938 $host = DB::quoteValue($host);
939 $ip = DB::quoteValue($ip);
941 $query = 'INSERT INTO '.sql_table('comment')
942 . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) '
943 . "VALUES ($name, $url, $memberid, $body, $itemid, '$timestamp', $host, $blogid, $ip)";
945 if ( DB::execute($query) === FALSE )
947 die("Error while executing query: " . $query);
950 return DB::getInsertId();
953 // TODO: remove this function (replaced by BlogImport::sql_addToTeam)
954 function convert_addToTeam($blogid, $memberid, $admin) {
956 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
957 . "VALUES ($memberid, $blogid, $admin)";
959 if ( DB::execute($query) === FALSE )
961 die("Error while executing query: " . $query);
964 return DB::getInsertId();
967 function convert_showLogin($type) {
970 <h1>Please Log in First</h1>
971 <p>Enter your data below:</p>
973 <form method="post" action="<?php echo $type?>">
976 <li>Name: <input name="login" /></li>
977 <li>Password <input name="password" type="password" /></li>
981 <input name="action" value="login" type="hidden" />
982 <input type="submit" value="Log in" />
986 <?php convert_foot();
990 function convert_head() {
992 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
993 <html xmlns="http://www.w3.org/1999/xhtml">
995 <title>Nucleus Convert</title>
997 @import url('../styles/manual.css');
1003 function convert_foot() {
1009 function convert_doError($msg) {
1020 <p><a href="index.php" onclick="history.back();">Go Back</a></p>
1026 function endsWithSlash($s) {
1027 return (strrpos($s,'/') == strlen($s) - 1);