d35f84219c83731d405ada2e15b5af95d517b17a
[autoinstalls/wordpress.git] / wp-admin / import / blogger.php
1 <?php
2
3 class Blogger_Import {
4
5         var $lump_authors = false;
6         var $import = array();
7
8         // Shows the welcome screen and the magic iframe.
9         function greet() {
10                 $title = __('Import Blogger');
11                 $welcome = __('Howdy! This importer allows you to import posts and comments from your Blogger account into your WordPress blog.');
12                 $noiframes = __('This feature requires iframe support.');
13                 $warning = __('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                 if ( function_exists('curl_init') )
19                         echo "<iframe src='admin.php?import=blogger&amp;noheader=true' height='350px' width = '99%'>$noiframes</iframe><p><a href='admin.php?import=blogger&amp;restart=true&amp;noheader=true' onclick='return confirm(\"$warning\")'>$reset</a></p>";
20                 else
21                         echo "<p>$incompat</p>";
22                 echo "</div>\n";
23         }
24
25         // Deletes saved data and redirect.
26         function restart() {
27                 delete_option('import-blogger');
28                 wp_redirect("admin.php?import=blogger");
29                 die();
30         }
31
32         // Generates a string that will make the page reload in a specified interval.
33         function refresher($msec) {
34                 if ( $msec )
35                         return "<html><head><script type='text/javascript'>window.onload=setTimeout('window.location.reload()', $msec);</script>\n</head>\n<body>\n";
36                 else
37                         return "<html><head><script type='text/javascript'>window.onload=window.location.reload();</script>\n</head>\n<body>\n";
38         }
39
40         // Returns associative array of code, header, cookies, body. Based on code from php.net.
41         function parse_response($this_response) {
42                 // Split response into header and body sections
43                 list($response_headers, $response_body) = explode("\r\n\r\n", $this_response, 2);
44                 $response_header_lines = explode("\r\n", $response_headers);
45
46                 // First line of headers is the HTTP response code
47                 $http_response_line = array_shift($response_header_lines);
48                 if(preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@',$http_response_line, $matches)) { $response_code = $matches[1]; }
49
50                 // put the rest of the headers in an array
51                 $response_header_array = array();
52                 foreach($response_header_lines as $header_line) {
53                         list($header,$value) = explode(': ', $header_line, 2);
54                         $response_header_array[$header] .= $value."\n";
55                 }
56
57                 $cookie_array = array();
58                 $cookies = explode("\n", $response_header_array["Set-Cookie"]);
59                 foreach($cookies as $this_cookie) { array_push($cookie_array, "Cookie: ".$this_cookie); }
60
61                 return array("code" => $response_code, "header" => $response_header_array, "cookies" => $cookie_array, "body" => $response_body);
62         }
63
64         // Prints a form for the user to enter Blogger creds.
65         function login_form($text='') {
66                 echo '<h1>' . __('Log in to Blogger') . "</h1>\n$text\n";
67                 echo '<form method="post" action="admin.php?import=blogger&amp;noheader=true&amp;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>';
68                 die;
69         }
70
71         // Sends creds to Blogger, returns the session cookies an array of headers.
72         function login_blogger($user, $pass) {
73                 $_url = 'http://www.blogger.com/login.do';
74                 $params = "username=$user&password=$pass";
75                 $ch = curl_init();
76                 curl_setopt($ch, CURLOPT_POST,1);
77                 curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
78                 curl_setopt($ch, CURLOPT_URL,$_url);
79                 curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
80                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
81                 curl_setopt($ch, CURLOPT_HEADER,1);
82                 curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
83                 $response = curl_exec ($ch);
84
85                 $response = $this->parse_response($response);
86
87                 sleep(1);
88
89                 return $response['cookies'];
90         }
91
92         // Requests page from Blogger, returns the response array.
93         function get_blogger($url, $header = '', $user=false, $pass=false) {
94                 $ch = curl_init();
95                 if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}");
96                 curl_setopt($ch, CURLOPT_URL,$url);
97                 curl_setopt($ch, CURLOPT_TIMEOUT, 10);
98                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
99                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
100                 curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
101                 curl_setopt($ch, CURLOPT_HEADER,1);
102                 if (is_array($header)) curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
103                 $response = curl_exec ($ch);
104
105                 $response = $this->parse_response($response);
106                 $response['url'] = $url;
107
108                 if (curl_errno($ch)) {
109                         print curl_error($ch);
110                 } else {
111                         curl_close($ch);
112                 }
113
114                 return $response;
115         }
116
117         // Posts data to Blogger, returns response array.
118         function post_blogger($url, $header = false, $paramary = false, $parse=true) {
119                 $params = '';
120                 if ( is_array($paramary) ) {
121                         foreach($paramary as $key=>$value)
122                                 if($key && $value != '')
123                                         $params.=$key."=".urlencode(stripslashes($value))."&";
124                 }
125                 if ($user && $pass) $params .= "username=$user&password=$pass";
126                 $params = trim($params,'&');
127                 $ch = curl_init();
128                 curl_setopt($ch, CURLOPT_POST,1);
129                 curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
130                 if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}");
131                 curl_setopt($ch, CURLOPT_URL,$url);
132                 curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
133                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
134                 curl_setopt($ch, CURLOPT_HEADER,$parse);
135                 curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
136                 if ($header) curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
137                 $response = curl_exec ($ch);
138         
139                 if ($parse) {
140                         $response = $this->parse_response($response);
141                         $response['url'] = $url;
142                         return $response;
143                 }
144         
145                 return $response;
146         }
147
148         // Prints the list of blogs for import.
149         function show_blogs() {
150                 global $import;
151                 echo '<h1>' . __('Selecting a Blog') . "</h1>\n<ul>";
152                 foreach ( $this->import['blogs'] as $blog ) {
153                         if (9 == $blog['nextstep']) $status = "100%";
154                         elseif (8 == $blog['nextstep']) $status = "90%";
155                         elseif (7 == $blog['nextstep']) $status = "82.5%";
156                         elseif (6 == $blog['nextstep']) $status = "75%";
157                         elseif (5 == $blog['nextstep']) $status = "57%";
158                         elseif (4 == $blog['nextstep']) $status = "28%";
159                         elseif (3 == $blog['nextstep']) $status = "14%";
160                         else $status = "0%";
161                         echo "\t<li><a href='admin.php?import=blogger&amp;noheader=true&amp;blog={$blog['id']}'>{$blog['title']}</a> $status</li>\n";
162                 }
163                 die("</ul>\n");
164         }
165
166         // Publishes.
167         function publish_blogger($i, $text) {
168                 $head = $this->refresher(2000) . "<h1>$text</h1>\n";
169                 if ( ! strstr($this->import['blogs'][$_GET['blog']]['publish'][$i], 'http') ) {
170                         // First call. Start the publish process with a fresh set of cookies.
171                         $this->import['cookies'] = $this->login_blogger($this->import['user'], $this->import['pass']);
172                         update_option('import-blogger', $this->import);
173                         $paramary = array('blogID' => $_GET['blog'], 'all' => '1', 'republishAll' => 'Republish Entire Blog', 'publish' => '1', 'redirectUrl' => "/publish.do?blogID={$_GET['blog']}&inprogress=true");
174
175                         $response = $this->post_blogger("http://www.blogger.com/publish.do?blogID={$_GET['blog']}", $this->import['cookies'], $paramary);
176                         if ( $response['code'] == '302' ) {
177                                 $url = str_replace('publish.g', 'publish-body.g', $response['header']['Location']);
178                                 $this->import['blogs'][$_GET['blog']]['publish'][$i] = $url;
179                                 update_option('import-blogger', $this->import);
180                                 $response = $this->get_blogger($url, $this->import['cookies']);
181                                 preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches);
182                                 $progress = $matches[0];
183                                 die($head . $progress);
184                         } else {
185                                 $this->import['blogs'][$_GET['blog']]['publish'][$i] = false;
186                                 update_option('import-blogger', $this->import);
187                                 die($head);
188                         }
189                 } else {
190                         // Subsequent call. Keep checking status until Blogger reports publish complete.
191                         $url = $this->import['blogs'][$_GET['blog']]['publish'][$i];
192                         $response = $this->get_blogger($url, $this->import['cookies']);
193                         if ( preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches) ) {
194                                 $progress = $matches[0];
195                                 if ( strstr($progress, '100%') ) {
196                                         $this->set_next_step($i);
197                                         $progress .= '<p>'.__('Moving on...').'</p>';
198                                 }
199                                 die($head . $progress);
200                         } else {
201                                 $this->import['blogs'][$_GET['blog']]['publish'][$i] = false;
202                                 update_option('import-blogger', $this->import);
203                                 die("$head<p>" . __('Trying again...') . '</p>');
204                         }
205                 }
206         }
207
208         // Sets next step, saves options
209         function set_next_step($step) {
210                 $this->import['blogs'][$_GET['blog']]['nextstep'] = $step;
211                 update_option('import-blogger', $this->import);
212         }
213         
214         // Redirects to next step
215         function do_next_step() {
216                 wp_redirect("admin.php?import=blogger&noheader=true&blog={$_GET['blog']}");
217                 die();
218         }
219
220         // Step 0: Do Blogger login, get blogid/title pairs.
221         function do_login() {
222                 if ( ( ! $this->import['user'] && ! is_array($this->import['cookies']) ) ) {
223                         // The user must provide a Blogger username and password.
224                         if ( ! ( $_POST['user'] && $_POST['pass'] ) ) {
225                                 $this->login_form(__('The script will log into your Blogger account, change some settings so it can read your blog, and restore the original settings when it\'s done. Here\'s what you do:').'</p><ol><li>'.__('Back up your Blogger template.').'</li><li>'.__('Back up any other Blogger settings you might need later.').'</li><li>'.__('Log out of Blogger').'</li><li>'.__('Log in <em>here</em> with your Blogger username and password.').'</li><li>'.__('On the next screen, click one of your Blogger blogs.').'</li><li>'.__('Do not close this window or navigate away until the process is complete.').'</li></ol>');
226                         }
227                 
228                         // Try logging in. If we get an array of cookies back, we at least connected.           
229                         $this->import['cookies'] = $this->login_blogger($_POST['user'], $_POST['pass']);
230                         if ( !is_array( $this->import['cookies'] ) ) {
231                                 $this->login_form(__('Login failed. Please enter your credentials again.'));
232                         }
233                         
234                         // Save the password so we can log the browser in when it's time to publish.
235                         $this->import['pass'] = $_POST['pass'];
236                         $this->import['user'] = $_POST['user'];
237
238                         // Get the Blogger welcome page and scrape the blog numbers and names from it
239                         $response = $this->get_blogger('http://www.blogger.com/home', $this->import['cookies']);
240                         if (! stristr($response['body'], 'signed in as') ) $this->login_form(__('Login failed. Please re-enter your username and password.'));
241                         $blogsary = array();
242                         preg_match_all('#posts\.g\?blogID=(\d+)">([^<]+)</a>#U', $response['body'], $blogsary);
243                         if ( ! count( $blogsary[1] < 1 ) )
244                                 die(__('No blogs found for this user.'));
245                         $this->import['blogs'] = array();
246                         $template = '<MainPage><br /><br /><br /><p>'.__('Are you looking for %title%? It is temporarily out of service. Please try again in a few minutes. Meanwhile, discover <a href="http://wordpress.org/">a better blogging tool</a>.').'</p><BloggerArchives><a class="archive" href="<$BlogArchiveURL$>"><$BlogArchiveName$></a><br /></BloggerArchives></MainPage><ArchivePage><Blogger><wordpresspost><$BlogItemDateTime$>|W|P|<$BlogItemAuthorNickname$>|W|P|<$BlogItemBody$>|W|P|<$BlogItemNumber$>|W|P|<$BlogItemTitle$>|W|P|<$BlogItemAuthorEmail$><BlogItemCommentsEnabled><BlogItemComments><wordpresscomment><$BlogCommentDateTime$>|W|P|<$BlogCommentAuthor$>|W|P|<$BlogCommentBody$></BlogItemComments></BlogItemCommentsEnabled></Blogger></ArchivePage>';
247                         foreach ( $blogsary[1] as $key => $id ) {
248                                 // Define the required Blogger options.
249                                 $blog_opts = array(
250                                         'blog-options-basic' => false,
251                                         'blog-options-archiving' => array('archiveFrequency' => 'm'),
252                                         'blog-publishing' => array('publishMode'=>'0', 'blogID' => "$id", 'subdomain' => mt_rand().mt_rand(), 'pingWeblogs' => 'false'),
253                                         'blog-formatting' => array('timeStampFormat' => '0', 'encoding'=>'UTF-8', 'convertLineBreaks'=>'false', 'floatAlignment'=>'false'),
254                                         'blog-comments' => array('commentsTimeStampFormat' => '0'),
255                                         'template-edit' => array( 'templateText' =>  str_replace('%title%', trim($blogsary[2][$key]), $template) )
256                                 );
257
258                                 // Build the blog options array template
259                                 foreach ($blog_opts as $blog_opt => $modify)
260                                         $new_opts["$blog_opt"] = array('backup'=>false, 'modify' => $modify, 'error'=>false);
261
262                                 $this->import['blogs']["$id"] = array(
263                                         'id' => $id,
264                                         'title' => trim($blogsary[2][$key]),
265                                         'options' => $new_opts,
266                                         'url' => false,
267                                         'publish_cookies' => false,
268                                         'published' => false,
269                                         'archives' => false,
270                                         'lump_authors' => false,
271                                         'newusers' => array(),
272                                         'nextstep' => 2
273                                 );
274                         }
275                         update_option('import-blogger', $this->import);
276                         wp_redirect("admin.php?import=blogger&noheader=true&step=1");
277                 }
278                 die();
279         }
280
281         // Step 1: Select one of the blogs belonging to the user logged in.
282         function select_blog() {
283                 if ( is_array($this->import['blogs']) ) {
284                         $this->show_blogs();
285                         die();
286                 } else {
287                         $this->restart();
288                 }
289         }
290
291         // Step 2: Backup the Blogger options pages, updating some of them.
292         function backup_settings() {
293                 $output.= '<h1>'.__('Backing up Blogger options')."</h1>\n";
294                 $form = false;
295                 foreach ($this->import['blogs'][$_GET['blog']]['options'] as $blog_opt => $optary) {
296                         if ( $blog_opt == $_GET['form'] ) {
297                                 // Save the posted form data
298                                 $this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['backup'] = $_POST;
299                                 update_option('import-blogger',$this->import);
300
301                                 // Post the modified form data to Blogger
302                                 if ( $optary['modify'] ) {
303                                         $posturl = "http://www.blogger.com/{$blog_opt}.do";
304                                         $headers = array_merge($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'], $this->import['cookies']);
305                                         if ( 'blog-publishing' == $blog_opt ) {
306                                                 if ( $_POST['publishMode'] > 0 ) {
307                                                         $response = $this->get_blogger("http://www.blogger.com/blog-publishing.g?blogID={$_GET['blog']}&publishMode=0", $headers);
308                                                         if ( $response['code'] >= 400 )
309                                                                 die('<h2>'.__('Failed attempt to change publish mode from FTP to BlogSpot.').'</h2><pre>' . addslashes(print_r($headers, 1)) . addslashes(print_r($response, 1)) . '</pre>');
310                                                         $this->import['blogs'][$_GET['blog']]['url'] = 'http://' . $optary['modify']['subdomain'] . '.blogspot.com/';
311                                                         sleep(2);
312                                                 } else {
313                                                         $this->import['blogs'][$_GET['blog']]['url'] = 'http://' . $_POST['subdomain'] . '.blogspot.com/';
314                                                         update_option('import-blogger', $this->import);
315                                                         $output .= "<del><p>$blog_opt</p></del>\n";
316                                                         continue;
317                                                 }
318                                                 $paramary = $optary['modify'];
319                                         } else {
320                                                 $paramary = array_merge($_POST, $optary['modify']);
321                                         }
322                                         $response = $this->post_blogger($posturl, $headers, $paramary);
323                                         if ( $response['code'] >= 400 || strstr($response['body'], 'There are errors on this form') )
324                                                 die('<p>'.__('Error on form submission. Retry or reset the importer.').'</p>' . addslashes(print_r($response, 1)));
325                                 }
326                                 $output .= "<del><p>$blog_opt</p></del>\n";
327                         } elseif ( is_array($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['backup']) ) {
328                                 // This option set has already been backed up.
329                                 $output .= "<del><p>$blog_opt</p></del>\n";
330                         } elseif ( ! $form ) {
331                                 // This option page needs to be downloaded and given to the browser for submission back to this script.
332                                 $response = $this->get_blogger("http://www.blogger.com/{$blog_opt}.g?blogID={$_GET['blog']}", $this->import['cookies']);
333                                 $this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'] = $response['cookies'];
334                                 update_option('import-blogger',$this->import);
335                                 $body = $response['body'];
336                                 $body = preg_replace("|\<!DOCTYPE.*\<body[^>]*>|ms","",$body);
337                                 $body = preg_replace("|/?{$blog_opt}.do|","admin.php?import=blogger&amp;noheader=true&amp;step=2&amp;blog={$_GET['blog']}&amp;form={$blog_opt}",$body);
338                                 $body = str_replace("name='submit'","name='supermit'",$body);
339                                 $body = str_replace('name="submit"','name="supermit"',$body);
340                                 $body = str_replace('</body>','',str_replace('</html>','',$body));
341                                 $form = "<div style='height:0px;width:0px;overflow:hidden;'>";
342                                 $form.= $body;
343                                 $form.= "</div><script type='text/javascript'>forms=document.getElementsByTagName('form');for(i=0;i<forms.length;i++){if(forms[i].action.search('{$blog_opt}')){forms[i].submit();break;}}</script>";
344                                 $output.= '<p>'.sprintf('<strong>%s</strong> in progress, please wait...', $blog_opt)."</p>\n";
345                         } else {
346                                 $output.= "<p>$blog_opt</p>\n";
347                         }
348                 }
349                 if ( $form )
350                         die($output . $form);
351
352                 $this->set_next_step(4);
353                 $this->do_next_step();
354         }
355
356         // Step 3: Cancelled :-)
357
358         // Step 4: Publish with the new template and settings.
359         function publish_blog() {
360                 $this->publish_blogger(5, __('Publishing with new template and options'));
361         }
362
363         // Step 5: Get the archive URLs from the new blog.
364         function get_archive_urls() {
365                 $bloghtml = $this->get_blogger($this->import['blogs'][$_GET['blog']]['url']);
366                 if (! strstr($bloghtml['body'], '<a class="archive"') )
367                         die(__('Your Blogger blog did not take the new template or did not respond.'));
368                 preg_match_all('#<a class="archive" href="([^"]*)"#', $bloghtml['body'], $archives);
369                 foreach ($archives[1] as $archive) {
370                         $this->import['blogs'][$_GET['blog']]['archives'][$archive] = false;
371                 }
372                 $this->set_next_step(6);
373                 $this->do_next_step();
374         }
375
376         // Step 6: Get each monthly archive, import it, mark it done.
377         function get_archive() {
378                 global $wpdb;
379                 $output = '<h2>'.__('Importing Blogger archives into WordPress').'</h2>';
380                 $did_one = false;
381                 $post_array = $posts = array();
382                 foreach ( $this->import['blogs'][$_GET['blog']]['archives'] as $url => $status ) {
383                         $archivename = substr(basename($url),0,7);
384                         if ( $status || $did_one ) {
385                                 $foo = 'bar';
386                                 // Do nothing.
387                         } else {
388                                 // Import the selected month
389                                 $postcount = 0;
390                                 $skippedpostcount = 0;
391                                 $commentcount = 0;
392                                 $skippedcommentcount = 0;
393                                 $status = __('in progress...');
394                                 $this->import['blogs'][$_GET['blog']]['archives']["$url"] = $status;
395                                 update_option('import-blogger', $import);
396                                 $archive = $this->get_blogger($url);
397                                 if ( $archive['code'] > 200 )
398                                         continue;       
399                                 $posts = explode('<wordpresspost>', $archive['body']);
400                                 for ($i = 1; $i < count($posts); $i = $i + 1) {
401                                         $postparts = explode('<wordpresscomment>', $posts[$i]);
402                                         $postinfo = explode('|W|P|', $postparts[0]);
403                                         $post_date = $postinfo[0];
404                                         $post_content = $postinfo[2];
405                                         // Don't try to re-use the original numbers
406                                         // because the new, longer numbers are too
407                                         // big to handle as ints.
408                                         //$post_number = $postinfo[3];
409                                         $post_title = ( $postinfo[4] != '' ) ? $postinfo[4] : $postinfo[3];
410                                         $post_author_name = $wpdb->escape(trim($postinfo[1]));
411                                         $post_author_email = $postinfo[5] ? $postinfo[5] : 'user@wordpress.org';
412         
413                                         if ( $this->lump_authors ) {
414                                                 // Ignore Blogger authors. Use the current user_ID for all posts imported.
415                                                 $post_author = $GLOBALS['user_ID'];
416                                         } else {
417                                                 // Add a user for each new author encountered.
418                                                 if (! username_exists($post_author_name) ) {
419                                                         $user_login = $wpdb->escape($post_author_name);
420                                                         $user_email = $wpdb->escape($post_author_email);
421                                                         $user_password = substr(md5(uniqid(microtime())), 0, 6);
422                                                         $result = wp_create_user( $user_login, $user_password, $user_email );
423                                                         $status.= sprintf('Registered user <strong>%s</strong>.', $user_login);
424                                                         $this->import['blogs'][$_GET['blog']]['newusers'][] = $user_login;
425                                                 }
426                                                 $userdata = get_userdatabylogin( $post_author_name );
427                                                 $post_author = $userdata->ID;
428                                         }
429                                         $post_date = explode(' ', $post_date);
430                                         $post_date_Ymd = explode('/', $post_date[0]);
431                                         $postyear = $post_date_Ymd[2];
432                                         $postmonth = zeroise($post_date_Ymd[0], 2);
433                                         $postday = zeroise($post_date_Ymd[1], 2);
434                                         $post_date_His = explode(':', $post_date[1]);
435                                         $posthour = zeroise($post_date_His[0], 2);
436                                         $postminute = zeroise($post_date_His[1], 2);
437                                         $postsecond = zeroise($post_date_His[2], 2);
438         
439                                         if (($post_date[2] == 'PM') && ($posthour != '12'))
440                                                 $posthour = $posthour + 12;
441                                         else if (($post_date[2] == 'AM') && ($posthour == '12'))
442                                                 $posthour = '00';
443         
444                                         $post_date = "$postyear-$postmonth-$postday $posthour:$postminute:$postsecond";
445         
446                                         $post_content = addslashes($post_content);
447                                         $post_content = str_replace(array('<br>','<BR>','<br/>','<BR/>','<br />','<BR />'), "\n", $post_content); // the XHTML touch... ;)
448         
449                                         $post_title = addslashes($post_title);
450                         
451                                         $post_status = 'publish';
452         
453                                         if ( $ID = post_exists($post_title, '', $post_date) ) {
454                                                 $post_array[$i]['ID'] = $ID;
455                                                 $skippedpostcount++;
456                                         } else {
457                                                 $post_array[$i]['post'] = compact('post_author', 'post_content', 'post_title', 'post_category', 'post_author', 'post_date', 'post_status');
458                                                 $post_array[$i]['comments'] = false;
459                                         }
460
461                                         // Import any comments attached to this post.
462                                         if ($postparts[1]) :
463                                         for ($j = 1; $j < count($postparts); $j = $j + 1) {
464                                                 $commentinfo = explode('|W|P|', $postparts[$j]);
465                                                 $comment_date = explode(' ', $commentinfo[0]);
466                                                 $comment_date_Ymd = explode('/', $comment_date[0]);
467                                                 $commentyear = $comment_date_Ymd[2];
468                                                 $commentmonth = zeroise($comment_date_Ymd[0], 2);
469                                                 $commentday = zeroise($comment_date_Ymd[1], 2);
470                                                 $comment_date_His = explode(':', $comment_date[1]);
471                                                 $commenthour = zeroise($comment_date_His[0], 2);
472                                                 $commentminute = zeroise($comment_date_His[1], 2);
473                                                 $commentsecond = '00';
474                                                 if (($comment_date[2] == 'PM') && ($commenthour != '12'))
475                                                         $commenthour = $commenthour + 12;
476                                                 else if (($comment_date[2] == 'AM') && ($commenthour == '12'))
477                                                         $commenthour = '00';
478                                                 $comment_date = "$commentyear-$commentmonth-$commentday $commenthour:$commentminute:$commentsecond";
479                                                 $comment_author = addslashes(strip_tags($commentinfo[1]));
480                                                 if ( strpos($commentinfo[1], 'a href') ) {
481                                                         $comment_author_parts = explode('&quot;', htmlentities($commentinfo[1]));
482                                                         $comment_author_url = $comment_author_parts[1];
483                                                 } else $comment_author_url = '';
484                                                 $comment_content = $commentinfo[2];
485                                                 $comment_content = str_replace(array('<br>','<BR>','<br/>','<BR/>','<br />','<BR />'), "\n", $comment_content);
486                                                 $comment_approved = 1;
487                                                 if ( comment_exists($comment_author, $comment_date) ) {
488                                                         $skippedcommentcount++;
489                                                 } else {
490                                                         $comment = compact('comment_author', 'comment_author_url', 'comment_date', 'comment_content', 'comment_approved');
491                                                         $post_array[$i]['comments'][$j] = wp_filter_comment($comment);
492                                                 }
493                                                 $commentcount++;
494                                         }
495                                         endif;
496                                         $postcount++;
497                                 }
498                                 if ( count($post_array) ) {
499                                         krsort($post_array);
500                                         foreach($post_array as $post) {
501                                                 if ( ! $comment_post_ID = $post['ID'] )
502                                                         $comment_post_ID = wp_insert_post($post['post']);
503                                                 if ( $post['comments'] ) {
504                                                         foreach ( $post['comments'] as $comment ) {
505                                                                 $comment['comment_post_ID'] = $comment_post_ID;
506                                                                 wp_insert_comment($comment);
507                                                         }
508                                                 }
509                                         }
510                                 }
511                                 $status = sprintf(__('%s post(s) parsed, %s skipped...'), $postcount,  $skippedpostcount).' '.
512                                         sprintf(__('%s comment(s) parsed, %s skipped...'), $commentcoun, $skippedcommentcount).' '.
513                                         ' <strong>'.__('Done').'</strong>';
514                                 $import = $this->import;
515                                 $import['blogs'][$_GET['blog']]['archives']["$url"] = $status;
516                                 update_option('import-blogger', $import);
517                                 $did_one = true;
518                         }
519                         $output.= "<p>$archivename $status</p>\n";
520                 }
521                 if ( ! $did_one )
522                         $this->set_next_step(7);
523                 die( $this->refresher(1000) . $output );
524         }
525
526         // Step 7: Restore the backed-up settings to Blogger
527         function restore_settings() {
528                 $output = '<h1>'.__('Restoring your Blogger options')."</h1>\n";
529                 $did_one = false;
530                 // Restore options in reverse order.
531                 if ( ! $this->import['reversed'] ) {
532                         $this->import['blogs'][$_GET['blog']]['options'] = array_reverse($this->import['blogs'][$_GET['blog']]['options'], true);
533                         $this->import['reversed'] = true;
534                         update_option('import-blogger', $this->import);
535                 }
536                 foreach ( $this->import['blogs'][$_GET['blog']]['options'] as $blog_opt => $optary ) {
537                         if ( $did_one ) {
538                                 $output .= "<p>$blog_opt</p>\n";
539                         } elseif ( $optary['restored'] || ! $optary['modify'] ) {
540                                 $output .= "<p><del>$blog_opt</del></p>\n";
541                         } else {
542                                 $posturl = "http://www.blogger.com/{$blog_opt}.do";
543                                 $headers = array_merge($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'], $this->import['cookies']);
544                                 if ( 'blog-publishing' == $blog_opt) {
545                                         if ( $optary['backup']['publishMode'] > 0 ) {
546                                                 $response = $this->get_blogger("http://www.blogger.com/blog-publishing.g?blogID={$_GET['blog']}&publishMode={$optary['backup']['publishMode']}", $headers);
547                                                 sleep(2);
548                                                 if ( $response['code'] >= 400 )
549                                                         die('<h1>Error restoring publishMode.</h1><p>Please tell the devs.</p>' . addslashes(print_r($response, 1)) );
550                                         }
551                                 }
552                                 if ( $optary['backup'] != $optary['modify'] ) {
553                                         $response = $this->post_blogger($posturl, $headers, $optary['backup']);
554                                         if ( $response['code'] >= 400 || strstr($response['body'], 'There are errors on this form') ) {
555                                                 $this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['error'] = true;
556                                                 update_option('import-blogger', $this->import);
557                                                 $output .= sprintf(__('%s failed. Trying again.'), "<p><strong>$blog_opt</strong> ").'</p>';
558                                         } else {
559                                                 $this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['restored'] = true;
560                                                 update_option('import-blogger', $this->import);
561                                                 $output .= sprintf(__('%s restored.'), "<p><strong>$blog_opt</strong> ").'</p>';
562                                         }
563                                 }
564                                 $did_one = true;
565                         }
566                 }
567
568                 if ( $did_one ) {
569                         die( $this->refresher(1000) . $output );
570                 } elseif ( $this->import['blogs'][$_GET['blog']]['options']['blog-publishing']['backup']['publishMode'] > 0 ) {
571                         $this->set_next_step(9);
572                 } else {
573                         $this->set_next_step(8);
574                 }
575
576                 $this->do_next_step();
577         }
578
579         // Step 8: Republish, all back to normal
580         function republish_blog() {
581                 $this->publish_blogger(9, __('Publishing with original template and options'));
582         }
583
584         // Step 9: Congratulate the user
585         function congrats() {
586                 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>';
587                 if ( count($this->import['blogs']) > 1 )
588                         echo '<li>'.__('In case you haven\'t done it already, you can import the posts from your other blogs:'). $this->show_blogs() . '</li>';
589                 if ( $n = count($this->import['blogs'][$_GET['blog']]['newusers']) )
590                         echo '<li>'.sprintf(__('Go to <a href="%s" target="%s">Authors &amp; Users</a>, where you can modify the new user(s) or delete them. If you want to make all of the imported posts yours, you will be given that option when you delete the new authors.'), 'users.php', '_parent').'</li>';
591                 echo '<li>'.__('For security, click the link below to reset this importer. That will clear your Blogger credentials and options from the database.').'</li>';
592                 echo '</ul>';
593         }
594
595         // Figures out what to do, then does it.
596         function start() {
597                 if ( $_GET['restart'] == 'true' ) {
598                         $this->restart();
599                 }
600                 
601                 if ( isset($_GET['noheader']) ) {
602                         header('Content-Type: text/html; charset=utf-8');
603
604                         $this->import = get_settings('import-blogger');
605
606                         if ( false === $this->import ) {
607                                 $step = 0;
608                         } elseif ( isset($_GET['step']) ) {
609                                 $step = (int) $_GET['step'];
610                         } elseif ( isset($_GET['blog']) && isset($this->import['blogs'][$_GET['blog']]['nextstep']) ) {
611                                 $step = $this->import['blogs'][$_GET['blog']]['nextstep'];
612                         } elseif ( is_array($this->import['blogs']) ) {
613                                 $step = 1;
614                         } else {
615                                 $step = 0;
616                         }
617 //echo "Step $step.";
618 //die('<pre>'.print_r($this->import,1).'</pre');
619                         switch ($step) {
620                                 case 0 :
621                                         $this->do_login();
622                                         break;
623                                 case 1 :
624                                         $this->select_blog();
625                                         break;
626                                 case 2 :
627                                         $this->backup_settings();
628                                         break;
629                                 case 3 :
630                                         $this->wait_for_blogger();
631                                         break;
632                                 case 4 :
633                                         $this->publish_blog();
634                                         break;
635                                 case 5 :
636                                         $this->get_archive_urls();
637                                         break;
638                                 case 6 :
639                                         $this->get_archive();
640                                         break;
641                                 case 7 :
642                                         $this->restore_settings();
643                                         break;
644                                 case 8 :
645                                         $this->republish_blog();
646                                         break;
647                                 case 9 :
648                                         $this->congrats();
649                                         break;
650                         }
651                         die;
652                         
653                 } else {
654                         $this->greet();
655                 }
656         }
657
658         function Blogger_Import() {
659                 // This space intentionally left blank.
660         }
661 }
662
663 $blogger_import = new Blogger_Import();
664
665 register_importer('blogger', 'Blogger', __('Import posts and comments from a Blogger account'), array ($blogger_import, 'start'));
666
667 ?>