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 * This script will import a Blogger blog into a Nucleus blog, using
14 * a easy to use wizard.
17 * - Templates are not converted
18 * - Nucleus should already be installed
19 * - Members should exist for all teammembers
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 1624 2012-01-09 11:36:20Z sakamocchi $
26 include("../../config.php");
27 include("functions.inc.php");
28 include($DIR_LIBS . "ADMIN.php");
29 include($DIR_LIBS . "MEDIA.php");
31 if (!$member->isLoggedIn()) {
32 convert_showLogin('bloggercaif.php');
35 if (!$member->isAdmin()) {
36 convert_doError('Only Super-Admins are allowed to perform blog conversions');
39 $ver = convert_getNucleusVersion();
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.");
43 // include PRAX lib (to read XML files easily)
48 bc_assignMembers(); break;
50 bc_showOverview(); break;
52 bc_doConversion(); break;
53 case "login": // drop through
55 bc_getBloggerBlogID();
58 // step 1: get the Blogger Blog ID
59 function bc_getBloggerBlogID() {
60 global $HTTP_SERVER_VARS, $PHP_SELF;
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)
69 <h1>Step 1: Exporting to a file</h1>
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:
76 <h2>Exporting from Blogger</h2>
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>
82 Log into <a href="http://www.blogger.com/">Blogger</a> and go to the blog you want to export.
85 Change the template of your blog to the following:
88 <?xml version="1.0"?>
95 <bloggerid><$BlogItemNumber$></bloggerid>
96 <body><![CDATA[<$BlogItemBody$>]]></body>
97 <date><$BlogItemDateTime$></date>
98 <author><$BlogItemAuthor$></author>
105 Don't forget to save changes!
108 Go to the settings and change the following options:
111 Blog filename: <b>blogger.xml</b>
114 Show <b>900</b> <b>day's posts</b> on main page
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)
120 Archive Frequency: <b>No Archive</b>
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.
128 If you're running blogspot, you'll need to edit this file and take out the advertising banner code.
132 <h2>Exporting comments to CAIF (Instructions for YACCS)</h2>
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>
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.
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" />
157 function bc_assignMembers() {
158 global $HTTP_POST_VARS, $CONF;
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.");
173 <form method="post" action="bloggercaif.php">
176 <h1>Step 2: Assign Members to Authors</h1>
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.
185 <th>Blogger Author</th>
186 <th>Nucleus Member</th>
192 $blog->openfile('blogger.xml');
193 $blog->record_delim = 'blogentry';
200 while ( $entry = $blog->readRecord() ) {
201 $row = $entry->getRow();
204 if (!in_array($row['author'],$authors))
205 array_push($authors,$row['author']);
209 $blog->close(); // close the file
212 while ($a_name = array_pop($authors)) {
216 <b><?php echo $a_name?></b>
217 <input name="author[<?php echo $idx?>]" value="<?php echo Entity::hsc($a_name)?>" type="hidden" />
220 <?php $query = 'SELECT mname as text, mnumber as value FROM '.sql_table('member');
222 $template['name'] = 'memberid[' . $idx . ']';
223 echo showlist($query,'select',$template);
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>
238 <h1>Choose Destination Weblog</h1>
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.
245 <input name="createnew" value="0" type="radio" checked='checked' id="createnew_no" /><label for="createnew_no">Choose existing weblog to add to:</label>
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);
254 <input name="createnew" value="1" type="radio" id="createnew_yes" /><label for="createnew_yes">Create new weblog</label>
256 <li>New blog name: <input name="newblogname" /></li>
258 <?php $query = 'SELECT mname as text, mnumber as value FROM '.sql_table('member');
260 $template['name'] = 'newowner';
261 echo showlist($query,'select',$template);
267 <h1>Do the conversion!</h1>
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" />
275 <b>Note:</b> Clicking the button once is enough, even if it takes a while to complete.
285 function bc_doConversion() {
286 global $HTTP_POST_VARS, $manager;
289 $authorcount = intval($HTTP_POST_VARS['authorcount']);
290 $author = $HTTP_POST_VARS['author'];
292 for ($i=0;$i<$authorcount;$i++) {
294 $memberid[$key] = intval($HTTP_POST_VARS['memberid'][$i]);
295 $isadmin[$key] = intval($HTTP_POST_VARS['admin'][$i]);
298 $createnew = intval($HTTP_POST_VARS['createnew']);
299 $newblogname = stripslashes($HTTP_POST_VARS['newblogname']);
300 $newowner = intval($HTTP_POST_VARS['newowner']);
302 global $nucleus_blogid;
303 $nucleus_blogid = intval($HTTP_POST_VARS['blogid']);
311 <h1>Step 3: Converting...</h1>
314 Please be patient. Don't hit reload! The conversion progress should be showing below.
317 // try to extend time limit
318 // surpress error messages when not allowed to do so
319 @set_time_limit(1200);
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]];
330 echo "Create New Weblog = $createnew (name='$newblogname', owner=$newowner, dest=$nucleus_blogid)<br />";
335 if ($createnew == 1) {
336 // choose unique name
337 $shortname = 'blogger';
338 if (Blog::exists($shortname)) {
340 while (Blog::exists($shortname . $idx))
342 $shortname = $shortname . $idx;
345 $nucleus_blogid = convert_addToBlog($newblogname, $shortname, $newowner);
346 echo "<pre>New blog created</pre>";
349 // add authors to blog team
350 $b =& $manager->getBlog($nucleus_blogid);
352 $catid = $b->getDefaultCategory();
354 for ($i=0;$i<$authorcount;$i++)
355 $b->addTeamMember($memberid[$author[$i]],$isadmin[$author[$i]]);
361 // 3. go through blogger.xml file
364 $blog->openfile('blogger.xml');
365 $blog->record_delim = 'blogentry';
368 while ( $entry = $blog->readRecord() ) {
369 $row = $entry->getRow();
371 bc_convertOneItem($row, $memberid, $nucleus_blogid);
374 $blog->close(); // close the file
376 // 4. convert comments
377 bc_convertComments($mapping);
379 echo "<pre>All done!</pre>";
385 function bc_convertOneItem($row, $memberid, $nucleus_blogid) {
386 global $catid, $comments;
388 $nucl_id = $memberid[$row['author']];
389 $bloggerid = $row['bloggerid'];
391 $timestamp = date("Y-m-d H:i:s",bc_transformDate($row['date']));
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>";
399 $nucleus_itemid = convert_addToItem($row['title'], $row['body'], '', $nucleus_blogid, $nucl_id, $timestamp, 0, $catid, 0, 0);
401 echo "<li>New itemid= $nucleus_itemid</li>";
405 $mapping[$bloggerid] = $nucleus_itemid;
410 function bc_transformDate($date) {
411 // 7/24/2000 11:27:13 AM
412 if (eregi("(.*)/(.*)/(.*) (.*):(.*):(.*) (.*)",$date,$regs) != false) {
413 if ($regs[7] == "PM")
415 return mktime($regs[4],$regs[5],$regs[6],$regs[1],$regs[2],$regs[3]);
423 // mapping is an array mapping blogger IDs to nucleus itemids
424 function bc_convertComments($mapping) {
425 $reader = new ReadCAIF('caif.xml',$mapping);
428 function bc_addComment($nucleus_itemid, $data) {
429 global $nucleus_blogid;
431 if (!$nucleus_itemid) {
432 echo "<div>No matching itemid found: ";
438 $c_datetime = $data['datetime'];
439 $c_name = $data['name'];
440 $c_email = $data['email'];
441 $c_uri = $data['uri'];
443 $c_text = $data['text'];
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);
450 // get unix timestamp out of datetime thing (for yaccs, this contains an erroneous comma)
451 $c_timestamp = strtotime(str_replace(',','',$c_datetime));
453 // choose url or email to pass as userid
454 if ((stristr($c_uri,'http://') != false) && ($c_uri != 'http://'))
457 $c_userid = $c_email;
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>";
471 $c_timestamp = date("Y-m-d H:i:s",$c_timestamp);
474 convert_addToComments($c_name, $c_userid, $c_text, $nucleus_blogid, $nucleus_itemid, 0, $c_timestamp, $c_ip);
479 /* by Wouter Demuynck, slightly based on PRAX.php */
481 function ReadCAIF($filename, $mapping) {
482 $this->fp = fopen($filename, 'r');
483 $this->mapping =& $mapping;
484 $this->currentItem = 0;
485 $this->tag_stack = array();
488 $this->field_data = '';
489 $this->fields = array();
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) );
501 function startElement($parser, $name, $attrs) {
502 array_push($this->tag_stack, $name);
504 // echo "<br />BEGIN: ", implode($this->tag_stack,'->');
505 if ( !$this->in_rec and !strcmp($name, 'comment') ) {
507 $this->rec_lvl = sizeof($this->tag_stack);
508 $this->field_lvl = $this->rec_lvl + 1;
510 else if ( $this->in_rec and sizeof($this->tag_stack) == $this->field_lvl ) {
512 } else if ($name == 'thread') {
513 $this->currentItem = $this->mapping[$attrs['id']];
514 // echo '<b>THREAD START (',$this->currentItem,')</b>';
521 function endElement($parser, $name) {
522 array_pop($this->tag_stack);
524 // echo "<br />END: ", implode($this->tag_stack,'->');
526 if ( $this->in_rec ) {
528 if ( sizeof($this->tag_stack) < $this->rec_lvl ) {
530 bc_addComment($this->currentItem, $this->fields);
531 $this->fields = array();
534 else if ( sizeof($this->tag_stack) < $this->field_lvl ) {
536 $this->fields[$name] = $this->field_data;
537 $this->field_data = '';
544 function characterData ($parser, $data) {
545 if ( $this->in_field )
546 $this->field_data .= $data;