raw
mp-wp_genesis           1 <?php
mp-wp_genesis 2 /**
mp-wp_genesis 3 * Blogger Importer
mp-wp_genesis 4 *
mp-wp_genesis 5 * @package WordPress
mp-wp_genesis 6 * @subpackage Importer
mp-wp_genesis 7 */
mp-wp_genesis 8
mp-wp_genesis 9 /**
mp-wp_genesis 10 * How many records per GData query
mp-wp_genesis 11 *
mp-wp_genesis 12 * @package WordPress
mp-wp_genesis 13 * @subpackage Blogger_Import
mp-wp_genesis 14 * @var int
mp-wp_genesis 15 * @since unknown
mp-wp_genesis 16 */
mp-wp_genesis 17 define( 'MAX_RESULTS', 50 );
mp-wp_genesis 18
mp-wp_genesis 19 /**
mp-wp_genesis 20 * How many seconds to let the script run
mp-wp_genesis 21 *
mp-wp_genesis 22 * @package WordPress
mp-wp_genesis 23 * @subpackage Blogger_Import
mp-wp_genesis 24 * @var int
mp-wp_genesis 25 * @since unknown
mp-wp_genesis 26 */
mp-wp_genesis 27 define( 'MAX_EXECUTION_TIME', 20 );
mp-wp_genesis 28
mp-wp_genesis 29 /**
mp-wp_genesis 30 * How many seconds between status bar updates
mp-wp_genesis 31 *
mp-wp_genesis 32 * @package WordPress
mp-wp_genesis 33 * @subpackage Blogger_Import
mp-wp_genesis 34 * @var int
mp-wp_genesis 35 * @since unknown
mp-wp_genesis 36 */
mp-wp_genesis 37 define( 'STATUS_INTERVAL', 3 );
mp-wp_genesis 38
mp-wp_genesis 39 /**
mp-wp_genesis 40 * Blogger Importer class
mp-wp_genesis 41 *
mp-wp_genesis 42 * @since unknown
mp-wp_genesis 43 */
mp-wp_genesis 44 class Blogger_Import {
mp-wp_genesis 45
mp-wp_genesis 46 // Shows the welcome screen and the magic auth link.
mp-wp_genesis 47 function greet() {
mp-wp_genesis 48 $next_url = get_option('siteurl') . '/wp-admin/index.php?import=blogger&amp;noheader=true';
mp-wp_genesis 49 $auth_url = "https://www.google.com/accounts/AuthSubRequest";
mp-wp_genesis 50 $title = __('Import Blogger');
mp-wp_genesis 51 $welcome = __('Howdy! This importer allows you to import posts and comments from your Blogger account into your WordPress blog.');
mp-wp_genesis 52 $prereqs = __('To use this importer, you must have a Google account and an upgraded (New, was Beta) blog hosted on blogspot.com or a custom domain (not FTP).');
mp-wp_genesis 53 $stepone = __('The first thing you need to do is tell Blogger to let WordPress access your account. You will be sent back here after providing authorization.');
mp-wp_genesis 54 $auth = __('Authorize');
mp-wp_genesis 55
mp-wp_genesis 56 echo "
mp-wp_genesis 57 <div class='wrap'>
mp-wp_genesis 58 ".screen_icon()."
mp-wp_genesis 59 <h2>$title</h2>
mp-wp_genesis 60 <p>$welcome</p><p>$prereqs</p><p>$stepone</p>
mp-wp_genesis 61 <form action='$auth_url' method='get'>
mp-wp_genesis 62 <p class='submit' style='text-align:left;'>
mp-wp_genesis 63 <input type='submit' class='button' value='$auth' />
mp-wp_genesis 64 <input type='hidden' name='scope' value='http://www.blogger.com/feeds/' />
mp-wp_genesis 65 <input type='hidden' name='session' value='1' />
mp-wp_genesis 66 <input type='hidden' name='secure' value='0' />
mp-wp_genesis 67 <input type='hidden' name='next' value='$next_url' />
mp-wp_genesis 68 </p>
mp-wp_genesis 69 </form>
mp-wp_genesis 70 </div>\n";
mp-wp_genesis 71 }
mp-wp_genesis 72
mp-wp_genesis 73 function uh_oh($title, $message, $info) {
mp-wp_genesis 74 echo "<div class='wrap'>";
mp-wp_genesis 75 screen_icon();
mp-wp_genesis 76 echo "<h2>$title</h2><p>$message</p><pre>$info</pre></div>";
mp-wp_genesis 77 }
mp-wp_genesis 78
mp-wp_genesis 79 function auth() {
mp-wp_genesis 80 // We have a single-use token that must be upgraded to a session token.
mp-wp_genesis 81 $token = preg_replace( '/[^-_0-9a-zA-Z]/', '', $_GET['token'] );
mp-wp_genesis 82 $headers = array(
mp-wp_genesis 83 "GET /accounts/AuthSubSessionToken HTTP/1.0",
mp-wp_genesis 84 "Authorization: AuthSub token=\"$token\""
mp-wp_genesis 85 );
mp-wp_genesis 86 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 87 $sock = $this->_get_auth_sock( );
mp-wp_genesis 88 if ( ! $sock ) return false;
mp-wp_genesis 89 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 90 preg_match( '/token=([-_0-9a-z]+)/i', $response, $matches );
mp-wp_genesis 91 if ( empty( $matches[1] ) ) {
mp-wp_genesis 92 $this->uh_oh(
mp-wp_genesis 93 __( 'Authorization failed' ),
mp-wp_genesis 94 __( 'Something went wrong. If the problem persists, send this info to support:' ),
mp-wp_genesis 95 htmlspecialchars($response)
mp-wp_genesis 96 );
mp-wp_genesis 97 return false;
mp-wp_genesis 98 }
mp-wp_genesis 99 $this->token = $matches[1];
mp-wp_genesis 100
mp-wp_genesis 101 wp_redirect( remove_query_arg( array( 'token', 'noheader' ) ) );
mp-wp_genesis 102 }
mp-wp_genesis 103
mp-wp_genesis 104 function get_token_info() {
mp-wp_genesis 105 $headers = array(
mp-wp_genesis 106 "GET /accounts/AuthSubTokenInfo HTTP/1.0",
mp-wp_genesis 107 "Authorization: AuthSub token=\"$this->token\""
mp-wp_genesis 108 );
mp-wp_genesis 109 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 110 $sock = $this->_get_auth_sock( );
mp-wp_genesis 111 if ( ! $sock ) return;
mp-wp_genesis 112 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 113 return $this->parse_response($response);
mp-wp_genesis 114 }
mp-wp_genesis 115
mp-wp_genesis 116 function token_is_valid() {
mp-wp_genesis 117 $info = $this->get_token_info();
mp-wp_genesis 118
mp-wp_genesis 119 if ( $info['code'] == 200 )
mp-wp_genesis 120 return true;
mp-wp_genesis 121
mp-wp_genesis 122 return false;
mp-wp_genesis 123 }
mp-wp_genesis 124
mp-wp_genesis 125 function show_blogs($iter = 0) {
mp-wp_genesis 126 if ( empty($this->blogs) ) {
mp-wp_genesis 127 $headers = array(
mp-wp_genesis 128 "GET /feeds/default/blogs HTTP/1.0",
mp-wp_genesis 129 "Host: www.blogger.com",
mp-wp_genesis 130 "Authorization: AuthSub token=\"$this->token\""
mp-wp_genesis 131 );
mp-wp_genesis 132 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 133 $sock = $this->_get_blogger_sock( );
mp-wp_genesis 134 if ( ! $sock ) return;
mp-wp_genesis 135 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 136
mp-wp_genesis 137 // Quick and dirty XML mining.
mp-wp_genesis 138 list( $headers, $xml ) = explode( "\r\n\r\n", $response );
mp-wp_genesis 139 $p = xml_parser_create();
mp-wp_genesis 140 xml_parse_into_struct($p, $xml, $vals, $index);
mp-wp_genesis 141 xml_parser_free($p);
mp-wp_genesis 142
mp-wp_genesis 143 $this->title = $vals[$index['TITLE'][0]]['value'];
mp-wp_genesis 144
mp-wp_genesis 145 // Give it a few retries... this step often flakes out the first time.
mp-wp_genesis 146 if ( empty( $index['ENTRY'] ) ) {
mp-wp_genesis 147 if ( $iter < 3 ) {
mp-wp_genesis 148 return $this->show_blogs($iter + 1);
mp-wp_genesis 149 } else {
mp-wp_genesis 150 $this->uh_oh(
mp-wp_genesis 151 __('Trouble signing in'),
mp-wp_genesis 152 __('We were not able to gain access to your account. Try starting over.'),
mp-wp_genesis 153 ''
mp-wp_genesis 154 );
mp-wp_genesis 155 return false;
mp-wp_genesis 156 }
mp-wp_genesis 157 }
mp-wp_genesis 158
mp-wp_genesis 159 foreach ( $index['ENTRY'] as $i ) {
mp-wp_genesis 160 $blog = array();
mp-wp_genesis 161 while ( ( $tag = $vals[$i] ) && ! ( $tag['tag'] == 'ENTRY' && $tag['type'] == 'close' ) ) {
mp-wp_genesis 162 if ( $tag['tag'] == 'TITLE' ) {
mp-wp_genesis 163 $blog['title'] = $tag['value'];
mp-wp_genesis 164 } elseif ( $tag['tag'] == 'SUMMARY' ) {
mp-wp_genesis 165 $blog['summary'] == $tag['value'];
mp-wp_genesis 166 } elseif ( $tag['tag'] == 'LINK' ) {
mp-wp_genesis 167 if ( $tag['attributes']['REL'] == 'alternate' && $tag['attributes']['TYPE'] == 'text/html' ) {
mp-wp_genesis 168 $parts = parse_url( $tag['attributes']['HREF'] );
mp-wp_genesis 169 $blog['host'] = $parts['host'];
mp-wp_genesis 170 } elseif ( $tag['attributes']['REL'] == 'edit' )
mp-wp_genesis 171 $blog['gateway'] = $tag['attributes']['HREF'];
mp-wp_genesis 172 }
mp-wp_genesis 173 ++$i;
mp-wp_genesis 174 }
mp-wp_genesis 175 if ( ! empty ( $blog ) ) {
mp-wp_genesis 176 $blog['total_posts'] = $this->get_total_results('posts', $blog['host']);
mp-wp_genesis 177 $blog['total_comments'] = $this->get_total_results('comments', $blog['host']);
mp-wp_genesis 178 $blog['mode'] = 'init';
mp-wp_genesis 179 $this->blogs[] = $blog;
mp-wp_genesis 180 }
mp-wp_genesis 181 }
mp-wp_genesis 182
mp-wp_genesis 183 if ( empty( $this->blogs ) ) {
mp-wp_genesis 184 $this->uh_oh(
mp-wp_genesis 185 __('No blogs found'),
mp-wp_genesis 186 __('We were able to log in but there were no blogs. Try a different account next time.'),
mp-wp_genesis 187 ''
mp-wp_genesis 188 );
mp-wp_genesis 189 return false;
mp-wp_genesis 190 }
mp-wp_genesis 191 }
mp-wp_genesis 192 //echo '<pre>'.print_r($this,1).'</pre>';
mp-wp_genesis 193 $start = js_escape( __('Import') );
mp-wp_genesis 194 $continue = js_escape( __('Continue') );
mp-wp_genesis 195 $stop = js_escape( __('Importing...') );
mp-wp_genesis 196 $authors = js_escape( __('Set Authors') );
mp-wp_genesis 197 $loadauth = js_escape( __('Preparing author mapping form...') );
mp-wp_genesis 198 $authhead = js_escape( __('Final Step: Author Mapping') );
mp-wp_genesis 199 $nothing = js_escape( __('Nothing was imported. Had you already imported this blog?') );
mp-wp_genesis 200 $title = __('Blogger Blogs');
mp-wp_genesis 201 $name = __('Blog Name');
mp-wp_genesis 202 $url = __('Blog URL');
mp-wp_genesis 203 $action = __('The Magic Button');
mp-wp_genesis 204 $posts = __('Posts');
mp-wp_genesis 205 $comments = __('Comments');
mp-wp_genesis 206 $noscript = __('This feature requires Javascript but it seems to be disabled. Please enable Javascript and then reload this page. Don\'t worry, you can turn it back off when you\'re done.');
mp-wp_genesis 207
mp-wp_genesis 208 $interval = STATUS_INTERVAL * 1000;
mp-wp_genesis 209
mp-wp_genesis 210 foreach ( $this->blogs as $i => $blog ) {
mp-wp_genesis 211 if ( $blog['mode'] == 'init' )
mp-wp_genesis 212 $value = $start;
mp-wp_genesis 213 elseif ( $blog['mode'] == 'posts' || $blog['mode'] == 'comments' )
mp-wp_genesis 214 $value = $continue;
mp-wp_genesis 215 else
mp-wp_genesis 216 $value = $authors;
mp-wp_genesis 217 $blogtitle = js_escape( $blog['title'] );
mp-wp_genesis 218 $pdone = isset($blog['posts_done']) ? (int) $blog['posts_done'] : 0;
mp-wp_genesis 219 $cdone = isset($blog['comments_done']) ? (int) $blog['comments_done'] : 0;
mp-wp_genesis 220 $init .= "blogs[$i]=new blog($i,'$blogtitle','{$blog['mode']}'," . $this->get_js_status($i) . ');';
mp-wp_genesis 221 $pstat = "<div class='ind' id='pind$i'>&nbsp;</div><div id='pstat$i' class='stat'>$pdone/{$blog['total_posts']}</div>";
mp-wp_genesis 222 $cstat = "<div class='ind' id='cind$i'>&nbsp;</div><div id='cstat$i' class='stat'>$cdone/{$blog['total_comments']}</div>";
mp-wp_genesis 223 $rows .= "<tr id='blog$i'><td class='blogtitle'>$blogtitle</td><td class='bloghost'>{$blog['host']}</td><td class='bar'>$pstat</td><td class='bar'>$cstat</td><td class='submit'><input type='submit' class='button' id='submit$i' value='$value' /><input type='hidden' name='blog' value='$i' /></td></tr>\n";
mp-wp_genesis 224 }
mp-wp_genesis 225
mp-wp_genesis 226 echo "<div class='wrap'><h2>$title</h2><noscript>$noscript</noscript><table cellpadding='5px'><thead><tr><td>$name</td><td>$url</td><td>$posts</td><td>$comments</td><td>$action</td></tr></thead>\n$rows</table></div>";
mp-wp_genesis 227 echo "
mp-wp_genesis 228 <script type='text/javascript'>
mp-wp_genesis 229 /* <![CDATA[ */
mp-wp_genesis 230 var strings = {cont:'$continue',stop:'$stop',stopping:'$stopping',authors:'$authors',nothing:'$nothing'};
mp-wp_genesis 231 var blogs = {};
mp-wp_genesis 232 function blog(i, title, mode, status){
mp-wp_genesis 233 this.blog = i;
mp-wp_genesis 234 this.mode = mode;
mp-wp_genesis 235 this.title = title;
mp-wp_genesis 236 this.status = status;
mp-wp_genesis 237 this.button = document.getElementById('submit'+this.blog);
mp-wp_genesis 238 };
mp-wp_genesis 239 blog.prototype = {
mp-wp_genesis 240 start: function() {
mp-wp_genesis 241 this.cont = true;
mp-wp_genesis 242 this.kick();
mp-wp_genesis 243 this.check();
mp-wp_genesis 244 },
mp-wp_genesis 245 kick: function() {
mp-wp_genesis 246 ++this.kicks;
mp-wp_genesis 247 var i = this.blog;
mp-wp_genesis 248 jQuery.post('admin.php?import=blogger&noheader=true',{blog:this.blog},function(text,result){blogs[i].kickd(text,result)});
mp-wp_genesis 249 },
mp-wp_genesis 250 check: function() {
mp-wp_genesis 251 ++this.checks;
mp-wp_genesis 252 var i = this.blog;
mp-wp_genesis 253 jQuery.post('admin.php?import=blogger&noheader=true&status=true',{blog:this.blog},function(text,result){blogs[i].checkd(text,result)});
mp-wp_genesis 254 },
mp-wp_genesis 255 kickd: function(text, result) {
mp-wp_genesis 256 if ( result == 'error' ) {
mp-wp_genesis 257 // TODO: exception handling
mp-wp_genesis 258 if ( this.cont )
mp-wp_genesis 259 setTimeout('blogs['+this.blog+'].kick()', 1000);
mp-wp_genesis 260 } else {
mp-wp_genesis 261 if ( text == 'done' ) {
mp-wp_genesis 262 this.stop();
mp-wp_genesis 263 this.done();
mp-wp_genesis 264 } else if ( text == 'nothing' ) {
mp-wp_genesis 265 this.stop();
mp-wp_genesis 266 this.nothing();
mp-wp_genesis 267 } else if ( text == 'continue' ) {
mp-wp_genesis 268 this.kick();
mp-wp_genesis 269 } else if ( this.mode = 'stopped' )
mp-wp_genesis 270 jQuery(this.button).attr('value', strings.cont);
mp-wp_genesis 271 }
mp-wp_genesis 272 --this.kicks;
mp-wp_genesis 273 },
mp-wp_genesis 274 checkd: function(text, result) {
mp-wp_genesis 275 if ( result == 'error' ) {
mp-wp_genesis 276 // TODO: exception handling
mp-wp_genesis 277 } else {
mp-wp_genesis 278 eval('this.status='+text);
mp-wp_genesis 279 jQuery('#pstat'+this.blog).empty().append(this.status.p1+'/'+this.status.p2);
mp-wp_genesis 280 jQuery('#cstat'+this.blog).empty().append(this.status.c1+'/'+this.status.c2);
mp-wp_genesis 281 this.update();
mp-wp_genesis 282 if ( this.cont || this.kicks > 0 )
mp-wp_genesis 283 setTimeout('blogs['+this.blog+'].check()', $interval);
mp-wp_genesis 284 }
mp-wp_genesis 285 --this.checks;
mp-wp_genesis 286 },
mp-wp_genesis 287 update: function() {
mp-wp_genesis 288 jQuery('#pind'+this.blog).width(((this.status.p1>0&&this.status.p2>0)?(this.status.p1/this.status.p2*jQuery('#pind'+this.blog).parent().width()):1)+'px');
mp-wp_genesis 289 jQuery('#cind'+this.blog).width(((this.status.c1>0&&this.status.c2>0)?(this.status.c1/this.status.c2*jQuery('#cind'+this.blog).parent().width()):1)+'px');
mp-wp_genesis 290 },
mp-wp_genesis 291 stop: function() {
mp-wp_genesis 292 this.cont = false;
mp-wp_genesis 293 },
mp-wp_genesis 294 done: function() {
mp-wp_genesis 295 this.mode = 'authors';
mp-wp_genesis 296 jQuery(this.button).attr('value', strings.authors);
mp-wp_genesis 297 },
mp-wp_genesis 298 nothing: function() {
mp-wp_genesis 299 this.mode = 'nothing';
mp-wp_genesis 300 jQuery(this.button).remove();
mp-wp_genesis 301 alert(strings.nothing);
mp-wp_genesis 302 },
mp-wp_genesis 303 getauthors: function() {
mp-wp_genesis 304 if ( jQuery('div.wrap').length > 1 )
mp-wp_genesis 305 jQuery('div.wrap').gt(0).remove();
mp-wp_genesis 306 jQuery('div.wrap').empty().append('<h2>$authhead</h2><h3>' + this.title + '</h3>');
mp-wp_genesis 307 jQuery('div.wrap').append('<p id=\"auth\">$loadauth</p>');
mp-wp_genesis 308 jQuery('p#auth').load('index.php?import=blogger&noheader=true&authors=1',{blog:this.blog});
mp-wp_genesis 309 },
mp-wp_genesis 310 init: function() {
mp-wp_genesis 311 this.update();
mp-wp_genesis 312 var i = this.blog;
mp-wp_genesis 313 jQuery(this.button).bind('click', function(){return blogs[i].click();});
mp-wp_genesis 314 this.kicks = 0;
mp-wp_genesis 315 this.checks = 0;
mp-wp_genesis 316 },
mp-wp_genesis 317 click: function() {
mp-wp_genesis 318 if ( this.mode == 'init' || this.mode == 'stopped' || this.mode == 'posts' || this.mode == 'comments' ) {
mp-wp_genesis 319 this.mode = 'started';
mp-wp_genesis 320 this.start();
mp-wp_genesis 321 jQuery(this.button).attr('value', strings.stop);
mp-wp_genesis 322 } else if ( this.mode == 'started' ) {
mp-wp_genesis 323 return false; // let it run...
mp-wp_genesis 324 this.mode = 'stopped';
mp-wp_genesis 325 this.stop();
mp-wp_genesis 326 if ( this.checks > 0 || this.kicks > 0 ) {
mp-wp_genesis 327 this.mode = 'stopping';
mp-wp_genesis 328 jQuery(this.button).attr('value', strings.stopping);
mp-wp_genesis 329 } else {
mp-wp_genesis 330 jQuery(this.button).attr('value', strings.cont);
mp-wp_genesis 331 }
mp-wp_genesis 332 } else if ( this.mode == 'authors' ) {
mp-wp_genesis 333 document.location = 'index.php?import=blogger&authors=1&blog='+this.blog;
mp-wp_genesis 334 //this.mode = 'authors2';
mp-wp_genesis 335 //this.getauthors();
mp-wp_genesis 336 }
mp-wp_genesis 337 return false;
mp-wp_genesis 338 }
mp-wp_genesis 339 };
mp-wp_genesis 340 $init
mp-wp_genesis 341 jQuery.each(blogs, function(i, me){me.init();});
mp-wp_genesis 342 /* ]]> */
mp-wp_genesis 343 </script>\n";
mp-wp_genesis 344 }
mp-wp_genesis 345
mp-wp_genesis 346 // Handy function for stopping the script after a number of seconds.
mp-wp_genesis 347 function have_time() {
mp-wp_genesis 348 global $importer_started;
mp-wp_genesis 349 if ( time() - $importer_started > MAX_EXECUTION_TIME )
mp-wp_genesis 350 die('continue');
mp-wp_genesis 351 return true;
mp-wp_genesis 352 }
mp-wp_genesis 353
mp-wp_genesis 354 function get_total_results($type, $host) {
mp-wp_genesis 355 $headers = array(
mp-wp_genesis 356 "GET /feeds/$type/default?max-results=1&start-index=2 HTTP/1.0",
mp-wp_genesis 357 "Host: $host",
mp-wp_genesis 358 "Authorization: AuthSub token=\"$this->token\""
mp-wp_genesis 359 );
mp-wp_genesis 360 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 361 $sock = $this->_get_blogger_sock( $host );
mp-wp_genesis 362 if ( ! $sock ) return;
mp-wp_genesis 363 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 364 $response = $this->parse_response( $response );
mp-wp_genesis 365 $parser = xml_parser_create();
mp-wp_genesis 366 xml_parse_into_struct($parser, $response['body'], $struct, $index);
mp-wp_genesis 367 xml_parser_free($parser);
mp-wp_genesis 368 $total_results = $struct[$index['OPENSEARCH:TOTALRESULTS'][0]]['value'];
mp-wp_genesis 369 return (int) $total_results;
mp-wp_genesis 370 }
mp-wp_genesis 371
mp-wp_genesis 372 function import_blog($blogID) {
mp-wp_genesis 373 global $importing_blog;
mp-wp_genesis 374 $importing_blog = $blogID;
mp-wp_genesis 375
mp-wp_genesis 376 if ( isset($_GET['authors']) )
mp-wp_genesis 377 return print($this->get_author_form());
mp-wp_genesis 378
mp-wp_genesis 379 header('Content-Type: text/plain');
mp-wp_genesis 380
mp-wp_genesis 381 if ( isset($_GET['status']) )
mp-wp_genesis 382 die($this->get_js_status());
mp-wp_genesis 383
mp-wp_genesis 384 if ( isset($_GET['saveauthors']) )
mp-wp_genesis 385 die($this->save_authors());
mp-wp_genesis 386
mp-wp_genesis 387 $blog = $this->blogs[$blogID];
mp-wp_genesis 388 $total_results = $this->get_total_results('posts', $blog['host']);
mp-wp_genesis 389 $this->blogs[$importing_blog]['total_posts'] = $total_results;
mp-wp_genesis 390
mp-wp_genesis 391 $start_index = $total_results - MAX_RESULTS + 1;
mp-wp_genesis 392
mp-wp_genesis 393 if ( isset( $this->blogs[$importing_blog]['posts_start_index'] ) )
mp-wp_genesis 394 $start_index = (int) $this->blogs[$importing_blog]['posts_start_index'];
mp-wp_genesis 395 elseif ( $total_results > MAX_RESULTS )
mp-wp_genesis 396 $start_index = $total_results - MAX_RESULTS + 1;
mp-wp_genesis 397 else
mp-wp_genesis 398 $start_index = 1;
mp-wp_genesis 399
mp-wp_genesis 400 // This will be positive until we have finished importing posts
mp-wp_genesis 401 if ( $start_index > 0 ) {
mp-wp_genesis 402 // Grab all the posts
mp-wp_genesis 403 $this->blogs[$importing_blog]['mode'] = 'posts';
mp-wp_genesis 404 $query = "start-index=$start_index&max-results=" . MAX_RESULTS;
mp-wp_genesis 405 do {
mp-wp_genesis 406 $index = $struct = $entries = array();
mp-wp_genesis 407 $headers = array(
mp-wp_genesis 408 "GET /feeds/posts/default?$query HTTP/1.0",
mp-wp_genesis 409 "Host: {$blog['host']}",
mp-wp_genesis 410 "Authorization: AuthSub token=\"$this->token\""
mp-wp_genesis 411 );
mp-wp_genesis 412 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 413 $sock = $this->_get_blogger_sock( $blog['host'] );
mp-wp_genesis 414 if ( ! $sock ) return; // TODO: Error handling
mp-wp_genesis 415 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 416
mp-wp_genesis 417 $response = $this->parse_response( $response );
mp-wp_genesis 418
mp-wp_genesis 419 // Extract the entries and send for insertion
mp-wp_genesis 420 preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches );
mp-wp_genesis 421 if ( count( $matches[0] ) ) {
mp-wp_genesis 422 $entries = array_reverse($matches[0]);
mp-wp_genesis 423 foreach ( $entries as $entry ) {
mp-wp_genesis 424 $entry = "<feed>$entry</feed>";
mp-wp_genesis 425 $AtomParser = new AtomParser();
mp-wp_genesis 426 $AtomParser->parse( $entry );
mp-wp_genesis 427 $result = $this->import_post($AtomParser->entry);
mp-wp_genesis 428 if ( is_wp_error( $result ) )
mp-wp_genesis 429 return $result;
mp-wp_genesis 430 unset($AtomParser);
mp-wp_genesis 431 }
mp-wp_genesis 432 } else break;
mp-wp_genesis 433
mp-wp_genesis 434 // Get the 'previous' query string which we'll use on the next iteration
mp-wp_genesis 435 $query = '';
mp-wp_genesis 436 $links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches);
mp-wp_genesis 437 if ( count( $matches[1] ) )
mp-wp_genesis 438 foreach ( $matches[1] as $match )
mp-wp_genesis 439 if ( preg_match('/rel=.previous./', $match) )
mp-wp_genesis 440 $query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) );
mp-wp_genesis 441
mp-wp_genesis 442 if ( $query ) {
mp-wp_genesis 443 parse_str($query, $q);
mp-wp_genesis 444 $this->blogs[$importing_blog]['posts_start_index'] = (int) $q['start-index'];
mp-wp_genesis 445 } else
mp-wp_genesis 446 $this->blogs[$importing_blog]['posts_start_index'] = 0;
mp-wp_genesis 447 $this->save_vars();
mp-wp_genesis 448 } while ( !empty( $query ) && $this->have_time() );
mp-wp_genesis 449 }
mp-wp_genesis 450
mp-wp_genesis 451 $total_results = $this->get_total_results( 'comments', $blog['host'] );
mp-wp_genesis 452 $this->blogs[$importing_blog]['total_comments'] = $total_results;
mp-wp_genesis 453
mp-wp_genesis 454 if ( isset( $this->blogs[$importing_blog]['comments_start_index'] ) )
mp-wp_genesis 455 $start_index = (int) $this->blogs[$importing_blog]['comments_start_index'];
mp-wp_genesis 456 elseif ( $total_results > MAX_RESULTS )
mp-wp_genesis 457 $start_index = $total_results - MAX_RESULTS + 1;
mp-wp_genesis 458 else
mp-wp_genesis 459 $start_index = 1;
mp-wp_genesis 460
mp-wp_genesis 461 if ( $start_index > 0 ) {
mp-wp_genesis 462 // Grab all the comments
mp-wp_genesis 463 $this->blogs[$importing_blog]['mode'] = 'comments';
mp-wp_genesis 464 $query = "start-index=$start_index&max-results=" . MAX_RESULTS;
mp-wp_genesis 465 do {
mp-wp_genesis 466 $index = $struct = $entries = array();
mp-wp_genesis 467 $headers = array(
mp-wp_genesis 468 "GET /feeds/comments/default?$query HTTP/1.0",
mp-wp_genesis 469 "Host: {$blog['host']}",
mp-wp_genesis 470 "Authorization: AuthSub token=\"$this->token\""
mp-wp_genesis 471 );
mp-wp_genesis 472 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 473 $sock = $this->_get_blogger_sock( $blog['host'] );
mp-wp_genesis 474 if ( ! $sock ) return; // TODO: Error handling
mp-wp_genesis 475 $response = $this->_txrx( $sock, $request );
mp-wp_genesis 476
mp-wp_genesis 477 $response = $this->parse_response( $response );
mp-wp_genesis 478
mp-wp_genesis 479 // Extract the comments and send for insertion
mp-wp_genesis 480 preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches );
mp-wp_genesis 481 if ( count( $matches[0] ) ) {
mp-wp_genesis 482 $entries = array_reverse( $matches[0] );
mp-wp_genesis 483 foreach ( $entries as $entry ) {
mp-wp_genesis 484 $entry = "<feed>$entry</feed>";
mp-wp_genesis 485 $AtomParser = new AtomParser();
mp-wp_genesis 486 $AtomParser->parse( $entry );
mp-wp_genesis 487 $this->import_comment($AtomParser->entry);
mp-wp_genesis 488 unset($AtomParser);
mp-wp_genesis 489 }
mp-wp_genesis 490 }
mp-wp_genesis 491
mp-wp_genesis 492 // Get the 'previous' query string which we'll use on the next iteration
mp-wp_genesis 493 $query = '';
mp-wp_genesis 494 $links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches);
mp-wp_genesis 495 if ( count( $matches[1] ) )
mp-wp_genesis 496 foreach ( $matches[1] as $match )
mp-wp_genesis 497 if ( preg_match('/rel=.previous./', $match) )
mp-wp_genesis 498 $query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) );
mp-wp_genesis 499
mp-wp_genesis 500 parse_str($query, $q);
mp-wp_genesis 501
mp-wp_genesis 502 $this->blogs[$importing_blog]['comments_start_index'] = (int) $q['start-index'];
mp-wp_genesis 503 $this->save_vars();
mp-wp_genesis 504 } while ( !empty( $query ) && $this->have_time() );
mp-wp_genesis 505 }
mp-wp_genesis 506 $this->blogs[$importing_blog]['mode'] = 'authors';
mp-wp_genesis 507 $this->save_vars();
mp-wp_genesis 508 if ( !$this->blogs[$importing_blog]['posts_done'] && !$this->blogs[$importing_blog]['comments_done'] )
mp-wp_genesis 509 die('nothing');
mp-wp_genesis 510 do_action('import_done', 'blogger');
mp-wp_genesis 511 die('done');
mp-wp_genesis 512 }
mp-wp_genesis 513
mp-wp_genesis 514 function convert_date( $date ) {
mp-wp_genesis 515 preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\.[0-9]+)?(Z|[\+|\-][0-9]{2,4}){0,1}#', $date, $date_bits);
mp-wp_genesis 516 $offset = iso8601_timezone_to_offset( $date_bits[7] );
mp-wp_genesis 517 $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
mp-wp_genesis 518 $timestamp -= $offset; // Convert from Blogger local time to GMT
mp-wp_genesis 519 $timestamp += get_option('gmt_offset') * 3600; // Convert from GMT to WP local time
mp-wp_genesis 520 return gmdate('Y-m-d H:i:s', $timestamp);
mp-wp_genesis 521 }
mp-wp_genesis 522
mp-wp_genesis 523 function no_apos( $string ) {
mp-wp_genesis 524 return str_replace( '&apos;', "'", $string);
mp-wp_genesis 525 }
mp-wp_genesis 526
mp-wp_genesis 527 function min_whitespace( $string ) {
mp-wp_genesis 528 return preg_replace( '|\s+|', ' ', $string );
mp-wp_genesis 529 }
mp-wp_genesis 530
mp-wp_genesis 531 function import_post( $entry ) {
mp-wp_genesis 532 global $importing_blog;
mp-wp_genesis 533
mp-wp_genesis 534 // The old permalink is all Blogger gives us to link comments to their posts.
mp-wp_genesis 535 if ( isset( $entry->draft ) )
mp-wp_genesis 536 $rel = 'self';
mp-wp_genesis 537 else
mp-wp_genesis 538 $rel = 'alternate';
mp-wp_genesis 539 foreach ( $entry->links as $link ) {
mp-wp_genesis 540 if ( $link['rel'] == $rel ) {
mp-wp_genesis 541 $parts = parse_url( $link['href'] );
mp-wp_genesis 542 $entry->old_permalink = $parts['path'];
mp-wp_genesis 543 break;
mp-wp_genesis 544 }
mp-wp_genesis 545 }
mp-wp_genesis 546
mp-wp_genesis 547 $post_date = $this->convert_date( $entry->published );
mp-wp_genesis 548 $post_content = trim( addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) ) );
mp-wp_genesis 549 $post_title = trim( addslashes( $this->no_apos( $this->min_whitespace( $entry->title ) ) ) );
mp-wp_genesis 550 $post_status = isset( $entry->draft ) ? 'draft' : 'publish';
mp-wp_genesis 551
mp-wp_genesis 552 // Clean up content
mp-wp_genesis 553 $post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
mp-wp_genesis 554 $post_content = str_replace('<br>', '<br />', $post_content);
mp-wp_genesis 555 $post_content = str_replace('<hr>', '<hr />', $post_content);
mp-wp_genesis 556
mp-wp_genesis 557 // Checks for duplicates
mp-wp_genesis 558 if ( isset( $this->blogs[$importing_blog]['posts'][$entry->old_permalink] ) ) {
mp-wp_genesis 559 ++$this->blogs[$importing_blog]['posts_skipped'];
mp-wp_genesis 560 } elseif ( $post_id = post_exists( $post_title, $post_content, $post_date ) ) {
mp-wp_genesis 561 $this->blogs[$importing_blog]['posts'][$entry->old_permalink] = $post_id;
mp-wp_genesis 562 ++$this->blogs[$importing_blog]['posts_skipped'];
mp-wp_genesis 563 } else {
mp-wp_genesis 564 $post = compact('post_date', 'post_content', 'post_title', 'post_status');
mp-wp_genesis 565
mp-wp_genesis 566 $post_id = wp_insert_post($post);
mp-wp_genesis 567 if ( is_wp_error( $post_id ) )
mp-wp_genesis 568 return $post_id;
mp-wp_genesis 569
mp-wp_genesis 570 wp_create_categories( array_map( 'addslashes', $entry->categories ), $post_id );
mp-wp_genesis 571
mp-wp_genesis 572 $author = $this->no_apos( strip_tags( $entry->author ) );
mp-wp_genesis 573
mp-wp_genesis 574 add_post_meta( $post_id, 'blogger_blog', $this->blogs[$importing_blog]['host'], true );
mp-wp_genesis 575 add_post_meta( $post_id, 'blogger_author', $author, true );
mp-wp_genesis 576 add_post_meta( $post_id, 'blogger_permalink', $entry->old_permalink, true );
mp-wp_genesis 577
mp-wp_genesis 578 $this->blogs[$importing_blog]['posts'][$entry->old_permalink] = $post_id;
mp-wp_genesis 579 ++$this->blogs[$importing_blog]['posts_done'];
mp-wp_genesis 580 }
mp-wp_genesis 581 $this->save_vars();
mp-wp_genesis 582 return;
mp-wp_genesis 583 }
mp-wp_genesis 584
mp-wp_genesis 585 function import_comment( $entry ) {
mp-wp_genesis 586 global $importing_blog;
mp-wp_genesis 587
mp-wp_genesis 588 // Drop the #fragment and we have the comment's old post permalink.
mp-wp_genesis 589 foreach ( $entry->links as $link ) {
mp-wp_genesis 590 if ( $link['rel'] == 'alternate' ) {
mp-wp_genesis 591 $parts = parse_url( $link['href'] );
mp-wp_genesis 592 $entry->old_permalink = $parts['fragment'];
mp-wp_genesis 593 $entry->old_post_permalink = $parts['path'];
mp-wp_genesis 594 break;
mp-wp_genesis 595 }
mp-wp_genesis 596 }
mp-wp_genesis 597
mp-wp_genesis 598 $comment_post_ID = (int) $this->blogs[$importing_blog]['posts'][$entry->old_post_permalink];
mp-wp_genesis 599 preg_match('#<name>(.+?)</name>.*(?:\<uri>(.+?)</uri>)?#', $entry->author, $matches);
mp-wp_genesis 600 $comment_author = addslashes( $this->no_apos( strip_tags( (string) $matches[1] ) ) );
mp-wp_genesis 601 $comment_author_url = addslashes( $this->no_apos( strip_tags( (string) $matches[2] ) ) );
mp-wp_genesis 602 $comment_date = $this->convert_date( $entry->updated );
mp-wp_genesis 603 $comment_content = addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) );
mp-wp_genesis 604
mp-wp_genesis 605 // Clean up content
mp-wp_genesis 606 $comment_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $comment_content);
mp-wp_genesis 607 $comment_content = str_replace('<br>', '<br />', $comment_content);
mp-wp_genesis 608 $comment_content = str_replace('<hr>', '<hr />', $comment_content);
mp-wp_genesis 609
mp-wp_genesis 610 // Checks for duplicates
mp-wp_genesis 611 if (
mp-wp_genesis 612 isset( $this->blogs[$importing_blog]['comments'][$entry->old_permalink] ) ||
mp-wp_genesis 613 comment_exists( $comment_author, $comment_date )
mp-wp_genesis 614 ) {
mp-wp_genesis 615 ++$this->blogs[$importing_blog]['comments_skipped'];
mp-wp_genesis 616 } else {
mp-wp_genesis 617 $comment = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_date', 'comment_content');
mp-wp_genesis 618
mp-wp_genesis 619 $comment_id = wp_insert_comment($comment);
mp-wp_genesis 620
mp-wp_genesis 621 $this->blogs[$importing_blog]['comments'][$entry->old_permalink] = $comment_id;
mp-wp_genesis 622
mp-wp_genesis 623 ++$this->blogs[$importing_blog]['comments_done'];
mp-wp_genesis 624 }
mp-wp_genesis 625 $this->save_vars();
mp-wp_genesis 626 }
mp-wp_genesis 627
mp-wp_genesis 628 function get_js_status($blog = false) {
mp-wp_genesis 629 global $importing_blog;
mp-wp_genesis 630 if ( $blog === false )
mp-wp_genesis 631 $blog = $this->blogs[$importing_blog];
mp-wp_genesis 632 else
mp-wp_genesis 633 $blog = $this->blogs[$blog];
mp-wp_genesis 634 $p1 = isset( $blog['posts_done'] ) ? (int) $blog['posts_done'] : 0;
mp-wp_genesis 635 $p2 = isset( $blog['total_posts'] ) ? (int) $blog['total_posts'] : 0;
mp-wp_genesis 636 $c1 = isset( $blog['comments_done'] ) ? (int) $blog['comments_done'] : 0;
mp-wp_genesis 637 $c2 = isset( $blog['total_comments'] ) ? (int) $blog['total_comments'] : 0;
mp-wp_genesis 638 return "{p1:$p1,p2:$p2,c1:$c1,c2:$c2}";
mp-wp_genesis 639 }
mp-wp_genesis 640
mp-wp_genesis 641 function get_author_form($blog = false) {
mp-wp_genesis 642 global $importing_blog, $wpdb, $current_user;
mp-wp_genesis 643 if ( $blog === false )
mp-wp_genesis 644 $blog = & $this->blogs[$importing_blog];
mp-wp_genesis 645 else
mp-wp_genesis 646 $blog = & $this->blogs[$blog];
mp-wp_genesis 647
mp-wp_genesis 648 if ( !isset( $blog['authors'] ) ) {
mp-wp_genesis 649 $post_ids = array_values($blog['posts']);
mp-wp_genesis 650 $authors = (array) $wpdb->get_col("SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN (" . join( ',', $post_ids ) . ")");
mp-wp_genesis 651 $blog['authors'] = array_map(null, $authors, array_fill(0, count($authors), $current_user->ID));
mp-wp_genesis 652 $this->save_vars();
mp-wp_genesis 653 }
mp-wp_genesis 654
mp-wp_genesis 655 $directions = __('All posts were imported with the current user as author. Use this form to move each Blogger user\'s posts to a different WordPress user. You may <a href="users.php">add users</a> and then return to this page and complete the user mapping. This form may be used as many times as you like until you activate the "Restart" function below.');
mp-wp_genesis 656 $heading = __('Author mapping');
mp-wp_genesis 657 $blogtitle = "{$blog['title']} ({$blog['host']})";
mp-wp_genesis 658 $mapthis = __('Blogger username');
mp-wp_genesis 659 $tothis = __('WordPress login');
mp-wp_genesis 660 $submit = js_escape( __('Save Changes') );
mp-wp_genesis 661
mp-wp_genesis 662 foreach ( $blog['authors'] as $i => $author )
mp-wp_genesis 663 $rows .= "<tr><td><label for='authors[$i]'>{$author[0]}</label></td><td><select name='authors[$i]' id='authors[$i]'>" . $this->get_user_options($author[1]) . "</select></td></tr>";
mp-wp_genesis 664
mp-wp_genesis 665 return "<div class='wrap'><h2>$heading</h2><h3>$blogtitle</h3><p>$directions</p><form action='index.php?import=blogger&amp;noheader=true&saveauthors=1' method='post'><input type='hidden' name='blog' value='$importing_blog' /><table cellpadding='5'><thead><td>$mapthis</td><td>$tothis</td></thead>$rows<tr><td></td><td class='submit'><input type='submit' class='button authorsubmit' value='$submit' /></td></tr></table></form></div>";
mp-wp_genesis 666 }
mp-wp_genesis 667
mp-wp_genesis 668 function get_user_options($current) {
mp-wp_genesis 669 global $importer_users;
mp-wp_genesis 670 if ( ! isset( $importer_users ) )
mp-wp_genesis 671 $importer_users = (array) get_users_of_blog();
mp-wp_genesis 672
mp-wp_genesis 673 foreach ( $importer_users as $user ) {
mp-wp_genesis 674 $sel = ( $user->user_id == $current ) ? " selected='selected'" : '';
mp-wp_genesis 675 $options .= "<option value='$user->user_id'$sel>$user->display_name</option>";
mp-wp_genesis 676 }
mp-wp_genesis 677
mp-wp_genesis 678 return $options;
mp-wp_genesis 679 }
mp-wp_genesis 680
mp-wp_genesis 681 function save_authors() {
mp-wp_genesis 682 global $importing_blog, $wpdb;
mp-wp_genesis 683 $authors = (array) $_POST['authors'];
mp-wp_genesis 684
mp-wp_genesis 685 $host = $this->blogs[$importing_blog]['host'];
mp-wp_genesis 686
mp-wp_genesis 687 // Get an array of posts => authors
mp-wp_genesis 688 $post_ids = (array) $wpdb->get_col( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'blogger_blog' AND meta_value = %s", $host) );
mp-wp_genesis 689 $post_ids = join( ',', $post_ids );
mp-wp_genesis 690 $results = (array) $wpdb->get_results("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN ($post_ids)");
mp-wp_genesis 691 foreach ( $results as $row )
mp-wp_genesis 692 $authors_posts[$row->post_id] = $row->meta_value;
mp-wp_genesis 693
mp-wp_genesis 694 foreach ( $authors as $author => $user_id ) {
mp-wp_genesis 695 $user_id = (int) $user_id;
mp-wp_genesis 696
mp-wp_genesis 697 // Skip authors that haven't been changed
mp-wp_genesis 698 if ( $user_id == $this->blogs[$importing_blog]['authors'][$author][1] )
mp-wp_genesis 699 continue;
mp-wp_genesis 700
mp-wp_genesis 701 // Get a list of the selected author's posts
mp-wp_genesis 702 $post_ids = (array) array_keys( $authors_posts, $this->blogs[$importing_blog]['authors'][$author][0] );
mp-wp_genesis 703 $post_ids = join( ',', $post_ids);
mp-wp_genesis 704
mp-wp_genesis 705 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_author = %d WHERE id IN ($post_ids)", $user_id) );
mp-wp_genesis 706 $this->blogs[$importing_blog]['authors'][$author][1] = $user_id;
mp-wp_genesis 707 }
mp-wp_genesis 708 $this->save_vars();
mp-wp_genesis 709
mp-wp_genesis 710 wp_redirect('edit.php');
mp-wp_genesis 711 }
mp-wp_genesis 712
mp-wp_genesis 713 function _get_auth_sock() {
mp-wp_genesis 714 // Connect to https://www.google.com
mp-wp_genesis 715 if ( !$sock = @ fsockopen('ssl://www.google.com', 443, $errno, $errstr) ) {
mp-wp_genesis 716 $this->uh_oh(
mp-wp_genesis 717 __('Could not connect to https://www.google.com'),
mp-wp_genesis 718 __('There was a problem opening a secure connection to Google. This is what went wrong:'),
mp-wp_genesis 719 "$errstr ($errno)"
mp-wp_genesis 720 );
mp-wp_genesis 721 return false;
mp-wp_genesis 722 }
mp-wp_genesis 723 return $sock;
mp-wp_genesis 724 }
mp-wp_genesis 725
mp-wp_genesis 726 function _get_blogger_sock($host = 'www2.blogger.com') {
mp-wp_genesis 727 if ( !$sock = @ fsockopen($host, 80, $errno, $errstr) ) {
mp-wp_genesis 728 $this->uh_oh(
mp-wp_genesis 729 sprintf( __('Could not connect to %s'), $host ),
mp-wp_genesis 730 __('There was a problem opening a connection to Blogger. This is what went wrong:'),
mp-wp_genesis 731 "$errstr ($errno)"
mp-wp_genesis 732 );
mp-wp_genesis 733 return false;
mp-wp_genesis 734 }
mp-wp_genesis 735 return $sock;
mp-wp_genesis 736 }
mp-wp_genesis 737
mp-wp_genesis 738 function _txrx( $sock, $request ) {
mp-wp_genesis 739 fwrite( $sock, $request );
mp-wp_genesis 740 while ( ! feof( $sock ) )
mp-wp_genesis 741 $response .= @ fread ( $sock, 8192 );
mp-wp_genesis 742 fclose( $sock );
mp-wp_genesis 743 return $response;
mp-wp_genesis 744 }
mp-wp_genesis 745
mp-wp_genesis 746 function revoke($token) {
mp-wp_genesis 747 $headers = array(
mp-wp_genesis 748 "GET /accounts/AuthSubRevokeToken HTTP/1.0",
mp-wp_genesis 749 "Authorization: AuthSub token=\"$token\""
mp-wp_genesis 750 );
mp-wp_genesis 751 $request = join( "\r\n", $headers ) . "\r\n\r\n";
mp-wp_genesis 752 $sock = $this->_get_auth_sock( );
mp-wp_genesis 753 if ( ! $sock ) return false;
mp-wp_genesis 754 $this->_txrx( $sock, $request );
mp-wp_genesis 755 }
mp-wp_genesis 756
mp-wp_genesis 757 function restart() {
mp-wp_genesis 758 global $wpdb;
mp-wp_genesis 759 $options = get_option( 'blogger_importer' );
mp-wp_genesis 760
mp-wp_genesis 761 if ( isset( $options['token'] ) )
mp-wp_genesis 762 $this->revoke( $options['token'] );
mp-wp_genesis 763
mp-wp_genesis 764 delete_option('blogger_importer');
mp-wp_genesis 765 $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_key = 'blogger_author'");
mp-wp_genesis 766 wp_redirect('?import=blogger');
mp-wp_genesis 767 }
mp-wp_genesis 768
mp-wp_genesis 769 // Returns associative array of code, header, cookies, body. Based on code from php.net.
mp-wp_genesis 770 function parse_response($this_response) {
mp-wp_genesis 771 // Split response into header and body sections
mp-wp_genesis 772 list($response_headers, $response_body) = explode("\r\n\r\n", $this_response, 2);
mp-wp_genesis 773 $response_header_lines = explode("\r\n", $response_headers);
mp-wp_genesis 774
mp-wp_genesis 775 // First line of headers is the HTTP response code
mp-wp_genesis 776 $http_response_line = array_shift($response_header_lines);
mp-wp_genesis 777 if(preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@',$http_response_line, $matches)) { $response_code = $matches[1]; }
mp-wp_genesis 778
mp-wp_genesis 779 // put the rest of the headers in an array
mp-wp_genesis 780 $response_header_array = array();
mp-wp_genesis 781 foreach($response_header_lines as $header_line) {
mp-wp_genesis 782 list($header,$value) = explode(': ', $header_line, 2);
mp-wp_genesis 783 $response_header_array[$header] .= $value."\n";
mp-wp_genesis 784 }
mp-wp_genesis 785
mp-wp_genesis 786 $cookie_array = array();
mp-wp_genesis 787 $cookies = explode("\n", $response_header_array["Set-Cookie"]);
mp-wp_genesis 788 foreach($cookies as $this_cookie) { array_push($cookie_array, "Cookie: ".$this_cookie); }
mp-wp_genesis 789
mp-wp_genesis 790 return array("code" => $response_code, "header" => $response_header_array, "cookies" => $cookie_array, "body" => $response_body);
mp-wp_genesis 791 }
mp-wp_genesis 792
mp-wp_genesis 793 // Step 9: Congratulate the user
mp-wp_genesis 794 function congrats() {
mp-wp_genesis 795 $blog = (int) $_GET['blog'];
mp-wp_genesis 796 echo '<h1>'.__('Congratulations!').'</h1><p>'.__('Now that you have imported your Blogger blog into WordPress, what are you going to do? Here are some suggestions:').'</p><ul><li>'.__('That was hard work! Take a break.').'</li>';
mp-wp_genesis 797 if ( count($this->import['blogs']) > 1 )
mp-wp_genesis 798 echo '<li>'.__('In case you haven\'t done it already, you can import the posts from your other blogs:'). $this->show_blogs() . '</li>';
mp-wp_genesis 799 if ( $n = count($this->import['blogs'][$blog]['newusers']) )
mp-wp_genesis 800 echo '<li>'.sprintf(__('Go to <a href="%s" target="%s">Authors &amp; Users</a>, where you can modify the new user(s) or delete them. If you want to make all of the imported posts yours, you will be given that option when you delete the new authors.'), 'users.php', '_parent').'</li>';
mp-wp_genesis 801 echo '<li>'.__('For security, click the link below to reset this importer.').'</li>';
mp-wp_genesis 802 echo '</ul>';
mp-wp_genesis 803 }
mp-wp_genesis 804
mp-wp_genesis 805 // Figures out what to do, then does it.
mp-wp_genesis 806 function start() {
mp-wp_genesis 807 if ( isset($_POST['restart']) )
mp-wp_genesis 808 $this->restart();
mp-wp_genesis 809
mp-wp_genesis 810 $options = get_option('blogger_importer');
mp-wp_genesis 811
mp-wp_genesis 812 if ( is_array($options) )
mp-wp_genesis 813 foreach ( $options as $key => $value )
mp-wp_genesis 814 $this->$key = $value;
mp-wp_genesis 815
mp-wp_genesis 816 if ( isset( $_REQUEST['blog'] ) ) {
mp-wp_genesis 817 $blog = is_array($_REQUEST['blog']) ? array_shift( $keys = array_keys( $_REQUEST['blog'] ) ) : $_REQUEST['blog'];
mp-wp_genesis 818 $blog = (int) $blog;
mp-wp_genesis 819 $result = $this->import_blog( $blog );
mp-wp_genesis 820 if ( is_wp_error( $result ) )
mp-wp_genesis 821 echo $result->get_error_message();
mp-wp_genesis 822 } elseif ( isset($_GET['token']) )
mp-wp_genesis 823 $this->auth();
mp-wp_genesis 824 elseif ( isset($this->token) && $this->token_is_valid() )
mp-wp_genesis 825 $this->show_blogs();
mp-wp_genesis 826 else
mp-wp_genesis 827 $this->greet();
mp-wp_genesis 828
mp-wp_genesis 829 $saved = $this->save_vars();
mp-wp_genesis 830
mp-wp_genesis 831 if ( $saved && !isset($_GET['noheader']) ) {
mp-wp_genesis 832 $restart = __('Restart');
mp-wp_genesis 833 $message = __('We have saved some information about your Blogger account in your WordPress database. Clearing this information will allow you to start over. Restarting will not affect any posts you have already imported. If you attempt to re-import a blog, duplicate posts and comments will be skipped.');
mp-wp_genesis 834 $submit = __('Clear account information');
mp-wp_genesis 835 echo "<div class='wrap'><h2>$restart</h2><p>$message</p><form method='post' action='?import=blogger&amp;noheader=true'><p class='submit' style='text-align:left;'><input type='submit' class='button' value='$submit' name='restart' /></p></form></div>";
mp-wp_genesis 836 }
mp-wp_genesis 837 }
mp-wp_genesis 838
mp-wp_genesis 839 function save_vars() {
mp-wp_genesis 840 $vars = get_object_vars($this);
mp-wp_genesis 841 update_option( 'blogger_importer', $vars );
mp-wp_genesis 842
mp-wp_genesis 843 return !empty($vars);
mp-wp_genesis 844 }
mp-wp_genesis 845
mp-wp_genesis 846 function admin_head() {
mp-wp_genesis 847 ?>
mp-wp_genesis 848 <style type="text/css">
mp-wp_genesis 849 td { text-align: center; line-height: 2em;}
mp-wp_genesis 850 thead td { font-weight: bold; }
mp-wp_genesis 851 .bar {
mp-wp_genesis 852 width: 200px;
mp-wp_genesis 853 text-align: left;
mp-wp_genesis 854 line-height: 2em;
mp-wp_genesis 855 padding: 0px;
mp-wp_genesis 856 }
mp-wp_genesis 857 .ind {
mp-wp_genesis 858 position: absolute;
mp-wp_genesis 859 background-color: #83B4D8;
mp-wp_genesis 860 width: 1px;
mp-wp_genesis 861 z-index: 9;
mp-wp_genesis 862 }
mp-wp_genesis 863 .stat {
mp-wp_genesis 864 z-index: 10;
mp-wp_genesis 865 position: relative;
mp-wp_genesis 866 text-align: center;
mp-wp_genesis 867 }
mp-wp_genesis 868 </style>
mp-wp_genesis 869 <?php
mp-wp_genesis 870 }
mp-wp_genesis 871
mp-wp_genesis 872 function Blogger_Import() {
mp-wp_genesis 873 global $importer_started;
mp-wp_genesis 874 $importer_started = time();
mp-wp_genesis 875 if ( isset( $_GET['import'] ) && $_GET['import'] == 'blogger' ) {
mp-wp_genesis 876 wp_enqueue_script('jquery');
mp-wp_genesis 877 add_action('admin_head', array(&$this, 'admin_head'));
mp-wp_genesis 878 }
mp-wp_genesis 879 }
mp-wp_genesis 880 }
mp-wp_genesis 881
mp-wp_genesis 882 $blogger_import = new Blogger_Import();
mp-wp_genesis 883
mp-wp_genesis 884 register_importer('blogger', __('Blogger'), __('Import posts, comments, and users from a Blogger blog.'), array ($blogger_import, 'start'));
mp-wp_genesis 885
mp-wp_genesis 886 class AtomEntry {
mp-wp_genesis 887 var $links = array();
mp-wp_genesis 888 var $categories = array();
mp-wp_genesis 889 }
mp-wp_genesis 890
mp-wp_genesis 891 class AtomParser {
mp-wp_genesis 892
mp-wp_genesis 893 var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');
mp-wp_genesis 894 var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft','author');
mp-wp_genesis 895
mp-wp_genesis 896 var $depth = 0;
mp-wp_genesis 897 var $indent = 2;
mp-wp_genesis 898 var $in_content;
mp-wp_genesis 899 var $ns_contexts = array();
mp-wp_genesis 900 var $ns_decls = array();
mp-wp_genesis 901 var $is_xhtml = false;
mp-wp_genesis 902 var $skipped_div = false;
mp-wp_genesis 903
mp-wp_genesis 904 var $entry;
mp-wp_genesis 905
mp-wp_genesis 906 function AtomParser() {
mp-wp_genesis 907
mp-wp_genesis 908 $this->entry = new AtomEntry();
mp-wp_genesis 909 $this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";');
mp-wp_genesis 910 $this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";');
mp-wp_genesis 911 }
mp-wp_genesis 912
mp-wp_genesis 913 function parse($xml) {
mp-wp_genesis 914
mp-wp_genesis 915 global $app_logging;
mp-wp_genesis 916 array_unshift($this->ns_contexts, array());
mp-wp_genesis 917
mp-wp_genesis 918 $parser = xml_parser_create_ns();
mp-wp_genesis 919 xml_set_object($parser, $this);
mp-wp_genesis 920 xml_set_element_handler($parser, "start_element", "end_element");
mp-wp_genesis 921 xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
mp-wp_genesis 922 xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
mp-wp_genesis 923 xml_set_character_data_handler($parser, "cdata");
mp-wp_genesis 924 xml_set_default_handler($parser, "_default");
mp-wp_genesis 925 xml_set_start_namespace_decl_handler($parser, "start_ns");
mp-wp_genesis 926 xml_set_end_namespace_decl_handler($parser, "end_ns");
mp-wp_genesis 927
mp-wp_genesis 928 $contents = "";
mp-wp_genesis 929
mp-wp_genesis 930 xml_parse($parser, $xml);
mp-wp_genesis 931
mp-wp_genesis 932 xml_parser_free($parser);
mp-wp_genesis 933
mp-wp_genesis 934 return true;
mp-wp_genesis 935 }
mp-wp_genesis 936
mp-wp_genesis 937 function start_element($parser, $name, $attrs) {
mp-wp_genesis 938
mp-wp_genesis 939 $tag = array_pop(split(":", $name));
mp-wp_genesis 940
mp-wp_genesis 941 array_unshift($this->ns_contexts, $this->ns_decls);
mp-wp_genesis 942
mp-wp_genesis 943 $this->depth++;
mp-wp_genesis 944
mp-wp_genesis 945 if(!empty($this->in_content)) {
mp-wp_genesis 946 $attrs_prefix = array();
mp-wp_genesis 947
mp-wp_genesis 948 // resolve prefixes for attributes
mp-wp_genesis 949 foreach($attrs as $key => $value) {
mp-wp_genesis 950 $attrs_prefix[$this->ns_to_prefix($key)] = $this->xml_escape($value);
mp-wp_genesis 951 }
mp-wp_genesis 952 $attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));
mp-wp_genesis 953 if(strlen($attrs_str) > 0) {
mp-wp_genesis 954 $attrs_str = " " . $attrs_str;
mp-wp_genesis 955 }
mp-wp_genesis 956
mp-wp_genesis 957 $xmlns_str = join(' ', array_map($this->map_xmlns_func, array_keys($this->ns_contexts[0]), array_values($this->ns_contexts[0])));
mp-wp_genesis 958 if(strlen($xmlns_str) > 0) {
mp-wp_genesis 959 $xmlns_str = " " . $xmlns_str;
mp-wp_genesis 960 }
mp-wp_genesis 961
mp-wp_genesis 962 // handle self-closing tags (case: a new child found right-away, no text node)
mp-wp_genesis 963 if(count($this->in_content) == 2) {
mp-wp_genesis 964 array_push($this->in_content, ">");
mp-wp_genesis 965 }
mp-wp_genesis 966
mp-wp_genesis 967 array_push($this->in_content, "<". $this->ns_to_prefix($name) ."{$xmlns_str}{$attrs_str}");
mp-wp_genesis 968 } else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {
mp-wp_genesis 969 $this->in_content = array();
mp-wp_genesis 970 $this->is_xhtml = $attrs['type'] == 'xhtml';
mp-wp_genesis 971 array_push($this->in_content, array($tag,$this->depth));
mp-wp_genesis 972 } else if($tag == 'link') {
mp-wp_genesis 973 array_push($this->entry->links, $attrs);
mp-wp_genesis 974 } else if($tag == 'category') {
mp-wp_genesis 975 array_push($this->entry->categories, $attrs['term']);
mp-wp_genesis 976 }
mp-wp_genesis 977
mp-wp_genesis 978 $this->ns_decls = array();
mp-wp_genesis 979 }
mp-wp_genesis 980
mp-wp_genesis 981 function end_element($parser, $name) {
mp-wp_genesis 982
mp-wp_genesis 983 $tag = array_pop(split(":", $name));
mp-wp_genesis 984
mp-wp_genesis 985 if(!empty($this->in_content)) {
mp-wp_genesis 986 if($this->in_content[0][0] == $tag &&
mp-wp_genesis 987 $this->in_content[0][1] == $this->depth) {
mp-wp_genesis 988 array_shift($this->in_content);
mp-wp_genesis 989 if($this->is_xhtml) {
mp-wp_genesis 990 $this->in_content = array_slice($this->in_content, 2, count($this->in_content)-3);
mp-wp_genesis 991 }
mp-wp_genesis 992 $this->entry->$tag = join('',$this->in_content);
mp-wp_genesis 993 $this->in_content = array();
mp-wp_genesis 994 } else {
mp-wp_genesis 995 $endtag = $this->ns_to_prefix($name);
mp-wp_genesis 996 if (strpos($this->in_content[count($this->in_content)-1], '<' . $endtag) !== false) {
mp-wp_genesis 997 array_push($this->in_content, "/>");
mp-wp_genesis 998 } else {
mp-wp_genesis 999 array_push($this->in_content, "</$endtag>");
mp-wp_genesis 1000 }
mp-wp_genesis 1001 }
mp-wp_genesis 1002 }
mp-wp_genesis 1003
mp-wp_genesis 1004 array_shift($this->ns_contexts);
mp-wp_genesis 1005
mp-wp_genesis 1006 #print str_repeat(" ", $this->depth * $this->indent) . "end_element('$name')" ."\n";
mp-wp_genesis 1007
mp-wp_genesis 1008 $this->depth--;
mp-wp_genesis 1009 }
mp-wp_genesis 1010
mp-wp_genesis 1011 function start_ns($parser, $prefix, $uri) {
mp-wp_genesis 1012 #print str_repeat(" ", $this->depth * $this->indent) . "starting: " . $prefix . ":" . $uri . "\n";
mp-wp_genesis 1013 array_push($this->ns_decls, array($prefix,$uri));
mp-wp_genesis 1014 }
mp-wp_genesis 1015
mp-wp_genesis 1016 function end_ns($parser, $prefix) {
mp-wp_genesis 1017 #print str_repeat(" ", $this->depth * $this->indent) . "ending: #" . $prefix . "#\n";
mp-wp_genesis 1018 }
mp-wp_genesis 1019
mp-wp_genesis 1020 function cdata($parser, $data) {
mp-wp_genesis 1021 #print str_repeat(" ", $this->depth * $this->indent) . "data: #" . $data . "#\n";
mp-wp_genesis 1022 if(!empty($this->in_content)) {
mp-wp_genesis 1023 // handle self-closing tags (case: text node found, need to close element started)
mp-wp_genesis 1024 if (strpos($this->in_content[count($this->in_content)-1], '<') !== false) {
mp-wp_genesis 1025 array_push($this->in_content, ">");
mp-wp_genesis 1026 }
mp-wp_genesis 1027 array_push($this->in_content, $this->xml_escape($data));
mp-wp_genesis 1028 }
mp-wp_genesis 1029 }
mp-wp_genesis 1030
mp-wp_genesis 1031 function _default($parser, $data) {
mp-wp_genesis 1032 # when does this gets called?
mp-wp_genesis 1033 }
mp-wp_genesis 1034
mp-wp_genesis 1035
mp-wp_genesis 1036 function ns_to_prefix($qname) {
mp-wp_genesis 1037 $components = split(":", $qname);
mp-wp_genesis 1038 $name = array_pop($components);
mp-wp_genesis 1039
mp-wp_genesis 1040 if(!empty($components)) {
mp-wp_genesis 1041 $ns = join(":",$components);
mp-wp_genesis 1042 foreach($this->ns_contexts as $context) {
mp-wp_genesis 1043 foreach($context as $mapping) {
mp-wp_genesis 1044 if($mapping[1] == $ns && strlen($mapping[0]) > 0) {
mp-wp_genesis 1045 return "$mapping[0]:$name";
mp-wp_genesis 1046 }
mp-wp_genesis 1047 }
mp-wp_genesis 1048 }
mp-wp_genesis 1049 }
mp-wp_genesis 1050 return $name;
mp-wp_genesis 1051 }
mp-wp_genesis 1052
mp-wp_genesis 1053 function xml_escape($string)
mp-wp_genesis 1054 {
mp-wp_genesis 1055 return str_replace(array('&','"',"'",'<','>'),
mp-wp_genesis 1056 array('&amp;','&quot;','&apos;','&lt;','&gt;'),
mp-wp_genesis 1057 $string );
mp-wp_genesis 1058 }
mp-wp_genesis 1059 }
mp-wp_genesis 1060
mp-wp_genesis 1061 ?>