[ Index ]

WordPress Source Cross Reference

title

Body

[close]

/wp-admin/import/ -> blogger.php (source)

   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                  wp_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                                  wp_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                          wp_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