OSDN Git Service

db3a01a90e30d21b16a6dd1364a8cede7a1324e2
[nucleus-jp/nucleus-next.git] / nucleus / convert / functions.inc.php
1 <?php
2 /*
3  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
4  * Copyright (C) 2002-2006 The Nucleus Group
5  *
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)
11  */
12 /**
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 $
16  */
17
18 // try to set a long timeout time
19 @set_time_limit(1200);
20
21 /**
22  * Generic class that can import XML files with either blog items or comments
23  * to be imported into a Nucleus blog
24  *
25  */
26 class BlogImport {
27
28         /**
29          * Creates a new BlogImport object
30          *
31          *
32          * @param iBlogId
33          *              Nucleus blogid to which the content of the XML file must be added
34          * @param aOptions
35          *              Import options
36          *                      $aOptions['PreserveIds'] = 1 (NOT IMPLEMENTED)
37          *                              try to use the same ID for the nucleus item as the ID listed
38          *                              in the XML
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)
51          * @param strCallback
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',
56          *              ...)
57          */
58         function BlogImport($iBlogId = -1, $aOptions = array('ReadNamesOnly' => 0), $aMapUserToNucleusId = array(), $aMapCategoryToNucleusId = array(), $strCallback = '') {
59                 global $manager;
60
61                 $this->iBlog                                    = $iBlogId;
62                 if ($iBlogId != -1)
63                         $this->oBlog                            =& $manager->getBlog($iBlogId);
64                 else
65                         $this->oBlog                            = 0;
66                 $this->aOptions                                 = $aOptions;
67                 $this->aMapUserToNucleusId              = $aMapUserToNucleusId;
68                 $this->aMapCategoryToNucleusId  = $aMapCategoryToNucleusId;
69                 $this->strCallback                              = $strCallback;
70                 $this->aMapIdToNucleusId                = array();
71
72                 $this->bReadNamesOnly                   = $this->aOptions['ReadNamesOnly'] == 1;
73                 $this->aCategoryNames                   = array();
74                 $this->aAuthorNames                             = array();
75
76
77                 // disable magic_quotes_runtime if it's turned on
78                 set_magic_quotes_runtime(0);
79
80                 // debugging mode?
81                 $this->bDebug = 0;
82
83                 // XML file pointer
84                 $this->fp = 0;
85
86                 // to maintain track of where we are inside the XML file
87                 $this->inXml            = 0;
88                 $this->inData           = 0;
89                 $this->inItem           = 0;
90                 $this->inComment        = 0;
91                 $this->aCurrentItem = $this->_blankItem();
92                 $this->aCurrentComment = $this->_blankComment();
93
94                 // character data pile
95                 $this->cdata = '';
96
97                 // init XML parser
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);
103
104                 // TODO: add data checking
105                 $this->bValid                                   = 1;
106
107                 // data structures
108                 $this->strErrorMessage                  = '';
109
110         }
111
112         /**
113          * Gets the import library version
114          */
115         function getVersion() {
116                 return '0.2';
117         }
118
119         /**
120          * Returns an array with all the author names used in the file (only
121          * the authors of items are included)
122          *
123          * @require importXmlFile should be called prior to calling this
124          */
125         function getAuthorNames() {
126                 return $this->aAuthorNames;
127         }
128
129         /**
130          * Returns an array with all the category names used in the file
131          *
132          * @require importXmlFile should be called prior to calling this
133          */
134         function getCategoryNames() {
135                 return $this->aCategoryNames;
136         }
137
138         /**
139          * Imports an XML file into a given blog
140          *
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)
145          *
146          * @param strXmlFile
147          *              Location of the XML file. The XML file must be in the correct
148          *              Nucleus import format
149          * @returns
150          *              0 on failure. Use getLastError() to get error message
151          *              1 on success
152          *
153          */
154         function importXmlFile($strXmlFile) {
155                 $this->resetErrorMessage();
156
157                 flush();
158
159                 if (!$this->bValid)
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');
165
166                 // open file
167                 $this->fp = @fopen($strXmlFile, 'r');
168                 if (!$this->fp)
169                         return $this->setErrorMessage('Failed to open file/URL');
170
171                 // here we go!
172                 $this->inXml = 1;
173
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 />';
179                 }
180
181                 // all done
182                 $this->inXml = 0;
183                 fclose($this->fp);
184
185                 return 1;
186         }
187
188         /**
189          * Identical to importXmlFile, but takes an almost-ready-for-addition array
190          *
191          * @param aData
192          *              Array with item data, as prepared by import_fromXML
193          *
194          * @returns
195          *              0 on failure. Use getLastError() to get error message
196          *              1 on success
197          */
198         function importOneItem(&$aData) {
199                 $this->resetErrorMessage();
200
201                 // - do some logic to determine nucleus users and categories
202                 // * find member id
203                 // * find blog id
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'];
210                 }
211
212                 // - apply logic to comments
213                 foreach (array_keys($aData['comments']) as $key) {
214                         // * find member id
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'];
222
223                                 if (!$authid && $url)
224                                         $aData['comments'][$key]['authorid'] = $url;
225                                 else if (!$authid && $email)
226                                         $aData['comments'][$key]['authorid'] = $email;
227                         }
228                 }
229
230                 // - call callback
231                 if ($this->strCallback && function_exists($this->strCallback)) {
232                         call_user_func_array($this->strCallback, array(&$aData));
233                 }
234
235                 if ($this->bDebug) {
236                         echo '<pre>';
237                         print_r($aData);
238                         echo '</pre>';
239                 }
240
241                 // - insert item into nucleus database
242                 $iNewId = $this->sql_addToItem(
243                         $aData['title'],
244                         $aData['body'],
245                         $aData['extended'],
246                         $aData['nucleus_blogid'],
247                         $aData['nucleus_memberid'],
248                         $aData['timestamp'],
249                         ($aData['itemstatus'] == 'open') ? 0 : 1,
250                         $aData['nucleus_catid'],
251                         $aData['posvotes'],
252                         $aData['negvotes']
253                 );
254
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'];
259
260                 // - insert comments into nucleus database
261                 foreach ($aData['comments'] as $comment) {
262                         $cId = $this->sql_addToComments(
263                                 $comment['author'],
264                                 $comment['authorid'],
265                                 $comment['body'],
266                                 $aData['nucleus_blogid'],
267                                 $aData['nucleus_id'],
268                                 $comment['nucleus_memberid'],
269                                 $comment['timestamp'],
270                                 $comment['host'],
271                                 $comment['ip']
272                         );
273                 }
274
275                 echo ' .'; // progress indicator
276                 flush();
277
278                 return 1;
279         }
280
281         function getHtmlCode($what) {
282                 ob_start();
283                 switch($what) {
284 // ----------------------------------------------------------------------------------------
285                         case 'NucleusMemberOptions':
286                                 $res = sql_query('SELECT mname as text, mnumber as value FROM '.sql_table('member'));
287                                 while ($o = mysql_fetch_object($res)) {
288                                         echo '<option value="'.i18n::hsc($o->value).'">'.i18n::hsc($o->text).'</option>';
289                                 }
290                                 break;
291 // ----------------------------------------------------------------------------------------
292                         case 'NucleusBlogSelect':
293                                 $query =  'SELECT bname as text, bnumber as value FROM '.sql_table('blog');
294                                 $template['name'] = 'blogid';
295                                 $template['selected'] = $CONF['DefaultBlog'];
296                                 showlist($query,'select',$template);
297                                 break;
298 // ----------------------------------------------------------------------------------------
299                         case 'ConvertSelectMembers':
300                         ?>
301                                 <h2>Assign Members to Authors</h2>
302
303                                 <p>
304                                 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.
305                                 </p>
306
307
308                                 <table>
309                                 <tr>
310                                         <th>Author</th>
311                                         <th>Nucleus Member</th>
312                                         <th>Blog Admin?</th>
313                                 </tr>
314
315                                 <?php
316
317                                 $authors = $this->getAuthorNames();
318
319                                 // get HTML code for selection list
320                                 $optionsHtml = $this->getHtmlCode('NucleusMemberOptions');
321                                 $idx = 0;
322                                 while ($a_name = array_pop($authors)) {
323                                         ?>
324                                                 <tr>
325                                                         <td>
326                                                                 <strong><?php echo $a_name?></strong>
327                                                                 <input name="author[<?php echo $idx?>]" value="<?php echo i18n::hsc($a_name)?>" type="hidden"
328                                                         </td>
329                                                         <td>
330                                                                 <select name="memberid[<?php echo $idx?>]">
331                                                                         <?php echo $optionsHtml; ?>
332                                                                 </select>
333                                                         </td>
334                                                         <td>
335                                                                 <input name="admin[<?php echo $idx?>]" type="checkbox" value="1" id="admin<?php echo $idx?>" /><label for="admin<?php echo $idx?>">Blog Admin</label>
336                                                         </td>
337                                                 </tr>
338                                         <?php   $idx++;
339                                 } // while
340
341                                 ?>
342                                         <tr>
343                                                 <td><em>Default Member</em></td>
344                                                 <td>
345                                                         <input name="author[<?php echo $idx?>]" value="_default" type="hidden"
346                                                         <select name="memberid[<?php echo $idx?>]">
347                                                                 <?php echo $optionsHtml; ?>
348                                                         </select>
349                                                         <td><input name="admin[<?php echo $idx?>]" type="hidden" value="0" id="admin<?php echo $idx?>" /></td>
350                                                 </td>
351
352                                         </tr>
353                                 </table>
354                                 <input type="hidden" name="authorcount" value="<?php echo ++$idx?>" />
355                         <?php
356                                 break;
357 // ----------------------------------------------------------------------------------------
358                         case 'ConvertSelectCategories':
359                         ?>
360                                 <h2>Assign Categories</h2>
361
362                                 <p>
363                                 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.
364                                 </p>
365
366
367                                 <table>
368                                 <tr>
369                                         <th>Category</th>
370                                         <th>Nucleus Category</th>
371                                 </tr>
372
373                                 <?php
374
375                                 $catnames = $this->getCategoryNames();
376
377                                 // get HTML code for selection list
378                                 $optionsHtml = $this->getHtmlCode('NucleusCategoryOptions');
379                                 $idx = 0;
380                                 while ($a_name = array_pop($catnames)) {
381                                         ?>
382                                                 <tr>
383                                                         <td>
384                                                                 <strong><?php echo $a_name?></strong>
385                                                                 <input name="category[<?php echo $idx?>]" value="<?php echo i18n::hsc($a_name)?>" type="hidden"
386                                                         </td>
387                                                         <td>
388                                                                 <select name="catid[<?php echo $idx?>]">
389                                                                         <?php echo $optionsHtml; ?>
390                                                                 </select>
391                                                         </td>
392                                                 </tr>
393                                         <?php   $idx++;
394                                 } // while
395                                 ?>
396                                 </table>
397                                 <input type="hidden" name="catcount" value="<?php echo $idx?>" />
398                         <?php
399                                 break;
400 // ----------------------------------------------------------------------------------------
401                         case 'ConvertSelectBlog':
402                         ?>
403                                 <h2>Choose Destination Weblog</h2>
404
405                                 <p>
406                                 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.
407                                 </p>
408
409                                 <div>
410                                         <input name="createnew" value="0" type="radio" checked='checked' id="createnew_no" /><label for="createnew_no">Choose existing weblog to add to:</label>
411
412                                         <?php echo $this->getHtmlCode('NucleusBlogSelect'); ?>
413                                 </div>
414                                 <div>
415                                         <input name="createnew" value="1" type="radio" id="createnew_yes" /><label for="createnew_yes">Create new weblog</label>
416                                         <ul>
417                                                 <li>New blog name: <input name="newblogname" /></li>
418                                                 <li>Blog owner:
419                                                         <select name="newowner">
420                                                                 <?php echo $this->getHtmlCode('NucleusMemberOptions'); ?>
421                                                         </select>
422                                                 </li>
423                                         </ul>
424                                 </div>
425                         <?php
426                                 break;
427 // ----------------------------------------------------------------------------------------
428                         case 'ConvertStart':
429                         ?>
430                                 <h2>Do the conversion!</h2>
431
432                                 <p>
433                                 <input type="submit" value="Step 3: Do the conversion!" />
434                                 <input type="hidden" name="action" value="doConversion" />
435                                 </p>
436
437                                 <div class="note">
438                                 <strong>Note:</strong> Clicking the button once is enough, even if it takes a while to complete.
439                                 </div>
440                         <?php
441                                 break;
442                 }
443                 $htmlCode = ob_get_contents();
444                 ob_end_clean();
445                 return $htmlCode;
446         }
447
448         /**
449          * Create blog if needed
450          * (request vars: blogid, createnew, newblogname, newowner)
451          *
452          * (static!)
453          */
454         function getBlogIdFromRequest() {
455                 $createnew              = intPostVar('createnew');
456                 $newowner               = intPostVar('newowner');
457                 $newblogname    = postVar('newblogname');
458                 $blogid                 = intPostVar('blogid');
459
460                 if ($createnew == 1) {
461                         // choose unique name
462                         $shortname = 'import';
463                         if (BLOG::exists($shortname)) {
464                                 $idx = 1;
465                                 while (BLOG::exists($shortname . $idx))
466                                         $idx++;
467                                 $shortname = $shortname . $idx;
468                         }
469
470                         $nucleus_blogid = BlogImport::sql_addToBlog($newblogname, $shortname, $newowner);
471
472                         echo '<h2>Creating new blog</h2>';
473                         echo '<p>Your new weblog has been created.</p>';
474
475                         return $nucleus_blogid;
476                 } else {
477                         return $blogid;
478                 }
479
480         }
481
482         function getFromRequest($what) {
483                 $aResult = array();
484
485                 switch ($what) {
486                         case 'authors':
487                                 $authorcount = intPostVar('authorcount');
488
489                                 $author = requestArray('author');
490                                 $memberid = requestIntArray('memberid');
491                                 $isadmin = requestIntArray('admin');
492
493                                 for ($i=0;$i<$authorcount;$i++) {
494                                         $authorname = undoMagic($author[$i]);
495
496                                         // add authors to team
497                                         $this->oBlog->addTeamMember(intval($memberid[$i]),intval($isadmin[$i]));
498
499                                         $aResult[$authorname] = $memberid[$i];
500                                 }
501
502                                 $this->aMapUserToNucleusId = $aResult;
503                                 break;
504                         case 'categories':
505                                 // TODO
506                                 $this->aMapCategoryToNucleusId = $aResult;
507                                 break;
508                 }
509
510                 return $aResult;
511         }
512
513         function _findCategoryId($name) {
514                 $catid = @$this->aMapCategoryToNucleusId[$name];
515                 if (!$catid && $this->oBlog)
516                         // get default category for weblog
517                         $catid = $this->oBlog->getDefaultCategory();
518                 return $catid;
519         }
520
521         function _findMemberId($name) {
522                 $memberid = intval(@$this->aMapUserToNucleusId[$name]);
523                 return $memberid;
524         }
525
526         /**
527          * Returns the last error message. Use it to find out the reason for failure
528          */
529         function getLastError() {
530                 return $this->strErrorMessage;
531         }
532         function resetErrorMessage() {
533                 $this->strErrorMessage = '';
534         }
535         function setErrorMessage($strMsg) {
536                 $this->strErrorMessage = $strMsg;
537                 return 0;
538         }
539
540         /**
541          * Called by XML parser for each new start element encountered
542          */
543         function startElement($parser, $name, $attrs) {
544                 if ($this->bDebug) echo 'START: ', $name, '<br />';
545
546                 switch ($name) {
547                         case 'blog':
548                                 $this->inData = 1;
549                                 $this->strImportFileVersion = $attrs['version'];
550                                 // TODO: check version number
551                                 break;
552                         case 'item':
553                                 $this->inItem = 1;
554                                 $this->aCurrentItem = $this->_blankItem($attrs['id']);
555                                 if (@$attrs['commentsOnly'] == 'true')
556                                         $this->aCurrentItem['commentsOnly'] = 1;
557                                 else
558                                         $this->aCurrentItem['commentsOnly'] = 0;
559                                 break;
560                         case 'timestamp':
561                                 if ($this->inItem || $this->inComment) {
562                                         // store time format
563                                         $this->currentTSFormat = $attrs['type'];
564                                 }
565                                 break;
566                         case 'author':
567                         case 'title':
568                         case 'body':
569                         case 'extended':
570                         case 'category':
571                         case 'itemstatus':
572                         case 'posvotes':
573                         case 'negvotes':
574                                 // nothing to do
575                                 break;
576                         case 'comment':
577                                 if ($this->inItem) {
578                                         $this->inComment = 1;
579                                         $this->aCurrentComment = $this->_blankComment($attrs['id']);
580                                 }
581                                 break;
582                         case 'email':
583                         case 'url':
584                         case 'authorid':
585                         case 'host':
586                         case 'ip':
587                                 // nothing to do
588                                 break;
589                         default:
590                                 echo 'UNEXPECTED TAG: ' , $name , '<br />';
591                                 break;
592                 }
593
594                 // character data never contains other tags
595                 $this->clearCharacterData();
596
597         }
598
599         /**
600           * Called by the XML parser for each closing tag encountered
601           */
602         function endElement($parser, $name) {
603                 if ($this->bDebug) echo 'END: ', $name, '<br />';
604
605                 switch ($name) {
606                         case 'blog':
607                                 $this->inData = 0;
608                                 break;
609                         case 'item':
610                                 if (!$this->bReadNamesOnly) {
611                                         // write to database
612                                         // TODO: check if succes or failure
613                                         $this->importOneItem($this->aCurrentItem);
614                                 }
615                                 $this->inItem = 0;
616
617                                 // initialize item structure
618                                 $this->aCurrentItem = $this->_blankItem();
619                                 break;
620                         case 'timestamp':
621                                 $timestamp = $this->getTime($this->getCharacterData(), $this->currentTSFormat);
622                                 if ($this->inComment)
623                                         $this->aCurrentComment['timestamp'] = $timestamp;
624                                 else if ($this->inItem)
625                                         $this->aCurrentItem['timestamp'] = $timestamp;
626                                 break;
627                         case 'author':
628                                 if ($this->inItem && !$this->inComment)
629                                         $this->_addAuthorName($this->getCharacterData());
630                                 if ($this->inComment)
631                                         $this->aCurrentComment['author'] = $this->getCharacterData();
632                                 else if ($this->inItem)
633                                         $this->aCurrentItem['author'] = $this->getCharacterData();
634                                 break;
635                         case 'title':
636                                 if ($this->inComment)
637                                         $this->aCurrentComment['title'] = $this->getCharacterData();
638                                 else if ($this->inItem)
639                                         $this->aCurrentItem['title'] = $this->getCharacterData();
640                                 break;
641                         case 'body':
642                                 if ($this->inComment)
643                                         $this->aCurrentComment['body'] = $this->getCharacterData();
644                                 else if ($this->inItem)
645                                         $this->aCurrentItem['body'] = $this->getCharacterData();
646                                 break;
647                         case 'extended':
648                                 if ($this->inItem)
649                                         $this->aCurrentItem['extended'] = $this->getCharacterData();
650                                 break;
651                         case 'category':
652                                 $this->_addCategoryName($this->getCharacterData());
653                                 if ($this->inItem && !$this->aCurrentItem['category']) {
654                                         $this->aCurrentItem['category'] = $this->getCharacterData();
655                                 }
656                                 break;
657                         case 'itemstatus':
658                                 if ($this->inItem)
659                                         $this->aCurrentItem['itemstatus'] = $this->getCharacterData();
660                                 break;
661                         case 'posvotes':
662                                 if ($this->inItem)
663                                         $this->aCurrentItem['posvotes'] = $this->getCharacterData();
664                                 break;
665                         case 'negvotes':
666                                 if ($this->inItem)
667                                         $this->aCurrentItem['negvotes'] = $this->getCharacterData();
668                                 break;
669                         case 'comment':
670                                 if ($this->inComment) {
671                                         array_push($this->aCurrentItem['comments'], $this->aCurrentComment);
672                                         $this->aCurrentComment = $this->_blankComment();
673                                         $this->inComment = 0;
674                                 }
675                                 break;
676                         case 'email':
677                                 if ($this->inComment)
678                                         $this->aCurrentComment['email'] = $this->getCharacterData();
679                                 break;
680                         case 'url':
681                                 if ($this->inComment)
682                                         $this->aCurrentComment['url'] = $this->getCharacterData();
683                                 break;
684                         case 'authorid':
685                                 if ($this->inComment)
686                                         $this->aCurrentComment['authorid'] = $this->getCharacterData();
687                                 break;
688                         case 'host':
689                                 if ($this->inComment)
690                                         $this->aCurrentComment['host'] = $this->getCharacterData();
691                                 break;
692                         case 'ip':
693                                 if ($this->inComment)
694                                         $this->aCurrentComment['ip'] = $this->getCharacterData();
695                                 break;
696                         default:
697                                 echo 'UNEXPECTED TAG: ' , $name, '<br />';
698                                 break;
699                 }
700                 $this->clearCharacterData();
701
702         }
703
704         /**
705          * Called by XML parser for data inside elements
706          */
707         function characterData ($parser, $data) {
708                 if ($this->bDebug) echo 'NEW DATA: ', i18n::hsc($data), '<br />';
709                 $this->cdata .= $data;
710         }
711
712         /**
713          * Returns the data collected so far
714          */
715         function getCharacterData() {
716                 return $this->cdata;
717         }
718
719         /**
720          * Clears the data buffer
721          */
722         function clearCharacterData() {
723                 $this->cdata = '';
724         }
725
726         /**
727          * Parses a given string into a unix timestamp.
728          *
729          * @param strTime
730          *              String, formatted as given in $strFormat
731          * @param strFormat
732          *              Multiple date formats are supported:
733          *                      'unix': plain unix timestamp (numeric)
734          *                      'blogger': for blogger import: MM/DD/YYYY hh:MM:SS AM
735          */
736         function getTime($strTime, $strFormat = 'unix') {
737                 $strFormat = strtolower($strFormat);
738                 switch($strFormat) {
739                         case 'unix':
740                                 return intval($strTime);
741                         case 'blogger':
742                                 // 7/24/2000 11:27:13 AM
743                                 if (eregi("(.*)/(.*)/(.*) (.*):(.*):(.*) (.*)",$strTime,$regs) != false) {
744                                         if (($regs[7] == "PM") && ($regs[4] != "12"))
745                                                 $regs[4] += 12;
746
747                                         return mktime($regs[4],$regs[5],$regs[6],$regs[1],$regs[2],$regs[3]);
748                                 } else {
749                                         return 0;
750                                 }
751                 }
752         }
753
754
755         function _blankItem($id = -1) {
756                 return array(
757                                 'id'                    => $id,
758                                 'commentsOnly'  => 0,
759                                 'timestamp'     => time(),
760                                 'author'                => '',
761                                 'title'                 => '',
762                                 'body'                  => '',
763                                 'extended'              => '',
764                                 'category'              => '',
765                                 'itemstatus'    => 'open',
766                                 'posvotes'              => 0,
767                                 'negvotes'              => 0,
768                                 'comments'              => array()
769                 );
770         }
771
772         function _blankComment($id = -1) {
773                 return array(
774                                 'id'                    => $id,
775                                 'timestamp'     => time(),
776                                 'author'                => '',
777                                 'title'                 => '',
778                                 'body'                  => '',
779                                 'email'                 => '',
780                                 'url'                   => '',
781                                 'authorid'              => '',
782                                 'host'                  => '',
783                                 'ip'                    => ''
784                 );
785         }
786
787         function _addAuthorName($name) {
788                 if (!in_array($name, $this->aAuthorNames))
789                         array_push($this->aAuthorNames, $name);
790         }
791
792         function _addCategoryName($name) {
793                 if (!in_array($name, $this->aCategoryNames))
794                         array_push($this->aCategoryNames, $name);
795         }
796
797         function sql_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) {
798                 $title          = trim(addslashes($title));
799                 $body           = trim(addslashes($body));
800                 $more           = trim(addslashes($more));
801                 $timestamp      = date("Y-m-d H:i:s", $timestamp);
802
803                 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) '
804                            . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $karmapos, $karmaneg,  $category)";
805
806                 mysql_query($query) or die("Error while executing query: " . $query);
807
808                 return mysql_insert_id();
809         }
810
811         function sql_addToBlog($name, $shortname, $ownerid) {
812                 $name           = addslashes($name);
813                 $shortname      = addslashes($shortname);
814
815                 // create new category first
816                 mysql_query('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another category')");
817                 $defcat = mysql_insert_id();
818
819                 $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ('$name','$shortname',1 ,0, $defcat)";
820                 mysql_query($query) or die("Error while executing query: " . $query);
821                 $id = mysql_insert_id();
822
823                 // update category row so it links to blog
824                 mysql_query('UPDATE ' . sql_table('category') . ' SET cblog=' . intval($id). ' WHERE catid=' . intval($defcat));
825
826                 BlogImport::sql_addToTeam($id,$ownerid,1);
827
828
829                 return $id;
830         }
831
832         function sql_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') {
833                 $name           = addslashes($name);
834                 $url            = addslashes($url);
835                 $body           = trim(addslashes($body));
836                 $host           = addslashes($host);
837                 $ip             = addslashes($ip);
838                 $timestamp      = date("Y-m-d H:i:s", $timestamp);
839
840                 $query = 'INSERT INTO '.sql_table('comment')
841                            . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) '
842                            . "VALUES ('$name', '$url', $memberid, '$body', $itemid, '$timestamp', '$host', $blogid, '$ip')";
843
844                 mysql_query($query) or die("Error while executing query: " . $query);
845
846                 return mysql_insert_id();
847         }
848
849         function sql_addToTeam($blogid, $memberid, $admin) {
850
851                 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
852                            . "VALUES ($memberid, $blogid, $admin)";
853
854                 mysql_query($query) or die("Error while executing query: " . $query);
855
856                 return mysql_insert_id();
857         }
858
859
860
861 }
862
863 // some sort of version checking
864 $ver = convert_getNucleusVersion();
865 if ($ver > 250)
866         convert_doError("You should check the Nucleus website for updates to this convert tool. This one might not work with your current Nucleus installation.");
867
868         // make sure the request variables get reqistered in the global scope
869         // Doing this should be avoided on code rewrite (this is a potential security risk)
870         if ((phpversion() >= "4.1.0") && (ini_get("register_globals") == 0)) {
871                 @import_request_variables("gp",'');
872         }
873
874         /** this function gets the nucleus version, even if the getNucleusVersion
875          * function does not exist yet
876          * return 96 for all versions < 100
877          */
878         function convert_getNucleusVersion() {
879                 if (!function_exists('getNucleusVersion')) return 96;
880                 return getNucleusVersion();
881         }
882
883         // TODO: remove this function (replaced by BlogImport::sql_addToItem)
884         function convert_addToItem($title, $body, $more, $blogid, $authorid, $timestamp, $closed, $category, $karmapos, $karmaneg) {
885                 $title = trim(addslashes($title));
886                 $body = trim(addslashes($body));
887                 $more = trim(addslashes($more));
888
889                 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IKARMAPOS, IKARMANEG, ICAT) '
890                            . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $karmapos, $karmaneg,  $category)";
891
892                 mysql_query($query) or die("Error while executing query: " . $query);
893
894                 return mysql_insert_id();
895         }
896
897
898         // TODO: remove this function (replaced by BlogImport::sql_addToBlog)
899         function convert_addToBlog($name, $shortname, $ownerid) {
900                 $name = addslashes($name);
901                 $shortname = addslashes($shortname);
902
903                 // create new category first
904                 mysql_query('INSERT INTO '.sql_table('category')." (CNAME, CDESC) VALUES ('General','Items that do not fit in another categort')");
905                 $defcat = mysql_insert_id();
906
907                 $query = 'INSERT INTO '.sql_table('blog')." (BNAME, BSHORTNAME, BCOMMENTS, BMAXCOMMENTS, BDEFCAT) VALUES ('$name','$shortname',1 ,0, $defcat)";
908                 mysql_query($query) or die("Error while executing query: " . $query);
909                 $id = mysql_insert_id();
910
911                 convert_addToTeam($id,$ownerid,1);
912
913
914                 return $id;
915         }
916
917         // TODO: remove this function (replaced by BlogImport::sql_addToComments)
918         function convert_addToComments($name, $url, $body, $blogid, $itemid, $memberid, $timestamp, $host, $ip='') {
919                 $name = addslashes($name);
920                 $url = addslashes($url);
921                 $body = trim(addslashes($body));
922                 $host = addslashes($host);
923                 $ip = addslashes($ip);
924
925                 $query = 'INSERT INTO '.sql_table('comment')
926                            . ' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CBLOG, CIP) '
927                            . "VALUES ('$name', '$url', $memberid, '$body', $itemid, '$timestamp', '$host', $blogid, '$ip')";
928
929                 mysql_query($query) or die("Error while executing query: " . $query);
930
931                 return mysql_insert_id();
932         }
933
934         // TODO: remove this function (replaced by BlogImport::sql_addToTeam)
935         function convert_addToTeam($blogid, $memberid, $admin) {
936
937                 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
938                            . "VALUES ($memberid, $blogid, $admin)";
939
940                 mysql_query($query) or die("Error while executing query: " . $query);
941
942                 return mysql_insert_id();
943         }
944
945         function convert_showLogin($type) {
946                 convert_head();
947         ?>
948                 <h1>Please Log in First</h1>
949                 <p>Enter your data below:</p>
950
951                 <form method="post" action="<?php echo $type?>">
952
953                         <ul>
954                                 <li>Name: <input name="login" /></li>
955                                 <li>Password <input name="password" type="password" /></li>
956                         </ul>
957
958                         <p>
959                                 <input name="action" value="login" type="hidden" />
960                                 <input type="submit" value="Log in" />
961                         </p>
962
963                 </form>
964         <?php           convert_foot();
965                 exit;
966         }
967
968         function convert_head() {
969         ?>
970                 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
971                 <html xmlns="http://www.w3.org/1999/xhtml">
972                 <head>
973                         <title>Nucleus Convert</title>
974                         <style><!--
975                                 @import url('../styles/manual.css');
976                         --></style>
977                 </head>
978                 <body>
979         <?php   }
980
981         function convert_foot() {
982         ?>
983                 </body>
984                 </html>
985         <?php   }
986
987         function convert_doError($msg) {
988                 convert_head();
989                 ?>
990                 <h1>Error!</h1>
991
992                 <p>Message was:</p>
993
994                 <blockquote><div>
995                 <?php echo $msg?>
996                 </div></blockquote>
997
998                 <p><a href="index.php" onclick="history.back();">Go Back</a></p>
999                 <?php
1000                 convert_foot();
1001                 exit;
1002         }
1003
1004         function endsWithSlash($s) {
1005                 return (strrpos($s,'/') == strlen($s) - 1);
1006         }
1007
1008
1009 ?>