OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / convert / bloggercaif.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  * This script will import a Blogger blog into a Nucleus blog, using
14  * a easy to use wizard.
15  *
16  * Notes:
17  *   - Templates are not converted
18  *   - Nucleus should already be installed
19  *       - Members should exist for all teammembers
20  *
21  * @license http://nucleuscms.org/license.txt GNU General Public License
22  * @copyright Copyright (C) 2002-2006 The Nucleus Group
23  * @version $Id: bloggercaif.php 1889 2012-06-17 08:46:45Z sakamocchi $
24  */
25
26 include("../../config.php");
27 include("functions.inc.php");
28 include($DIR_LIBS . "ADMIN.php");
29 include($DIR_LIBS . "MEDIA.php");
30
31 if (!$member->isLoggedIn()) {
32         convert_showLogin('bloggercaif.php');
33 }
34
35 if (!$member->isAdmin()) {
36         convert_doError('Only Super-Admins are allowed to perform blog conversions');
37 }
38
39 $ver = convert_getNucleusVersion();
40 if ($ver > 210)
41         convert_doError("You should check the Nucleus website for updates to this convert tool. This one might not work with your current Nucleus installation.");
42
43 // include PRAX lib (to read XML files easily)
44 include ('PRAX.php');
45
46 switch($action) {
47         case "assignMembers":
48                 bc_assignMembers(); break;
49         case "showOverview":
50                 bc_showOverview(); break;
51         case "doConversion":
52                 bc_doConversion(); break;
53         case "login": // drop through
54         default:
55                 bc_getBloggerBlogID();
56 }
57
58 // step 1: get the Blogger Blog ID
59 function bc_getBloggerBlogID() {
60         global $HTTP_SERVER_VARS, $PHP_SELF;
61
62         convert_head();
63
64         ?>
65                 <div class="note">
66                 <b>Note:</b> This conversion tool was written for Free Blogger blogs. If you use it for BloggerPro blogs, you'll lose the titles of your posts (as I currently have no information on the templating system of BloggerPro)
67                 </div>
68
69                 <h1>Step 1: Exporting to a file</h1>
70
71                 <p>
72                 The first step in the conversion is to export all your Blogger entries into one single file. This is done by logging in in Blogger and by temporary changing your settings and templates.
73                 <br />The full procedure is explained below:
74                 </p>
75
76                 <h2>Exporting from Blogger</h2>
77
78                 <div class="note"><b>Note:</b> If you intend to keep using your weblog afterwards, write down the changes you made, so they can be undone afterwards. For the templates, copy paste the old ones in a textfile.</div>
79
80                 <ol>
81                         <li>
82                                 Log into <a href="http://www.blogger.com/">Blogger</a> and go to the blog you want to export.
83                         </li>
84                         <li>
85                                 Change the template of your blog to the following:
86
87                                 <pre>
88 &lt;?xml version="1.0"?&gt;
89
90 &lt;bloggerblog&gt;
91
92  &lt;Blogger&gt;
93
94   &lt;blogentry&gt;
95    &lt;bloggerid&gt;&lt;$BlogItemNumber$&gt;&lt;/bloggerid&gt;
96    &lt;body&gt;&lt;![CDATA[&lt;$BlogItemBody$&gt;]]&gt;&lt;/body&gt;
97    &lt;date&gt;&lt;$BlogItemDateTime$&gt;&lt;/date&gt;
98    &lt;author&gt;&lt;$BlogItemAuthor$&gt;&lt;/author&gt;
99   &lt;/blogentry&gt;
100
101  &lt;/Blogger&gt;
102
103 &lt;/bloggerblog&gt;
104                                 </pre>
105                                 Don't forget to save changes!
106                         </li>
107                         <li>
108                                 Go to the settings and change the following options:
109                                 <ul>
110                                         <li>
111                                                 Blog filename: <b>blogger.xml</b>
112                                         </li>
113                                         <li>
114                                                 Show <b>900</b> <b>day's posts</b> on main page
115                                         </li>
116                                         <li>
117                                                 Date/Time Format: <b>MM/DD/YYYY HH:MM:SS AM|PM</b> (that option is not listed as such, instead it has the current date filled in)
118                                         </li>
119                                         <li>
120                                                 Archive Frequency: <b>No Archive</b>
121                                         </li>
122                                 </ul>
123                         </li>
124                         <li>
125                                 Save the settings and publish your blog. You'll end up with a blogger.xml file on your server containing all of your blog items.
126                         </li>
127                         <li>
128                                 If you're running blogspot, you'll need to edit this file and take out the advertising banner code.
129                         </li>
130                 </ol>
131
132                 <h2>Exporting comments to CAIF (Instructions for YACCS)</h2>
133
134                 <ol>
135                         <li>Log into YACCS</li>
136                         <li>Export using the CAIF format. This will result in an XML file, which you should save as <tt>caif.xml</tt> on your computer.</li>
137                 </ol>
138
139                 <h2>Importing</h2>
140
141                 <p>
142                 Now you have two files (<b>blogger.xml</b> and <b>caif.xml</b>). Upload both to the same directory as the convert files (/nucleus/convert) and continue to the next step.
143                 </p>
144
145                 <p>
146                 <form method="post" action="bloggercaif.php">
147                 <input type="submit" value="Next Step: Assign Members to Authors" />
148                 <input type="hidden" name="action" value="assignMembers" />
149                 </form>
150                 </p>
151
152         <?php
153         convert_foot();
154 }
155
156
157 function bc_assignMembers() {
158         global $HTTP_POST_VARS, $CONF;
159
160         // some checks
161         if (!file_exists('blogger.xml'))
162                 convert_doError("blogger.xml not found. Make sure it is in the correct directory");
163         if (!is_readable('blogger.xml'))
164                 convert_doError("The blogger.xml file is not readable. Make sure the file permissions are set correctly so PHP can access it.");
165         if (!file_exists('caif.xml'))
166                 convert_doError("caif.xml not found. Make sure it is in the correct directory");
167         if (!is_readable('caif.xml'))
168                 convert_doError("The caif.xml file is not readable. Make sure the file permissions are set correctly so PHP can access it.");
169
170         convert_head();
171
172         ?>
173                 <form method="post" action="bloggercaif.php">
174
175
176                 <h1>Step 2: Assign Members to Authors</h1>
177
178                 <p>
179                 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.
180                 </p>
181
182
183                 <table>
184                 <tr>
185                         <th>Blogger Author</th>
186                         <th>Nucleus Member</th>
187                         <th>Blog Admin?</th>
188                 </tr>
189
190                 <?php
191                 $blog = new RAX();
192                 $blog->openfile('blogger.xml');
193                 $blog->record_delim = 'blogentry';
194                 $blog->parse();
195
196
197                 $authors = array();
198
199
200                 while ( $entry = $blog->readRecord() )  {
201                         $row = $entry->getRow();
202
203                         // handle one item
204                         if (!in_array($row['author'],$authors))
205                                 array_push($authors,$row['author']);
206
207                 }
208
209                 $blog->close(); // close the file
210                 $idx = 0;
211
212 while ($a_name = array_pop($authors)) {
213         ?>
214                 <tr>
215                         <td>
216                                 <b><?php echo $a_name?></b>
217                                 <input name="author[<?php echo $idx?>]" value="<?php echo Entity::hsc($a_name)?>" type="hidden" />
218                         </td>
219                         <td>
220                 <?php                   $query =  'SELECT mname as text, mnumber as value FROM '.sql_table('member');
221
222                         $template['name'] = 'memberid[' . $idx . ']';
223                         echo showlist($query,'select',$template);
224                 ?>
225                         </td>
226                         <td>
227                                 <input name="admin[<?php echo $idx?>]" type="checkbox" value="1" id="admin<?php echo $idx?>" /><label for="admin<?php echo $idx?>">Blog Admin</label>
228                         </td>
229                 </tr>
230         <?php   $idx++;
231 } // while
232
233
234                 ?>
235                 </table>
236
237
238                 <h1>Choose Destination Weblog</h1>
239
240                 <p>
241                 There are two options: you can either choose an existing blog to add the blogger entries into, or you can choose to create a new weblog.
242                 </p>
243
244                 <div>
245                         <input name="createnew" value="0" type="radio" checked='checked' id="createnew_no" /><label for="createnew_no">Choose existing weblog to add to:</label>
246
247                         <?php                                   $query =  'SELECT bname as text, bnumber as value FROM '.sql_table('blog');
248                                         $template['name'] = 'blogid';
249                                         $template['selected'] = $CONF['DefaultBlog'];
250                                         echo showlist($query,'select',$template);
251                         ?>
252                 </div>
253                 <div>
254                         <input name="createnew" value="1" type="radio" id="createnew_yes" /><label for="createnew_yes">Create new weblog</label>
255                         <ul>
256                                 <li>New blog name: <input name="newblogname" /></li>
257                                 <li>Blog owner:
258                                 <?php                                   $query =  'SELECT mname as text, mnumber as value FROM '.sql_table('member');
259
260                                         $template['name'] = 'newowner';
261                                         echo showlist($query,'select',$template);
262                                 ?>
263                                 </li>
264                         </ul>
265                 </div>
266
267                 <h1>Do the conversion!</h1>
268                 <p>
269                 <input type="hidden" name="authorcount" value="<?php echo $idx?>" />
270                 <input type="submit" value="Step 3: Do the conversion!" />
271                 <input type="hidden" name="action" value="doConversion" />
272                 </p>
273
274                 <div class="note">
275                 <b>Note:</b> Clicking the button once is enough, even if it takes a while to complete.
276                 </div>
277
278                 </form>
279         <?php
280         convert_foot();
281
282 }
283
284
285 function bc_doConversion() {
286         global $HTTP_POST_VARS, $manager;
287
288         // 1. get all data
289         $authorcount = intval($HTTP_POST_VARS['authorcount']);
290         $author = $HTTP_POST_VARS['author'];
291
292         for ($i=0;$i<$authorcount;$i++) {
293                 $key = $author[$i];
294                 $memberid[$key] = intval($HTTP_POST_VARS['memberid'][$i]);
295                 $isadmin[$key] = intval($HTTP_POST_VARS['admin'][$i]);
296         }
297
298         $createnew = intval($HTTP_POST_VARS['createnew']);
299         $newblogname = stripslashes($HTTP_POST_VARS['newblogname']);
300         $newowner = intval($HTTP_POST_VARS['newowner']);
301
302         global $nucleus_blogid;
303         $nucleus_blogid = intval($HTTP_POST_VARS['blogid']);
304
305
306         // 2. check data
307
308         convert_head();
309
310         ?>
311                 <h1>Step 3: Converting...</h1>
312
313                 <p>
314                 Please be patient. Don't hit reload! The conversion progress should be showing below.
315                 </p>
316         <?php
317         // try to extend time limit
318         // surpress error messages when not allowed to do so
319         @set_time_limit(1200);
320
321         echo "<pre>";
322
323         echo "Authors: <br/>";
324         for ($i=0;$i<$authorcount;$i++) {
325                 echo  "\tAuthor=" . $author[$i];
326                 echo " ID=" . $memberid[$author[$i]];
327                 echo " ADMIN=" . $isadmin[$author[$i]];
328                 echo "<br />";
329         }
330         echo "Create New Weblog = $createnew (name='$newblogname', owner=$newowner, dest=$nucleus_blogid)<br />";
331
332         echo "</pre>";
333
334         // create blog
335         if ($createnew == 1) {
336                 // choose unique name
337                 $shortname = 'blogger';
338                 if (Blog::exists($shortname)) {
339                         $idx = 1;
340                         while (Blog::exists($shortname . $idx))
341                                 $idx++;
342                         $shortname = $shortname . $idx;
343                 }
344
345                 $nucleus_blogid = convert_addToBlog($newblogname, $shortname, $newowner);
346                 echo "<pre>New blog created</pre>";
347         }
348
349         // add authors to blog team
350         $b =& $manager->getBlog($nucleus_blogid);
351         global $catid;
352         $catid = $b->getDefaultCategory();
353
354         for ($i=0;$i<$authorcount;$i++)
355                 $b->addTeamMember($memberid[$author[$i]],$isadmin[$author[$i]]);
356
357
358         global $mapping;
359         $mapping = array();
360
361         // 3. go through blogger.xml file
362
363         $blog = new RAX();
364         $blog->openfile('blogger.xml');
365         $blog->record_delim = 'blogentry';
366         $blog->parse();
367
368         while ( $entry = $blog->readRecord() )  {
369                 $row = $entry->getRow();
370
371                 bc_convertOneItem($row, $memberid, $nucleus_blogid);
372         }
373
374         $blog->close(); // close the file
375
376         // 4. convert comments
377         bc_convertComments($mapping);
378
379         echo "<pre>All done!</pre>";
380
381         convert_foot();
382
383 }
384
385 function bc_convertOneItem($row, $memberid, $nucleus_blogid) {
386         global $catid, $comments;
387
388         $nucl_id = $memberid[$row['author']];
389         $bloggerid = $row['bloggerid'];
390
391         $timestamp = date("Y-m-d H:i:s",bc_transformDate($row['date']));
392
393         echo "<ul>";
394         echo "<li>Blogger ID: $bloggerid </li>";
395         echo "<li>Body:" .  Entity::hsc(substr($row['body'],0,20)) . "...(time: " . $timestamp . ") </li>";
396         echo "<li>author: " . $row['author'] ;
397         echo " (nucleus-id: " . $nucl_id . ")</li>";
398
399         $nucleus_itemid = convert_addToItem($row['title'], $row['body'], '', $nucleus_blogid, $nucl_id, $timestamp, 0, $catid, 0, 0);
400
401         echo "<li>New itemid= $nucleus_itemid</li>";
402
403         // save mapping
404         global $mapping;
405         $mapping[$bloggerid] = $nucleus_itemid;
406
407         echo "</ul>";
408 }
409
410 function bc_transformDate($date) {
411         // 7/24/2000 11:27:13 AM
412         if (eregi("(.*)/(.*)/(.*) (.*):(.*):(.*) (.*)",$date,$regs) != false) {
413                 if ($regs[7] == "PM")
414                         $regs[4] += 12;
415                 return mktime($regs[4],$regs[5],$regs[6],$regs[1],$regs[2],$regs[3]);
416
417         } else {
418                 return 0;
419         }
420
421 }
422
423 // mapping is an array mapping blogger IDs to nucleus itemids
424 function bc_convertComments($mapping) {
425         $reader = new ReadCAIF('caif.xml',$mapping);
426 }
427
428 function bc_addComment($nucleus_itemid, $data) {
429         global $nucleus_blogid;
430
431         if (!$nucleus_itemid) {
432                 echo "<div>No matching itemid found: ";
433                 print_r($data);
434                 echo "</div>";
435                 return;
436         }
437
438         $c_datetime = $data['datetime'];
439         $c_name = $data['name'];
440         $c_email = $data['email'];
441         $c_uri = $data['uri'];
442         $c_ip = $data['ip'];
443         $c_text = $data['text'];
444
445         // to be sure the CDATA part is gone
446         $c_text = str_replace('<![CDATA[','',$c_text);
447         $c_text = str_replace(']]>','',$c_text);
448         $c_text = trim($c_text);
449
450         // get unix timestamp out of datetime thing (for yaccs, this contains an erroneous comma)
451         $c_timestamp = strtotime(str_replace(',','',$c_datetime));
452
453         // choose url or email to pass as userid
454         if ((stristr($c_uri,'http://') != false) && ($c_uri != 'http://'))
455                 $c_userid = $c_uri;
456         else
457                 $c_userid = $c_email;
458
459         echo '<div>',Entity::hsc(shorten($c_text,50,'...')),'</div><ul>';
460 //      echo '<li>Date: ',strftime('%x %X',$c_timestamp),'</li>';
461         echo "<li>Name: $c_name</li>";
462 //      echo "<li>Email: $c_email</li>";
463 //      echo "<li>URI: $c_uri</li>";
464         echo "<li>UserID: $c_userid</li>";
465 //      echo "<li>ip: $c_ip</li>";
466         echo "<li>nucleus itemid: $nucleus_itemid</li>";
467 //      echo "<li>nucleus blogid: $nucleus_blogid</li>";
468         echo '</ul>';
469
470         // prepare for MySQL
471         $c_timestamp = date("Y-m-d H:i:s",$c_timestamp);
472
473         // add to comments
474         convert_addToComments($c_name, $c_userid, $c_text, $nucleus_blogid, $nucleus_itemid, 0, $c_timestamp, $c_ip);
475
476
477 }
478
479 /* by Wouter Demuynck, slightly based on PRAX.php */
480 class ReadCAIF {
481         function ReadCAIF($filename, $mapping) {
482                 $this->fp = fopen($filename, 'r');
483                 $this->mapping =& $mapping;
484                 $this->currentItem = 0;
485                 $this->tag_stack = array();
486                 $this->in_rec = 0;
487                 $this->in_field = 0;
488                 $this->field_data = '';
489                 $this->fields = array();
490
491                 $this->parser = xml_parser_create();
492                 xml_set_object($this->parser,$this);
493                 xml_set_element_handler($this->parser,  'startElement',  'endElement');
494                 xml_set_character_data_handler($this->parser,  'characterData');
495                 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
496                 while ($buffer = fread($this->fp, 4096))
497                         xml_parse( $this->parser, $buffer, feof($this->fp) );
498         }
499
500
501         function startElement($parser, $name, $attrs) {
502                 array_push($this->tag_stack, $name);
503
504 //              echo "<br />BEGIN: ", implode($this->tag_stack,'-&gt;');
505                 if ( !$this->in_rec and !strcmp($name, 'comment') ) {
506                         $this->in_rec = 1;
507                         $this->rec_lvl = sizeof($this->tag_stack);
508                         $this->field_lvl = $this->rec_lvl + 1;
509                 }
510                 else if ( $this->in_rec and sizeof($this->tag_stack) == $this->field_lvl ) {
511                         $this->in_field = 1;
512                 } else if ($name == 'thread') {
513                         $this->currentItem = $this->mapping[$attrs['id']];
514 //                      echo '<b>THREAD START (',$this->currentItem,')</b>';
515
516                 }
517
518         }
519
520
521         function endElement($parser, $name) {
522                 array_pop($this->tag_stack);
523
524 //              echo "<br />END: ", implode($this->tag_stack,'-&gt;');
525
526                 if ( $this->in_rec ) {
527
528                         if ( sizeof($this->tag_stack) < $this->rec_lvl ) {
529                                 $this->in_rec = 0;
530                                 bc_addComment($this->currentItem, $this->fields);
531                                 $this->fields = array();
532
533                         }
534                         else if ( sizeof($this->tag_stack) < $this->field_lvl ) {
535                                 $this->in_field = 0;
536                                 $this->fields[$name] = $this->field_data;
537                                 $this->field_data = '';
538                         }
539
540                 }
541
542         }
543
544         function characterData ($parser, $data) {
545                 if ( $this->in_field )
546                         $this->field_data .= $data;
547
548         }
549
550
551
552 }
553
554
555
556 ?>