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&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'> </div><div id='pstat$i' class='stat'>$pdone/{$blog['total_posts']}</div>";
mp-wp_genesis         222 			$cstat = "<div class='ind' id='cind$i'> </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( ''', "'", $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&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 & 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&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('&','"',''','<','>'),
mp-wp_genesis        1057 				$string );
mp-wp_genesis        1058 	}
mp-wp_genesis        1059 }
mp-wp_genesis        1060 
mp-wp_genesis        1061 ?>