+ $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).');
+ $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.');
+ $auth = __('Authorize');
+
+ echo "
+ <div class='wrap'><h2>$title</h2><p>$welcome</p><p>$prereqs</p><p>$stepone</p>
+ <form action='$auth_url' method='get'>
+ <p class='submit' style='text-align:left;'>
+ <input type='submit' class='button' value='$auth' />
+ <input type='hidden' name='scope' value='http://www.blogger.com/feeds/' />
+ <input type='hidden' name='session' value='1' />
+ <input type='hidden' name='secure' value='0' />
+ <input type='hidden' name='next' value='$next_url' />
+ </p>
+ </form>
+ </div>\n";
+ }
+
+ function uh_oh($title, $message, $info) {
+ echo "<div class='wrap'><h2>$title</h2><p>$message</p><pre>$info</pre></div>";
+ }
+
+ function auth() {
+ // We have a single-use token that must be upgraded to a session token.
+ $token = preg_replace( '/[^-_0-9a-zA-Z]/', '', $_GET['token'] );
+ $headers = array(
+ "GET /accounts/AuthSubSessionToken HTTP/1.0",
+ "Authorization: AuthSub token=\"$token\""
+ );
+ $request = join( "\r\n", $headers ) . "\r\n\r\n";
+ $sock = $this->_get_auth_sock( );
+ if ( ! $sock ) return false;
+ $response = $this->_txrx( $sock, $request );
+ preg_match( '/token=([-_0-9a-z]+)/i', $response, $matches );
+ if ( empty( $matches[1] ) ) {
+ $this->uh_oh(
+ __( 'Authorization failed' ),
+ __( 'Something went wrong. If the problem persists, send this info to support:' ),
+ htmlspecialchars($response)
+ );
+ return false;
+ }
+ $this->token = $matches[1];
+
+ wp_redirect( remove_query_arg( array( 'token', 'noheader' ) ) );
+ }
+
+ function get_token_info() {
+ $headers = array(
+ "GET /accounts/AuthSubTokenInfo HTTP/1.0",
+ "Authorization: AuthSub token=\"$this->token\""
+ );
+ $request = join( "\r\n", $headers ) . "\r\n\r\n";
+ $sock = $this->_get_auth_sock( );
+ if ( ! $sock ) return;
+ $response = $this->_txrx( $sock, $request );
+ return $this->parse_response($response);
+ }
+
+ function token_is_valid() {
+ $info = $this->get_token_info();
+
+ if ( $info['code'] == 200 )
+ return true;
+
+ return false;
+ }
+
+ function show_blogs($iter = 0) {
+ if ( empty($this->blogs) ) {
+ $headers = array(
+ "GET /feeds/default/blogs HTTP/1.0",
+ "Host: www.blogger.com",
+ "Authorization: AuthSub token=\"$this->token\""
+ );
+ $request = join( "\r\n", $headers ) . "\r\n\r\n";
+ $sock = $this->_get_blogger_sock( );
+ if ( ! $sock ) return;
+ $response = $this->_txrx( $sock, $request );
+
+ // Quick and dirty XML mining.
+ list( $headers, $xml ) = explode( "\r\n\r\n", $response );
+ $p = xml_parser_create();
+ xml_parse_into_struct($p, $xml, $vals, $index);
+ xml_parser_free($p);
+
+ $this->title = $vals[$index['TITLE'][0]]['value'];
+
+ // Give it a few retries... this step often flakes out the first time.
+ if ( empty( $index['ENTRY'] ) ) {
+ if ( $iter < 3 ) {
+ return $this->show_blogs($iter + 1);
+ } else {
+ $this->uh_oh(
+ __('Trouble signing in'),
+ __('We were not able to gain access to your account. Try starting over.'),
+ ''
+ );
+ return false;
+ }
+ }
+
+ foreach ( $index['ENTRY'] as $i ) {
+ $blog = array();
+ while ( ( $tag = $vals[$i] ) && ! ( $tag['tag'] == 'ENTRY' && $tag['type'] == 'close' ) ) {
+ if ( $tag['tag'] == 'TITLE' ) {
+ $blog['title'] = $tag['value'];
+ } elseif ( $tag['tag'] == 'SUMMARY' ) {
+ $blog['summary'] == $tag['value'];
+ } elseif ( $tag['tag'] == 'LINK' ) {
+ if ( $tag['attributes']['REL'] == 'alternate' && $tag['attributes']['TYPE'] == 'text/html' ) {
+ $parts = parse_url( $tag['attributes']['HREF'] );
+ $blog['host'] = $parts['host'];
+ } elseif ( $tag['attributes']['REL'] == 'edit' )
+ $blog['gateway'] = $tag['attributes']['HREF'];
+ }
+ ++$i;
+ }
+ if ( ! empty ( $blog ) ) {
+ $blog['total_posts'] = $this->get_total_results('posts', $blog['host']);
+ $blog['total_comments'] = $this->get_total_results('comments', $blog['host']);
+ $blog['mode'] = 'init';
+ $this->blogs[] = $blog;
+ }
+ }
+
+ if ( empty( $this->blogs ) ) {
+ $this->uh_oh(
+ __('No blogs found'),
+ __('We were able to log in but there were no blogs. Try a different account next time.'),
+ ''
+ );
+ return false;
+ }
+ }
+//echo '<pre>'.print_r($this,1).'</pre>';
+ $start = js_escape( __('Import') );
+ $continue = js_escape( __('Continue') );
+ $stop = js_escape( __('Importing...') );
+ $authors = js_escape( __('Set Authors') );
+ $loadauth = js_escape( __('Preparing author mapping form...') );
+ $authhead = js_escape( __('Final Step: Author Mapping') );
+ $nothing = js_escape( __('Nothing was imported. Had you already imported this blog?') );
+ $title = __('Blogger Blogs');
+ $name = __('Blog Name');
+ $url = __('Blog URL');
+ $action = __('The Magic Button');
+ $posts = __('Posts');
+ $comments = __('Comments');
+ $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.');
+
+ $interval = STATUS_INTERVAL * 1000;
+
+ foreach ( $this->blogs as $i => $blog ) {
+ if ( $blog['mode'] == 'init' )
+ $value = $start;
+ elseif ( $blog['mode'] == 'posts' || $blog['mode'] == 'comments' )
+ $value = $continue;
+ else
+ $value = $authors;
+ $blogtitle = js_escape( $blog['title'] );
+ $pdone = isset($blog['posts_done']) ? (int) $blog['posts_done'] : 0;
+ $cdone = isset($blog['comments_done']) ? (int) $blog['comments_done'] : 0;
+ $init .= "blogs[$i]=new blog($i,'$blogtitle','{$blog['mode']}'," . $this->get_js_status($i) . ');';
+ $pstat = "<div class='ind' id='pind$i'> </div><div id='pstat$i' class='stat'>$pdone/{$blog['total_posts']}</div>";
+ $cstat = "<div class='ind' id='cind$i'> </div><div id='cstat$i' class='stat'>$cdone/{$blog['total_comments']}</div>";
+ $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";
+ }
+
+ echo "<div class='wrap'><h2>$title</h2><noscript>$noscript</noscript><table cellpadding='5px'><thead><td>$name</td><td>$url</td><td>$posts</td><td>$comments</td><td>$action</td></thead>\n$rows</table></form></div>";
+ echo "
+ <script type='text/javascript'>
+ var strings = {cont:'$continue',stop:'$stop',stopping:'$stopping',authors:'$authors',nothing:'$nothing'};
+ var blogs = {};
+ function blog(i, title, mode, status){
+ this.blog = i;
+ this.mode = mode;
+ this.title = title;
+ this.status = status;
+ this.button = document.getElementById('submit'+this.blog);
+ };
+ blog.prototype = {
+ start: function() {
+ this.cont = true;
+ this.kick();
+ this.check();
+ },
+ kick: function() {
+ ++this.kicks;
+ var i = this.blog;
+ jQuery.post('admin.php?import=blogger&noheader=true',{blog:this.blog},function(text,result){blogs[i].kickd(text,result)});
+ },
+ check: function() {
+ ++this.checks;
+ var i = this.blog;
+ jQuery.post('admin.php?import=blogger&noheader=true&status=true',{blog:this.blog},function(text,result){blogs[i].checkd(text,result)});
+ },
+ kickd: function(text, result) {
+ if ( result == 'error' ) {
+ // TODO: exception handling
+ if ( this.cont )
+ setTimeout('blogs['+this.blog+'].kick()', 1000);
+ } else {
+ if ( text == 'done' ) {
+ this.stop();
+ this.done();
+ } else if ( text == 'nothing' ) {
+ this.stop();
+ this.nothing();
+ } else if ( text == 'continue' ) {
+ this.kick();
+ } else if ( this.mode = 'stopped' )
+ jQuery(this.button).attr('value', strings.cont);
+ }
+ --this.kicks;
+ },
+ checkd: function(text, result) {
+ if ( result == 'error' ) {
+ // TODO: exception handling
+ } else {
+ eval('this.status='+text);
+ jQuery('#pstat'+this.blog).empty().append(this.status.p1+'/'+this.status.p2);
+ jQuery('#cstat'+this.blog).empty().append(this.status.c1+'/'+this.status.c2);
+ this.update();
+ if ( this.cont || this.kicks > 0 )
+ setTimeout('blogs['+this.blog+'].check()', $interval);
+ }
+ --this.checks;
+ },
+ update: function() {
+ 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');
+ 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');
+ },
+ stop: function() {
+ this.cont = false;
+ },
+ done: function() {
+ this.mode = 'authors';
+ jQuery(this.button).attr('value', strings.authors);
+ },
+ nothing: function() {
+ this.mode = 'nothing';
+ jQuery(this.button).remove();
+ alert(strings.nothing);
+ },
+ getauthors: function() {
+ if ( jQuery('div.wrap').length > 1 )
+ jQuery('div.wrap').gt(0).remove();
+ jQuery('div.wrap').empty().append('<h2>$authhead</h2><h3>' + this.title + '</h3>');
+ jQuery('div.wrap').append('<p id=\"auth\">$loadauth</p>');
+ jQuery('p#auth').load('index.php?import=blogger&noheader=true&authors=1',{blog:this.blog});
+ },
+ init: function() {
+ this.update();
+ var i = this.blog;
+ jQuery(this.button).bind('click', function(){return blogs[i].click();});
+ this.kicks = 0;
+ this.checks = 0;
+ },
+ click: function() {
+ if ( this.mode == 'init' || this.mode == 'stopped' || this.mode == 'posts' || this.mode == 'comments' ) {
+ this.mode = 'started';
+ this.start();
+ jQuery(this.button).attr('value', strings.stop);
+ } else if ( this.mode == 'started' ) {
+ return false; // let it run...
+ this.mode = 'stopped';
+ this.stop();
+ if ( this.checks > 0 || this.kicks > 0 ) {
+ this.mode = 'stopping';
+ jQuery(this.button).attr('value', strings.stopping);
+ } else {
+ jQuery(this.button).attr('value', strings.cont);
+ }
+ } else if ( this.mode == 'authors' ) {
+ document.location = 'index.php?import=blogger&authors=1&blog='+this.blog;
+ //this.mode = 'authors2';
+ //this.getauthors();
+ }
+ return false;
+ }
+ };
+ $init
+ jQuery.each(blogs, function(i, me){me.init();});
+ </script>\n";
+ }
+
+ // Handy function for stopping the script after a number of seconds.
+ function have_time() {
+ global $importer_started;
+ if ( time() - $importer_started > MAX_EXECUTION_TIME )
+ die('continue');
+ return true;
+ }
+
+ function get_total_results($type, $host) {
+ $headers = array(
+ "GET /feeds/$type/default?max-results=1&start-index=2 HTTP/1.0",
+ "Host: $host",
+ "Authorization: AuthSub token=\"$this->token\""
+ );
+ $request = join( "\r\n", $headers ) . "\r\n\r\n";
+ $sock = $this->_get_blogger_sock( $host );
+ if ( ! $sock ) return;
+ $response = $this->_txrx( $sock, $request );
+ $response = $this->parse_response( $response );
+ $parser = xml_parser_create();
+ xml_parse_into_struct($parser, $response['body'], $struct, $index);
+ xml_parser_free($parser);
+ $total_results = $struct[$index['OPENSEARCH:TOTALRESULTS'][0]]['value'];
+ return (int) $total_results;
+ }
+
+ function import_blog($blogID) {
+ global $importing_blog;
+ $importing_blog = $blogID;
+
+ if ( isset($_GET['authors']) )
+ return print($this->get_author_form());
+
+ header('Content-Type: text/plain');
+
+ if ( isset($_GET['status']) )
+ die($this->get_js_status());
+
+ if ( isset($_GET['saveauthors']) )
+ die($this->save_authors());
+
+ $blog = $this->blogs[$blogID];
+ $total_results = $this->get_total_results('posts', $blog['host']);
+ $this->blogs[$importing_blog]['total_posts'] = $total_results;
+
+ $start_index = $total_results - MAX_RESULTS + 1;
+
+ if ( isset( $this->blogs[$importing_blog]['posts_start_index'] ) )
+ $start_index = (int) $this->blogs[$importing_blog]['posts_start_index'];
+ elseif ( $total_results > MAX_RESULTS )
+ $start_index = $total_results - MAX_RESULTS + 1;