| 10 | | $title = __('Import Old Blogger'); |
|---|
| 11 | | $welcome = __('Howdy! This importer allows you to import posts and comments from your Old Blogger account into your WordPress blog.'); |
|---|
| 12 | | $noiframes = __('This feature requires iframe support.'); |
|---|
| 13 | | $warning = js_escape(__('This will delete everything saved by the Blogger importer except your posts and comments. Are you sure you want to do this?')); |
|---|
| 14 | | $reset = __('Reset this importer'); |
|---|
| 15 | | $incompat = __('Your web server is not properly configured to use this importer. Please enable the CURL extension for PHP and then reload this page.'); |
|---|
| 16 | | |
|---|
| 17 | | echo "<div class='wrap'><h2>$title</h2><p>$welcome</p>"; |
|---|
| 18 | | echo "<p>" . __('Please note that this importer <em>does not work with new Blogger (using your Google account)</em>.') . "</p>"; |
|---|
| 19 | | if ( function_exists('curl_init') ) |
|---|
| 20 | | echo "<iframe src='admin.php?import=blogger&noheader=true' height='350px' width = '99%'>$noiframes</iframe><p><a href='admin.php?import=blogger&restart=true&noheader=true' onclick='return confirm(\"$warning\")'>$reset</a></p>"; |
|---|
| | 11 | $next_url = get_option('siteurl') . '/wp-admin/index.php?import=blogger&noheader=true'; |
|---|
| | 12 | $auth_url = "https://www.google.com/accounts/AuthSubRequest"; |
|---|
| | 13 | $title = __('Import Blogger'); |
|---|
| | 14 | $welcome = __('Howdy! This importer allows you to import posts and comments from your Blogger account into your WordPress blog.'); |
|---|
| | 15 | $prereqs = __('To use this importer, you must have a Google account, an upgraded (New, was Beta) blog, and it must be on blogspot or a custom domain (not FTP).'); |
|---|
| | 16 | $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.'); |
|---|
| | 17 | $auth = __('Authorize'); |
|---|
| | 18 | |
|---|
| | 19 | echo " |
|---|
| | 20 | <div class='wrap'><h2>$title</h2><p>$welcome</p><p>$prereqs</p><p>$stepone</p> |
|---|
| | 21 | <form action='$auth_url' method='get'> |
|---|
| | 22 | <p class='submit' style='text-align:left;'> |
|---|
| | 23 | <input type='submit' value='$auth' /> |
|---|
| | 24 | <input type='hidden' name='scope' value='http://www.blogger.com/feeds/' /> |
|---|
| | 25 | <input type='hidden' name='session' value='1' /> |
|---|
| | 26 | <input type='hidden' name='secure' value='0' /> |
|---|
| | 27 | <input type='hidden' name='next' value='$next_url' /> |
|---|
| | 28 | </p> |
|---|
| | 29 | </form> |
|---|
| | 30 | </div>\n"; |
|---|
| | 31 | } |
|---|
| | 32 | |
|---|
| | 33 | function uh_oh($title, $message, $info) { |
|---|
| | 34 | echo "<div class='wrap'><h2>$title</h2><p>$message</p><pre>$info</pre></div>"; |
|---|
| | 35 | } |
|---|
| | 36 | |
|---|
| | 37 | function auth() { |
|---|
| | 38 | // We have a single-use token that must be upgraded to a session token. |
|---|
| | 39 | $token = preg_replace( '/[^-_0-9a-zA-Z]/', '', $_GET['token'] ); |
|---|
| | 40 | $headers = array( |
|---|
| | 41 | "GET /accounts/AuthSubSessionToken HTTP/1.0", |
|---|
| | 42 | "Authorization: AuthSub token=\"$token\"" |
|---|
| | 43 | ); |
|---|
| | 44 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 45 | $sock = $this->_get_auth_sock( ); |
|---|
| | 46 | if ( ! $sock ) return false; |
|---|
| | 47 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 48 | preg_match( '/token=([-_0-9a-z]+)/i', $response, $matches ); |
|---|
| | 49 | if ( empty( $matches[1] ) ) { |
|---|
| | 50 | $this->uh_oh( |
|---|
| | 51 | __( 'Authorization failed' ), |
|---|
| | 52 | __( 'Something went wrong. If the problem persists, send this info to support:' ), |
|---|
| | 53 | htmlspecialchars($response) |
|---|
| | 54 | ); |
|---|
| | 55 | return false; |
|---|
| | 56 | } |
|---|
| | 57 | $this->token = $matches[1]; |
|---|
| | 58 | |
|---|
| | 59 | wp_redirect( remove_query_arg( array( 'token', 'noheader' ) ) ); |
|---|
| | 60 | } |
|---|
| | 61 | |
|---|
| | 62 | function get_token_info() { |
|---|
| | 63 | $headers = array( |
|---|
| | 64 | "GET /accounts/AuthSubTokenInfo HTTP/1.0", |
|---|
| | 65 | "Authorization: AuthSub token=\"$this->token\"" |
|---|
| | 66 | ); |
|---|
| | 67 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 68 | $sock = $this->_get_auth_sock( ); |
|---|
| | 69 | if ( ! $sock ) return; |
|---|
| | 70 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 71 | return $this->parse_response($response); |
|---|
| | 72 | } |
|---|
| | 73 | |
|---|
| | 74 | function token_is_valid() { |
|---|
| | 75 | $info = $this->get_token_info(); |
|---|
| | 76 | |
|---|
| | 77 | if ( $info['code'] == 200 ) |
|---|
| | 78 | return true; |
|---|
| | 79 | |
|---|
| | 80 | return false; |
|---|
| | 81 | } |
|---|
| | 82 | |
|---|
| | 83 | function show_blogs($iter = 0) { |
|---|
| | 84 | if ( empty($this->blogs) ) { |
|---|
| | 85 | $headers = array( |
|---|
| | 86 | "GET /feeds/default/blogs HTTP/1.0", |
|---|
| | 87 | "Host: www.blogger.com", |
|---|
| | 88 | "Authorization: AuthSub token=\"$this->token\"" |
|---|
| | 89 | ); |
|---|
| | 90 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 91 | $sock = $this->_get_blogger_sock( ); |
|---|
| | 92 | if ( ! $sock ) return; |
|---|
| | 93 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 94 | |
|---|
| | 95 | // Quick and dirty XML mining. |
|---|
| | 96 | list( $headers, $xml ) = explode( "\r\n\r\n", $response ); |
|---|
| | 97 | $p = xml_parser_create(); |
|---|
| | 98 | xml_parse_into_struct($p, $xml, $vals, $index); |
|---|
| | 99 | xml_parser_free($p); |
|---|
| | 100 | |
|---|
| | 101 | $this->title = $vals[$index['TITLE'][0]]['value']; |
|---|
| | 102 | |
|---|
| | 103 | // Give it a few retries... this step often flakes out the first time. |
|---|
| | 104 | if ( empty( $index['ENTRY'] ) ) { |
|---|
| | 105 | if ( $iter < 3 ) { |
|---|
| | 106 | return $this->show_blogs($iter + 1); |
|---|
| | 107 | } else { |
|---|
| | 108 | $this->uh_oh( |
|---|
| | 109 | __('Trouble signing in'), |
|---|
| | 110 | __('We were not able to gain access to your account. Try starting over.'), |
|---|
| | 111 | '' |
|---|
| | 112 | ); |
|---|
| | 113 | return false; |
|---|
| | 114 | } |
|---|
| | 115 | } |
|---|
| | 116 | |
|---|
| | 117 | foreach ( $index['ENTRY'] as $i ) { |
|---|
| | 118 | $blog = array(); |
|---|
| | 119 | while ( ( $tag = $vals[$i] ) && ! ( $tag['tag'] == 'ENTRY' && $tag['type'] == 'close' ) ) { |
|---|
| | 120 | if ( $tag['tag'] == 'TITLE' ) { |
|---|
| | 121 | $blog['title'] = $tag['value']; |
|---|
| | 122 | } elseif ( $tag['tag'] == 'SUMMARY' ) { |
|---|
| | 123 | $blog['summary'] == $tag['value']; |
|---|
| | 124 | } elseif ( $tag['tag'] == 'LINK' ) { |
|---|
| | 125 | if ( $tag['attributes']['REL'] == 'alternate' && $tag['attributes']['TYPE'] == 'text/html' ) { |
|---|
| | 126 | $parts = parse_url( $tag['attributes']['HREF'] ); |
|---|
| | 127 | $blog['host'] = $parts['host']; |
|---|
| | 128 | } elseif ( $tag['attributes']['REL'] == 'edit' ) |
|---|
| | 129 | $blog['gateway'] = $tag['attributes']['HREF']; |
|---|
| | 130 | } |
|---|
| | 131 | ++$i; |
|---|
| | 132 | } |
|---|
| | 133 | if ( ! empty ( $blog ) ) { |
|---|
| | 134 | $blog['total_posts'] = $this->get_total_results('posts', $blog['host']); |
|---|
| | 135 | $blog['total_comments'] = $this->get_total_results('comments', $blog['host']); |
|---|
| | 136 | $blog['mode'] = 'init'; |
|---|
| | 137 | $this->blogs[] = $blog; |
|---|
| | 138 | } |
|---|
| | 139 | } |
|---|
| | 140 | |
|---|
| | 141 | if ( empty( $this->blogs ) ) { |
|---|
| | 142 | $this->uh_oh( |
|---|
| | 143 | __('No blogs found'), |
|---|
| | 144 | __('We were able to log in but there were no blogs. Try a different account next time.'), |
|---|
| | 145 | '' |
|---|
| | 146 | ); |
|---|
| | 147 | return false; |
|---|
| | 148 | } |
|---|
| | 149 | } |
|---|
| | 150 | //echo '<pre>'.print_r($this,1).'</pre>'; |
|---|
| | 151 | $start = js_escape( __('Import') ); |
|---|
| | 152 | $continue = js_escape( __('Continue') ); |
|---|
| | 153 | $stop = js_escape( __('Importing...') ); |
|---|
| | 154 | $authors = js_escape( __('Set Authors') ); |
|---|
| | 155 | $loadauth = js_escape( __('Preparing author mapping form...') ); |
|---|
| | 156 | $authhead = js_escape( __('Final Step: Author Mapping') ); |
|---|
| | 157 | $nothing = js_escape( __('Nothing was imported. Had you already imported this blog?') ); |
|---|
| | 158 | $title = __('Blogger Blogs'); |
|---|
| | 159 | $name = __('Blog Name'); |
|---|
| | 160 | $url = __('Blog URL'); |
|---|
| | 161 | $action = __('The Magic Button'); |
|---|
| | 162 | $posts = __('Posts'); |
|---|
| | 163 | $comments = __('Comments'); |
|---|
| | 164 | $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.'); |
|---|
| | 165 | |
|---|
| | 166 | $interval = STATUS_INTERVAL * 1000; |
|---|
| | 167 | |
|---|
| | 168 | foreach ( $this->blogs as $i => $blog ) { |
|---|
| | 169 | if ( $blog['mode'] == 'init' ) |
|---|
| | 170 | $value = $start; |
|---|
| | 171 | elseif ( $blog['mode'] == 'posts' || $blog['mode'] == 'comments' ) |
|---|
| | 172 | $value = $continue; |
|---|
| | 173 | else |
|---|
| | 174 | $value = $authors; |
|---|
| | 175 | $blogtitle = js_escape( $blog['title'] ); |
|---|
| | 176 | $pdone = isset($blog['posts_done']) ? (int) $blog['posts_done'] : 0; |
|---|
| | 177 | $cdone = isset($blog['comments_done']) ? (int) $blog['comments_done'] : 0; |
|---|
| | 178 | $init .= "blogs[$i]=new blog($i,'$blogtitle','{$blog['mode']}'," . $this->get_js_status($i) . ');'; |
|---|
| | 179 | $pstat = "<div class='ind' id='pind$i'> </div><div id='pstat$i' class='stat'>$pdone/{$blog['total_posts']}</div>"; |
|---|
| | 180 | $cstat = "<div class='ind' id='cind$i'> </div><div id='cstat$i' class='stat'>$cdone/{$blog['total_comments']}</div>"; |
|---|
| | 181 | $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' id='submit$i' value='$value' /><input type='hidden' name='blog' value='$i' /></td></tr>\n"; |
|---|
| | 182 | } |
|---|
| | 183 | |
|---|
| | 184 | 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>"; |
|---|
| | 185 | echo " |
|---|
| | 186 | <script type='text/javascript'> |
|---|
| | 187 | var strings = {cont:'$continue',stop:'$stop',stopping:'$stopping',authors:'$authors',nothing:'$nothing'}; |
|---|
| | 188 | var blogs = {}; |
|---|
| | 189 | function blog(i, title, mode, status){ |
|---|
| | 190 | this.blog = i; |
|---|
| | 191 | this.mode = mode; |
|---|
| | 192 | this.title = title; |
|---|
| | 193 | this.status = status; |
|---|
| | 194 | this.button = document.getElementById('submit'+this.blog); |
|---|
| | 195 | }; |
|---|
| | 196 | blog.prototype = { |
|---|
| | 197 | start: function() { |
|---|
| | 198 | this.cont = true; |
|---|
| | 199 | this.kick(); |
|---|
| | 200 | this.check(); |
|---|
| | 201 | }, |
|---|
| | 202 | kick: function() { |
|---|
| | 203 | ++this.kicks; |
|---|
| | 204 | var i = this.blog; |
|---|
| | 205 | jQuery.post('admin.php?import=blogger&noheader=true',{blog:this.blog},function(text,result){blogs[i].kickd(text,result)}); |
|---|
| | 206 | }, |
|---|
| | 207 | check: function() { |
|---|
| | 208 | ++this.checks; |
|---|
| | 209 | var i = this.blog; |
|---|
| | 210 | jQuery.post('admin.php?import=blogger&noheader=true&status=true',{blog:this.blog},function(text,result){blogs[i].checkd(text,result)}); |
|---|
| | 211 | }, |
|---|
| | 212 | kickd: function(text, result) { |
|---|
| | 213 | if ( result == 'error' ) { |
|---|
| | 214 | // TODO: exception handling |
|---|
| | 215 | if ( this.cont ) |
|---|
| | 216 | setTimeout('blogs['+this.blog+'].kick()', 1000); |
|---|
| | 217 | } else { |
|---|
| | 218 | if ( text == 'done' ) { |
|---|
| | 219 | this.stop(); |
|---|
| | 220 | this.done(); |
|---|
| | 221 | } else if ( text == 'nothing' ) { |
|---|
| | 222 | this.stop(); |
|---|
| | 223 | this.nothing(); |
|---|
| | 224 | } else if ( text == 'continue' ) { |
|---|
| | 225 | this.kick(); |
|---|
| | 226 | } else if ( this.mode = 'stopped' ) |
|---|
| | 227 | jQuery(this.button).attr('value', strings.cont); |
|---|
| | 228 | } |
|---|
| | 229 | --this.kicks; |
|---|
| | 230 | }, |
|---|
| | 231 | checkd: function(text, result) { |
|---|
| | 232 | if ( result == 'error' ) { |
|---|
| | 233 | // TODO: exception handling |
|---|
| | 234 | } else { |
|---|
| | 235 | eval('this.status='+text); |
|---|
| | 236 | jQuery('#pstat'+this.blog).empty().append(this.status.p1+'/'+this.status.p2); |
|---|
| | 237 | jQuery('#cstat'+this.blog).empty().append(this.status.c1+'/'+this.status.c2); |
|---|
| | 238 | this.update(); |
|---|
| | 239 | if ( this.cont || this.kicks > 0 ) |
|---|
| | 240 | setTimeout('blogs['+this.blog+'].check()', $interval); |
|---|
| | 241 | } |
|---|
| | 242 | --this.checks; |
|---|
| | 243 | }, |
|---|
| | 244 | update: function() { |
|---|
| | 245 | 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'); |
|---|
| | 246 | 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'); |
|---|
| | 247 | }, |
|---|
| | 248 | stop: function() { |
|---|
| | 249 | this.cont = false; |
|---|
| | 250 | }, |
|---|
| | 251 | done: function() { |
|---|
| | 252 | this.mode = 'authors'; |
|---|
| | 253 | jQuery(this.button).attr('value', strings.authors); |
|---|
| | 254 | }, |
|---|
| | 255 | nothing: function() { |
|---|
| | 256 | this.mode = 'nothing'; |
|---|
| | 257 | jQuery(this.button).remove(); |
|---|
| | 258 | alert(strings.nothing); |
|---|
| | 259 | }, |
|---|
| | 260 | getauthors: function() { |
|---|
| | 261 | if ( jQuery('div.wrap').length > 1 ) |
|---|
| | 262 | jQuery('div.wrap').gt(0).remove(); |
|---|
| | 263 | jQuery('div.wrap').empty().append('<h2>$authhead</h2><h3>' + this.title + '</h3>'); |
|---|
| | 264 | jQuery('div.wrap').append('<p id=\"auth\">$loadauth</p>'); |
|---|
| | 265 | jQuery('p#auth').load('index.php?import=blogger&noheader=true&authors=1',{blog:this.blog}); |
|---|
| | 266 | }, |
|---|
| | 267 | init: function() { |
|---|
| | 268 | this.update(); |
|---|
| | 269 | var i = this.blog; |
|---|
| | 270 | jQuery(this.button).bind('click', function(){return blogs[i].click();}); |
|---|
| | 271 | this.kicks = 0; |
|---|
| | 272 | this.checks = 0; |
|---|
| | 273 | }, |
|---|
| | 274 | click: function() { |
|---|
| | 275 | if ( this.mode == 'init' || this.mode == 'stopped' || this.mode == 'posts' || this.mode == 'comments' ) { |
|---|
| | 276 | this.mode = 'started'; |
|---|
| | 277 | this.start(); |
|---|
| | 278 | jQuery(this.button).attr('value', strings.stop); |
|---|
| | 279 | } else if ( this.mode == 'started' ) { |
|---|
| | 280 | return false; // let it run... |
|---|
| | 281 | this.mode = 'stopped'; |
|---|
| | 282 | this.stop(); |
|---|
| | 283 | if ( this.checks > 0 || this.kicks > 0 ) { |
|---|
| | 284 | this.mode = 'stopping'; |
|---|
| | 285 | jQuery(this.button).attr('value', strings.stopping); |
|---|
| | 286 | } else { |
|---|
| | 287 | jQuery(this.button).attr('value', strings.cont); |
|---|
| | 288 | } |
|---|
| | 289 | } else if ( this.mode == 'authors' ) { |
|---|
| | 290 | document.location = 'index.php?import=blogger&authors=1&blog='+this.blog; |
|---|
| | 291 | //this.mode = 'authors2'; |
|---|
| | 292 | //this.getauthors(); |
|---|
| | 293 | } |
|---|
| | 294 | return false; |
|---|
| | 295 | } |
|---|
| | 296 | }; |
|---|
| | 297 | $init |
|---|
| | 298 | jQuery.each(blogs, function(i, me){me.init();}); |
|---|
| | 299 | </script>\n"; |
|---|
| | 300 | } |
|---|
| | 301 | |
|---|
| | 302 | // Handy function for stopping the script after a number of seconds. |
|---|
| | 303 | function have_time() { |
|---|
| | 304 | global $importer_started; |
|---|
| | 305 | if ( time() - $importer_started > MAX_EXECUTION_TIME ) |
|---|
| | 306 | die('continue'); |
|---|
| | 307 | return true; |
|---|
| | 308 | } |
|---|
| | 309 | |
|---|
| | 310 | function get_total_results($type, $host) { |
|---|
| | 311 | $headers = array( |
|---|
| | 312 | "GET /feeds/$type/default?max-results=1&start-index=2 HTTP/1.0", |
|---|
| | 313 | "Host: $host", |
|---|
| | 314 | "Authorization: AuthSub token=\"$this->token\"" |
|---|
| | 315 | ); |
|---|
| | 316 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 317 | $sock = $this->_get_blogger_sock( $host ); |
|---|
| | 318 | if ( ! $sock ) return; |
|---|
| | 319 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 320 | $response = $this->parse_response( $response ); |
|---|
| | 321 | $parser = xml_parser_create(); |
|---|
| | 322 | xml_parse_into_struct($parser, $response['body'], $struct, $index); |
|---|
| | 323 | xml_parser_free($parser); |
|---|
| | 324 | $total_results = $struct[$index['OPENSEARCH:TOTALRESULTS'][0]]['value']; |
|---|
| | 325 | return (int) $total_results; |
|---|
| | 326 | } |
|---|
| | 327 | |
|---|
| | 328 | function import_blog($blogID) { |
|---|
| | 329 | global $importing_blog; |
|---|
| | 330 | $importing_blog = $blogID; |
|---|
| | 331 | |
|---|
| | 332 | if ( isset($_GET['authors']) ) |
|---|
| | 333 | return print($this->get_author_form()); |
|---|
| | 334 | |
|---|
| | 335 | header('Content-Type: text/plain'); |
|---|
| | 336 | |
|---|
| | 337 | if ( isset($_GET['status']) ) |
|---|
| | 338 | die($this->get_js_status()); |
|---|
| | 339 | |
|---|
| | 340 | if ( isset($_GET['saveauthors']) ) |
|---|
| | 341 | die($this->save_authors()); |
|---|
| | 342 | |
|---|
| | 343 | $blog = $this->blogs[$blogID]; |
|---|
| | 344 | $total_results = $this->get_total_results('posts', $blog['host']); |
|---|
| | 345 | $this->blogs[$importing_blog]['total_posts'] = $total_results; |
|---|
| | 346 | |
|---|
| | 347 | $start_index = $total_results - MAX_RESULTS + 1; |
|---|
| | 348 | |
|---|
| | 349 | if ( isset( $this->blogs[$importing_blog]['posts_start_index'] ) ) |
|---|
| | 350 | $start_index = (int) $this->blogs[$importing_blog]['posts_start_index']; |
|---|
| | 351 | elseif ( $total_results > MAX_RESULTS ) |
|---|
| | 352 | $start_index = $total_results - MAX_RESULTS + 1; |
|---|
| 22 | | echo "<p>$incompat</p>"; |
|---|
| 23 | | echo "</div>\n"; |
|---|
| 24 | | } |
|---|
| 25 | | |
|---|
| 26 | | // Deletes saved data and redirect. |
|---|
| | 354 | $start_index = 1; |
|---|
| | 355 | |
|---|
| | 356 | // This will be positive until we have finished importing posts |
|---|
| | 357 | if ( $start_index > 0 ) { |
|---|
| | 358 | // Grab all the posts |
|---|
| | 359 | $this->blogs[$importing_blog]['mode'] = 'posts'; |
|---|
| | 360 | $query = "start-index=$start_index&max-results=" . MAX_RESULTS; |
|---|
| | 361 | do { |
|---|
| | 362 | $index = $struct = $entries = array(); |
|---|
| | 363 | $headers = array( |
|---|
| | 364 | "GET /feeds/posts/default?$query HTTP/1.0", |
|---|
| | 365 | "Host: {$blog['host']}", |
|---|
| | 366 | "Authorization: AuthSub token=\"$this->token\"" |
|---|
| | 367 | ); |
|---|
| | 368 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 369 | $sock = $this->_get_blogger_sock( $blog['host'] ); |
|---|
| | 370 | if ( ! $sock ) return; // TODO: Error handling |
|---|
| | 371 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 372 | |
|---|
| | 373 | $response = $this->parse_response( $response ); |
|---|
| | 374 | |
|---|
| | 375 | // Extract the entries and send for insertion |
|---|
| | 376 | preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches ); |
|---|
| | 377 | if ( count( $matches[0] ) ) { |
|---|
| | 378 | $entries = array_reverse($matches[0]); |
|---|
| | 379 | foreach ( $entries as $entry ) { |
|---|
| | 380 | $entry = "<feed>$entry</feed>"; |
|---|
| | 381 | $AtomParser = new AtomParser(); |
|---|
| | 382 | $AtomParser->parse( $entry ); |
|---|
| | 383 | $this->import_post($AtomParser->entry); |
|---|
| | 384 | unset($AtomParser); |
|---|
| | 385 | } |
|---|
| | 386 | } else break; |
|---|
| | 387 | |
|---|
| | 388 | // Get the 'previous' query string which we'll use on the next iteration |
|---|
| | 389 | $query = ''; |
|---|
| | 390 | $links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches); |
|---|
| | 391 | if ( count( $matches[1] ) ) |
|---|
| | 392 | foreach ( $matches[1] as $match ) |
|---|
| | 393 | if ( preg_match('/rel=.previous./', $match) ) |
|---|
| | 394 | $query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) ); |
|---|
| | 395 | |
|---|
| | 396 | if ( $query ) { |
|---|
| | 397 | parse_str($query, $q); |
|---|
| | 398 | $this->blogs[$importing_blog]['posts_start_index'] = (int) $q['start-index']; |
|---|
| | 399 | } else |
|---|
| | 400 | $this->blogs[$importing_blog]['posts_start_index'] = 0; |
|---|
| | 401 | $this->save_vars(); |
|---|
| | 402 | } while ( !empty( $query ) && $this->have_time() ); |
|---|
| | 403 | } |
|---|
| | 404 | |
|---|
| | 405 | $total_results = $this->get_total_results( 'comments', $blog['host'] ); |
|---|
| | 406 | $this->blogs[$importing_blog]['total_comments'] = $total_results; |
|---|
| | 407 | |
|---|
| | 408 | if ( isset( $this->blogs[$importing_blog]['comments_start_index'] ) ) |
|---|
| | 409 | $start_index = (int) $this->blogs[$importing_blog]['comments_start_index']; |
|---|
| | 410 | elseif ( $total_results > MAX_RESULTS ) |
|---|
| | 411 | $start_index = $total_results - MAX_RESULTS + 1; |
|---|
| | 412 | else |
|---|
| | 413 | $start_index = 1; |
|---|
| | 414 | |
|---|
| | 415 | if ( $start_index > 0 ) { |
|---|
| | 416 | // Grab all the comments |
|---|
| | 417 | $this->blogs[$importing_blog]['mode'] = 'comments'; |
|---|
| | 418 | $query = "start-index=$start_index&max-results=" . MAX_RESULTS; |
|---|
| | 419 | do { |
|---|
| | 420 | $index = $struct = $entries = array(); |
|---|
| | 421 | $headers = array( |
|---|
| | 422 | "GET /feeds/comments/default?$query HTTP/1.0", |
|---|
| | 423 | "Host: {$blog['host']}", |
|---|
| | 424 | "Authorization: AuthSub token=\"$this->token\"" |
|---|
| | 425 | ); |
|---|
| | 426 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 427 | $sock = $this->_get_blogger_sock( $blog['host'] ); |
|---|
| | 428 | if ( ! $sock ) return; // TODO: Error handling |
|---|
| | 429 | $response = $this->_txrx( $sock, $request ); |
|---|
| | 430 | |
|---|
| | 431 | $response = $this->parse_response( $response ); |
|---|
| | 432 | |
|---|
| | 433 | // Extract the comments and send for insertion |
|---|
| | 434 | preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches ); |
|---|
| | 435 | if ( count( $matches[0] ) ) { |
|---|
| | 436 | $entries = array_reverse( $matches[0] ); |
|---|
| | 437 | foreach ( $entries as $entry ) { |
|---|
| | 438 | $entry = "<feed>$entry</feed>"; |
|---|
| | 439 | $AtomParser = new AtomParser(); |
|---|
| | 440 | $AtomParser->parse( $entry ); |
|---|
| | 441 | $this->import_comment($AtomParser->entry); |
|---|
| | 442 | unset($AtomParser); |
|---|
| | 443 | } |
|---|
| | 444 | } |
|---|
| | 445 | |
|---|
| | 446 | // Get the 'previous' query string which we'll use on the next iteration |
|---|
| | 447 | $query = ''; |
|---|
| | 448 | $links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches); |
|---|
| | 449 | if ( count( $matches[1] ) ) |
|---|
| | 450 | foreach ( $matches[1] as $match ) |
|---|
| | 451 | if ( preg_match('/rel=.previous./', $match) ) |
|---|
| | 452 | $query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) ); |
|---|
| | 453 | |
|---|
| | 454 | parse_str($query, $q); |
|---|
| | 455 | |
|---|
| | 456 | $this->blogs[$importing_blog]['comments_start_index'] = (int) $q['start-index']; |
|---|
| | 457 | $this->save_vars(); |
|---|
| | 458 | } while ( !empty( $query ) && $this->have_time() ); |
|---|
| | 459 | } |
|---|
| | 460 | $this->blogs[$importing_blog]['mode'] = 'authors'; |
|---|
| | 461 | $this->save_vars(); |
|---|
| | 462 | if ( !$this->blogs[$importing_blog]['posts_done'] && !$this->blogs[$importing_blog]['comments_done'] ) |
|---|
| | 463 | die('nothing'); |
|---|
| | 464 | do_action('import_done', 'blogger'); |
|---|
| | 465 | die('done'); |
|---|
| | 466 | } |
|---|
| | 467 | |
|---|
| | 468 | function convert_date( $date ) { |
|---|
| | 469 | 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); |
|---|
| | 470 | $offset = iso8601_timezone_to_offset( $date_bits[7] ); |
|---|
| | 471 | $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]); |
|---|
| | 472 | $timestamp -= $offset; // Convert from Blogger local time to GMT |
|---|
| | 473 | $timestamp += get_option('gmt_offset') * 3600; // Convert from GMT to WP local time |
|---|
| | 474 | return gmdate('Y-m-d H:i:s', $timestamp); |
|---|
| | 475 | } |
|---|
| | 476 | |
|---|
| | 477 | function no_apos( $string ) { |
|---|
| | 478 | return str_replace( ''', "'", $string); |
|---|
| | 479 | } |
|---|
| | 480 | |
|---|
| | 481 | function min_whitespace( $string ) { |
|---|
| | 482 | return preg_replace( '|\s+|', ' ', $string ); |
|---|
| | 483 | } |
|---|
| | 484 | |
|---|
| | 485 | function import_post( $entry ) { |
|---|
| | 486 | global $wpdb, $importing_blog; |
|---|
| | 487 | |
|---|
| | 488 | // The old permalink is all Blogger gives us to link comments to their posts. |
|---|
| | 489 | if ( isset( $entry->draft ) ) |
|---|
| | 490 | $rel = 'self'; |
|---|
| | 491 | else |
|---|
| | 492 | $rel = 'alternate'; |
|---|
| | 493 | foreach ( $entry->links as $link ) { |
|---|
| | 494 | if ( $link['rel'] == $rel ) { |
|---|
| | 495 | $parts = parse_url( $link['href'] ); |
|---|
| | 496 | $entry->old_permalink = $parts['path']; |
|---|
| | 497 | break; |
|---|
| | 498 | } |
|---|
| | 499 | } |
|---|
| | 500 | |
|---|
| | 501 | $post_date = $this->convert_date( $entry->published ); |
|---|
| | 502 | $post_content = trim( addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) ) ); |
|---|
| | 503 | $post_title = trim( addslashes( $this->no_apos( $this->min_whitespace( $entry->title ) ) ) ); |
|---|
| | 504 | $post_status = isset( $entry->draft ) ? 'draft' : 'publish'; |
|---|
| | 505 | |
|---|
| | 506 | // Clean up content |
|---|
| | 507 | $post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content); |
|---|
| | 508 | $post_content = str_replace('<br>', '<br />', $post_content); |
|---|
| | 509 | $post_content = str_replace('<hr>', '<hr />', $post_content); |
|---|
| | 510 | |
|---|
| | 511 | // Checks for duplicates |
|---|
| | 512 | if ( |
|---|
| | 513 | isset( $this->blogs[$importing_blog]['posts'][$entry->old_permalink] ) || |
|---|
| | 514 | post_exists( $post_title, $post_content, $post_date ) |
|---|
| | 515 | ) { |
|---|
| | 516 | ++$this->blogs[$importing_blog]['posts_skipped']; |
|---|
| | 517 | } else { |
|---|
| | 518 | $post = compact('post_date', 'post_content', 'post_title', 'post_status'); |
|---|
| | 519 | |
|---|
| | 520 | $post_id = wp_insert_post($post); |
|---|
| | 521 | |
|---|
| | 522 | wp_create_categories( array_map( 'addslashes', $entry->categories ), $post_id ); |
|---|
| | 523 | |
|---|
| | 524 | $author = $this->no_apos( strip_tags( $entry->author ) ); |
|---|
| | 525 | |
|---|
| | 526 | add_post_meta( $post_id, 'blogger_blog', $this->blogs[$importing_blog]['host'], true ); |
|---|
| | 527 | add_post_meta( $post_id, 'blogger_author', $author, true ); |
|---|
| | 528 | add_post_meta( $post_id, 'blogger_permalink', $entry->old_permalink, true ); |
|---|
| | 529 | |
|---|
| | 530 | $this->blogs[$importing_blog]['posts'][$entry->old_permalink] = $post_id; |
|---|
| | 531 | ++$this->blogs[$importing_blog]['posts_done']; |
|---|
| | 532 | } |
|---|
| | 533 | $this->save_vars(); |
|---|
| | 534 | } |
|---|
| | 535 | |
|---|
| | 536 | function import_comment( $entry ) { |
|---|
| | 537 | global $importing_blog; |
|---|
| | 538 | |
|---|
| | 539 | // Drop the #fragment and we have the comment's old post permalink. |
|---|
| | 540 | foreach ( $entry->links as $link ) { |
|---|
| | 541 | if ( $link['rel'] == 'alternate' ) { |
|---|
| | 542 | $parts = parse_url( $link['href'] ); |
|---|
| | 543 | $entry->old_permalink = $parts['fragment']; |
|---|
| | 544 | $entry->old_post_permalink = $parts['path']; |
|---|
| | 545 | break; |
|---|
| | 546 | } |
|---|
| | 547 | } |
|---|
| | 548 | |
|---|
| | 549 | $comment_post_ID = $this->blogs[$importing_blog]['posts'][$entry->old_post_permalink]; |
|---|
| | 550 | $comment_author = addslashes( $this->no_apos( strip_tags( $entry->author ) ) ); |
|---|
| | 551 | $comment_date = $this->convert_date( $entry->updated ); |
|---|
| | 552 | $comment_content = addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) ); |
|---|
| | 553 | |
|---|
| | 554 | // Clean up content |
|---|
| | 555 | $comment_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $comment_content); |
|---|
| | 556 | $comment_content = str_replace('<br>', '<br />', $comment_content); |
|---|
| | 557 | $comment_content = str_replace('<hr>', '<hr />', $comment_content); |
|---|
| | 558 | |
|---|
| | 559 | // Checks for duplicates |
|---|
| | 560 | if ( |
|---|
| | 561 | isset( $this->blogs[$importing_blog]['comments'][$entry->old_permalink] ) || |
|---|
| | 562 | comment_exists( $comment_author, $comment_date ) |
|---|
| | 563 | ) { |
|---|
| | 564 | ++$this->blogs[$importing_blog]['comments_skipped']; |
|---|
| | 565 | } else { |
|---|
| | 566 | $comment = compact('comment_post_ID', 'comment_author', 'comment_date', 'comment_content'); |
|---|
| | 567 | |
|---|
| | 568 | $comment_id = wp_insert_comment($comment); |
|---|
| | 569 | |
|---|
| | 570 | $this->blogs[$importing_blog]['comments'][$entry->old_permalink] = $comment_id; |
|---|
| | 571 | |
|---|
| | 572 | ++$this->blogs[$importing_blog]['comments_done']; |
|---|
| | 573 | } |
|---|
| | 574 | $this->save_vars(); |
|---|
| | 575 | } |
|---|
| | 576 | |
|---|
| | 577 | function get_js_status($blog = false) { |
|---|
| | 578 | global $importing_blog; |
|---|
| | 579 | if ( $blog === false ) |
|---|
| | 580 | $blog = $this->blogs[$importing_blog]; |
|---|
| | 581 | else |
|---|
| | 582 | $blog = $this->blogs[$blog]; |
|---|
| | 583 | $p1 = isset( $blog['posts_done'] ) ? (int) $blog['posts_done'] : 0; |
|---|
| | 584 | $p2 = isset( $blog['total_posts'] ) ? (int) $blog['total_posts'] : 0; |
|---|
| | 585 | $c1 = isset( $blog['comments_done'] ) ? (int) $blog['comments_done'] : 0; |
|---|
| | 586 | $c2 = isset( $blog['total_comments'] ) ? (int) $blog['total_comments'] : 0; |
|---|
| | 587 | return "{p1:$p1,p2:$p2,c1:$c1,c2:$c2}"; |
|---|
| | 588 | } |
|---|
| | 589 | |
|---|
| | 590 | function get_author_form($blog = false) { |
|---|
| | 591 | global $importing_blog, $wpdb, $current_user; |
|---|
| | 592 | if ( $blog === false ) |
|---|
| | 593 | $blog = & $this->blogs[$importing_blog]; |
|---|
| | 594 | else |
|---|
| | 595 | $blog = & $this->blogs[$blog]; |
|---|
| | 596 | |
|---|
| | 597 | if ( !isset( $blog['authors'] ) ) { |
|---|
| | 598 | $post_ids = array_values($blog['posts']); |
|---|
| | 599 | $authors = (array) $wpdb->get_col("SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN (" . join( ',', $post_ids ) . ")"); |
|---|
| | 600 | $blog['authors'] = array_map(null, $authors, array_fill(0, count($authors), $current_user->ID)); |
|---|
| | 601 | $this->save_vars(); |
|---|
| | 602 | } |
|---|
| | 603 | |
|---|
| | 604 | $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.'); |
|---|
| | 605 | $heading = __('Author mapping'); |
|---|
| | 606 | $blogtitle = "{$blog['title']} ({$blog['host']})"; |
|---|
| | 607 | $mapthis = __('Blogger username'); |
|---|
| | 608 | $tothis = __('WordPress login'); |
|---|
| | 609 | $submit = js_escape( __('Save Changes »') ); |
|---|
| | 610 | |
|---|
| | 611 | foreach ( $blog['authors'] as $i => $author ) |
|---|
| | 612 | $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>"; |
|---|
| | 613 | |
|---|
| | 614 | 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='authorsubmit' value='$submit' /></td></tr></table></form></div>"; |
|---|
| | 615 | } |
|---|
| | 616 | |
|---|
| | 617 | function get_user_options($current) { |
|---|
| | 618 | global $wpdb, $importer_users; |
|---|
| | 619 | if ( ! isset( $importer_users ) ) |
|---|
| | 620 | $importer_users = (array) get_users_of_blog(); |
|---|
| | 621 | |
|---|
| | 622 | foreach ( $importer_users as $user ) { |
|---|
| | 623 | $sel = ( $user->user_id == $current ) ? " selected='selected'" : ''; |
|---|
| | 624 | $options .= "<option value='$user->user_id'$sel>$user->display_name</option>"; |
|---|
| | 625 | } |
|---|
| | 626 | |
|---|
| | 627 | return $options; |
|---|
| | 628 | } |
|---|
| | 629 | |
|---|
| | 630 | function save_authors() { |
|---|
| | 631 | global $importing_blog, $wpdb; |
|---|
| | 632 | $authors = (array) $_POST['authors']; |
|---|
| | 633 | |
|---|
| | 634 | $host = $this->blogs[$importing_blog]['host']; |
|---|
| | 635 | |
|---|
| | 636 | // Get an array of posts => authors |
|---|
| | 637 | $post_ids = (array) $wpdb->get_col("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'blogger_blog' AND meta_value = '$host'"); |
|---|
| | 638 | $post_ids = join( ',', $post_ids ); |
|---|
| | 639 | $results = (array) $wpdb->get_results("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN ($post_ids)"); |
|---|
| | 640 | foreach ( $results as $row ) |
|---|
| | 641 | $authors_posts[$row->post_id] = $row->meta_value; |
|---|
| | 642 | |
|---|
| | 643 | foreach ( $authors as $author => $user_id ) { |
|---|
| | 644 | $user_id = (int) $user_id; |
|---|
| | 645 | |
|---|
| | 646 | // Skip authors that haven't been changed |
|---|
| | 647 | if ( $user_id == $this->blogs[$importing_blog]['authors'][$author][1] ) |
|---|
| | 648 | continue; |
|---|
| | 649 | |
|---|
| | 650 | // Get a list of the selected author's posts |
|---|
| | 651 | $post_ids = (array) array_keys( $authors_posts, $this->blogs[$importing_blog]['authors'][$author][0] ); |
|---|
| | 652 | $post_ids = join( ',', $post_ids); |
|---|
| | 653 | |
|---|
| | 654 | $wpdb->query("UPDATE $wpdb->posts SET post_author = $user_id WHERE id IN ($post_ids)"); |
|---|
| | 655 | $this->blogs[$importing_blog]['authors'][$author][1] = $user_id; |
|---|
| | 656 | } |
|---|
| | 657 | $this->save_vars(); |
|---|
| | 658 | |
|---|
| | 659 | wp_redirect('edit.php'); |
|---|
| | 660 | } |
|---|
| | 661 | |
|---|
| | 662 | function _get_auth_sock() { |
|---|
| | 663 | // Connect to https://www.google.com |
|---|
| | 664 | if ( !$sock = @ fsockopen('ssl://www.google.com', 443, $errno, $errstr) ) { |
|---|
| | 665 | $this->uh_oh( |
|---|
| | 666 | __('Could not connect to https://www.google.com'), |
|---|
| | 667 | __('There was a problem opening a secure connection to Google. This is what went wrong:'), |
|---|
| | 668 | "$errstr ($errno)" |
|---|
| | 669 | ); |
|---|
| | 670 | return false; |
|---|
| | 671 | } |
|---|
| | 672 | return $sock; |
|---|
| | 673 | } |
|---|
| | 674 | |
|---|
| | 675 | function _get_blogger_sock($host = 'www.blogger.com') { |
|---|
| | 676 | if ( !$sock = @ fsockopen($host, 80, $errno, $errstr) ) { |
|---|
| | 677 | $this->uh_oh( |
|---|
| | 678 | sprintf( __('Could not connect to %s'), $host ), |
|---|
| | 679 | __('There was a problem opening a connection to Blogger. This is what went wrong:'), |
|---|
| | 680 | "$errstr ($errno)" |
|---|
| | 681 | ); |
|---|
| | 682 | return false; |
|---|
| | 683 | } |
|---|
| | 684 | return $sock; |
|---|
| | 685 | } |
|---|
| | 686 | |
|---|
| | 687 | function _txrx( $sock, $request ) { |
|---|
| | 688 | fwrite( $sock, $request ); |
|---|
| | 689 | while ( ! feof( $sock ) ) |
|---|
| | 690 | $response .= @ fread ( $sock, 8192 ); |
|---|
| | 691 | fclose( $sock ); |
|---|
| | 692 | return $response; |
|---|
| | 693 | } |
|---|
| | 694 | |
|---|
| | 695 | function revoke($token) { |
|---|
| | 696 | $headers = array( |
|---|
| | 697 | "GET /accounts/AuthSubRevokeToken HTTP/1.0", |
|---|
| | 698 | "Authorization: AuthSub token=\"$token\"" |
|---|
| | 699 | ); |
|---|
| | 700 | $request = join( "\r\n", $headers ) . "\r\n\r\n"; |
|---|
| | 701 | $sock = $this->_get_auth_sock( ); |
|---|
| | 702 | if ( ! $sock ) return false; |
|---|
| | 703 | $this->_txrx( $sock, $request ); |
|---|
| | 704 | } |
|---|
| | 705 | |
|---|
| 63 | | } |
|---|
| 64 | | |
|---|
| 65 | | // Prints a form for the user to enter Blogger creds. |
|---|
| 66 | | function login_form($text='') { |
|---|
| 67 | | echo '<h1>' . __('Log in to Blogger') . "</h1>\n$text\n"; |
|---|
| 68 | | echo '<form method="post" action="admin.php?import=blogger&noheader=true&step=0"><table><tr><td>' . __('Username') . ':</td><td><input type="text" name="user" /></td></tr><tr><td>' . __('Password') . ':</td><td><input type="password" name="pass" /></td><td><input type="submit" value="' . __('Start') . '" /></td></tr></table></form>'; |
|---|
| 69 | | die; |
|---|
| 70 | | } |
|---|
| 71 | | |
|---|
| 72 | | // Sends creds to Blogger, returns the session cookies an array of headers. |
|---|
| 73 | | function login_blogger($user, $pass) { |
|---|
| 74 | | $_url = 'http://www.blogger.com/login.do'; |
|---|
| 75 | | $params = "username=$user&password=$pass"; |
|---|
| 76 | | $ch = curl_init(); |
|---|
| 77 | | curl_setopt($ch, CURLOPT_POST,1); |
|---|
| 78 | | curl_setopt($ch, CURLOPT_POSTFIELDS,$params); |
|---|
| 79 | | curl_setopt($ch, CURLOPT_URL,$_url); |
|---|
| 80 | | curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter'); |
|---|
| 81 | | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); |
|---|
| 82 | | curl_setopt($ch, CURLOPT_HEADER,1); |
|---|
| 83 | | curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); |
|---|
| 84 | | $response = curl_exec ($ch); |
|---|
| 85 | | |
|---|
| 86 | | $response = $this->parse_response($response); |
|---|
| 87 | | |
|---|
| 88 | | sleep(1); |
|---|
| 89 | | |
|---|
| 90 | | return $response['cookies']; |
|---|
| 91 | | } |
|---|
| 92 | | |
|---|
| 93 | | // Requests page from Blogger, returns the response array. |
|---|
| 94 | | function get_blogger($url, $header = '', $user=false, $pass=false) { |
|---|
| 95 | | $ch = curl_init(); |
|---|
| 96 | | if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}"); |
|---|
| 97 | | curl_setopt($ch, CURLOPT_URL,$url); |
|---|
| 98 | | curl_setopt($ch, CURLOPT_TIMEOUT, 10); |
|---|
| 99 | | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
|---|
| 100 | | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
|---|
| 101 | | curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter'); |
|---|
| 102 | | curl_setopt($ch, CURLOPT_HEADER,1); |
|---|
| 103 | | if (is_array($header)) curl_setopt($ch, CURLOPT_HTTPHEADER, $header); |
|---|
| 104 | | $response = curl_exec ($ch); |
|---|
| 105 | | |
|---|
| 106 | | $response = $this->parse_response($response); |
|---|
| 107 | | $response['url'] = $url; |
|---|
| 108 | | |
|---|
| 109 | | if (curl_errno($ch)) { |
|---|
| 110 | | print curl_error($ch); |
|---|
| 111 | | } else { |
|---|
| 112 | | curl_close($ch); |
|---|
| 113 | | } |
|---|
| 114 | | |
|---|
| 115 | | return $response; |
|---|
| 116 | | } |
|---|
| 117 | | |
|---|
| 118 | | // Posts data to Blogger, returns response array. |
|---|
| 119 | | function post_blogger($url, $header = false, $paramary = false, $parse=true) { |
|---|
| 120 | | $params = ''; |
|---|
| 121 | | if ( is_array($paramary) ) { |
|---|
| 122 | | foreach($paramary as $key=>$value) |
|---|
| 123 | | if($key && $value != '') |
|---|
| 124 | | $params.=$key."=".urlencode(stripslashes($value))."&"; |
|---|
| 125 | | } |
|---|
| 126 | | if ($user && $pass) $params .= "username=$user&password=$pass"; |
|---|
| 127 | | $params = trim($params,'&'); |
|---|
| 128 | | $ch = curl_init(); |
|---|
| 129 | | curl_setopt($ch, CURLOPT_POST,1); |
|---|
| 130 | | curl_setopt($ch, CURLOPT_POSTFIELDS,$params); |
|---|
| 131 | | if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}"); |
|---|
| 132 | | curl_setopt($ch, CURLOPT_URL,$url); |
|---|
| 133 | | curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter'); |
|---|
| 134 | | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
|---|
| 135 | | curl_setopt($ch, CURLOPT_HEADER,$parse); |
|---|
| 136 | | curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); |
|---|
| 137 | | if ($header) curl_setopt($ch, CURLOPT_HTTPHEADER, $header); |
|---|
| 138 | | $response = curl_exec ($ch); |
|---|
| 139 | | |
|---|
| 140 | | if ($parse) { |
|---|
| 141 | | $response = $this->parse_response($response); |
|---|
| 142 | | $response['url'] = $url; |
|---|
| 143 | | return $response; |
|---|
| 144 | | } |
|---|
| 145 | | |
|---|
| 146 | | return $response; |
|---|
| 147 | | } |
|---|
| 148 | | |
|---|
| 149 | | // Prints the list of blogs for import. |
|---|
| 150 | | function show_blogs() { |
|---|
| 151 | | global $import; |
|---|
| 152 | | echo '<h1>' . __('Selecting a Blog') . "</h1>\n<ul>"; |
|---|
| 153 | | foreach ( $this->import['blogs'] as $blog ) { |
|---|
| 154 | | if (9 == $blog['nextstep']) $status = "100%"; |
|---|
| 155 | | elseif (8 == $blog['nextstep']) $status = "90%"; |
|---|
| 156 | | elseif (7 == $blog['nextstep']) $status = "82.5%"; |
|---|
| 157 | | elseif (6 == $blog['nextstep']) $status = "75%"; |
|---|
| 158 | | elseif (5 == $blog['nextstep']) $status = "57%"; |
|---|
| 159 | | elseif (4 == $blog['nextstep']) $status = "28%"; |
|---|
| 160 | | elseif (3 == $blog['nextstep']) $status = "14%"; |
|---|
| 161 | | else $status = "0%"; |
|---|
| 162 | | echo "\t<li><a href='admin.php?import=blogger&noheader=true&blog={$blog['id']}'>{$blog['title']}</a> $status</li>\n"; |
|---|
| 163 | | } |
|---|
| 164 | | die("</ul>\n"); |
|---|
| 165 | | } |
|---|
| 166 | | |
|---|
| 167 | | // Publishes. |
|---|
| 168 | | function publish_blogger($i, $text) { |
|---|
| 169 | | $head = $this->refresher(2000) . "<h1>$text</h1>\n"; |
|---|
| 170 | | if ( ! strstr($this->import['blogs'][$_GET['blog']]['publish'][$i], 'http') ) { |
|---|
| 171 | | // First call. Start the publish process with a fresh set of cookies. |
|---|
| 172 | | $this->import['cookies'] = $this->login_blogger($this->import['user'], $this->import['pass']); |
|---|
| 173 | | update_option('import-blogger', $this->import); |
|---|
| 174 | | $paramary = array('blogID' => $_GET['blog'], 'all' => '1', 'republishAll' => 'Republish Entire Blog', 'publish' => '1', 'redirectUrl' => "/publish.do?blogID={$_GET['blog']}&inprogress=true"); |
|---|
| 175 | | |
|---|
| 176 | | $response = $this->post_blogger("http://www.blogger.com/publish.do?blogID={$_GET['blog']}", $this->import['cookies'], $paramary); |
|---|
| 177 | | if ( $response['code'] == '302' ) { |
|---|
| 178 | | $url = str_replace('publish.g', 'publish-body.g', $response['header']['Location']); |
|---|
| 179 | | $this->import['blogs'][$_GET['blog']]['publish'][$i] = $url; |
|---|
| 180 | | update_option('import-blogger', $this->import); |
|---|
| 181 | | $response = $this->get_blogger($url, $this->import['cookies']); |
|---|
| 182 | | preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches); |
|---|
| 183 | | $progress = $matches[0]; |
|---|
| 184 | | die($head . $progress); |
|---|
| 185 | | } else { |
|---|
| 186 | | $this->import['blogs'][$_GET['blog']]['publish'][$i] = false; |
|---|
| 187 | | update_option('import-blogger', $this->import); |
|---|
| 188 | | die($head); |
|---|
| 189 | | } |
|---|
| 190 | | } else { |
|---|
| 191 | | // Subsequent call. Keep checking status until Blogger reports publish complete. |
|---|
| 192 | | $url = $this->import['blogs'][$_GET['blog']]['publish'][$i]; |
|---|
| 193 | | $response = $this->get_blogger($url, $this->import['cookies']); |
|---|
| 194 | | if ( preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches) ) { |
|---|
| 195 | | $progress = $matches[0]; |
|---|
| 196 | | if ( strstr($progress, '100%') ) { |
|---|
| 197 | | $this->set_next_step($i); |
|---|
| 198 | | $progress .= '<p>'.__('Moving on...').'</p>'; |
|---|
| 199 | | } |
|---|
| 200 | | die($head . $progress); |
|---|
| 201 | | } else { |
|---|
| 202 | | $this->import['blogs'][$_GET['blog']]['publish'][$i] = false; |
|---|
| 203 | | update_option('import-blogger', $this->import); |
|---|
| 204 | | die("$head<p>" . __('Trying again...') . '</p>'); |
|---|
| 205 | | } |
|---|
| 206 | | } |
|---|
| 207 | | } |
|---|
| 208 | | |
|---|
| 209 | | // Sets next step, saves options |
|---|
| 210 | | function set_next_step($step) { |
|---|
| 211 | | $this->import['blogs'][$_GET['blog']]['nextstep'] = $step; |
|---|
| 212 | | update_option('import-blogger', $this->import); |
|---|
| 213 | | } |
|---|
| 214 | | |
|---|
| 215 | | // Redirects to next step |
|---|
| 216< |
|---|