Created
January 15, 2013 14:23
-
-
Save emohamed/4539002 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| if ($_SERVER['REQUEST_METHOD']=='POST') { | |
| 21try { | |
| $enable_gzip = isset($_POST['gzip']); | |
| $migrator = new WpMigrator($_POST['new-home'], $_POST['new-prefix']); | |
| if (is_uploaded_file($_FILES['dump']['tmp_name'])) { | |
| $file_ext = preg_replace('~.*\.~', '', $_FILES['dump']['name']); | |
| $file_ext = strtolower($file_ext); | |
| $file_location = $_FILES['dump']['tmp_name']; | |
| $original_name = $_FILES['dump']['name']; | |
| } else if (is_valid_url($_POST['dump-url'])) { | |
| $remote = $_POST['dump-url']; | |
| $file_ext = preg_replace('~.*\.~', $remote); | |
| $file_location = $migrator->get_tmp_file(); | |
| copy($remote, $file_location); | |
| $original_name = basename($file_location); | |
| } else { | |
| $error = "Please specify either file or URL"; | |
| } | |
| $result_filename = preg_replace('~.gz$~', '', $_FILES['dump']['name']); | |
| if ($enable_gzip) { | |
| $result_filename .= '.gz'; | |
| } | |
| if (!isset($error)) { | |
| if ($file_ext=='gz') { | |
| $extracted = $migrator->get_tmp_file(); | |
| $migrator->_exec("gunzip -c $file_location > $extracted"); | |
| $file_location = $extracted; | |
| } | |
| $res = $migrator->migrate_file($file_location, $enable_gzip); | |
| header('Content-Disposition: attachment; filename="' . $result_filename . '"'); | |
| readfile($res); | |
| exit; | |
| } | |
| } catch (Exception $e) { | |
| $error = $e->getMessage(); | |
| } | |
| } | |
| class WpMigrator { | |
| var $to_be_cleaned = array(), | |
| $seds = array(); | |
| function __construct($new_home, $new_prefix) { | |
| # make sure that the URL is properly formatted | |
| if (!is_valid_url($new_home)) { | |
| throw new Exception("Home URL $url_pattern doesn't look correct. "); | |
| } | |
| $this->new_home = $new_home; | |
| $this->new_prefix = $new_prefix; | |
| } | |
| # delete temp files ... | |
| function __destruct () { | |
| foreach ($this->to_be_cleaned as $filename) { | |
| unlink($filename); | |
| } | |
| } | |
| function get_tmp_file() { | |
| $tmp_file_counter = 0; | |
| $file = "/tmp/migration-tmp-file-$tmp_file_counter"; | |
| while (file_exists($file)) { | |
| $tmp_file_counter++; | |
| $file = "/tmp/migration-tmp-file-$tmp_file_counter"; | |
| } | |
| $this->to_be_cleaned[] = $file; | |
| return $file; | |
| } | |
| # wrapper for shell commands executing | |
| function _exec($cmd) { | |
| return trim(shell_exec($cmd)); | |
| } | |
| function migrate_file($src_file, $enable_gzip) { | |
| $this->src_file = $src_file; | |
| $this->replace_tables(); | |
| $this->replace_urls(); | |
| $this->replace_misc(); | |
| $this->fix_serailized_arrays(); | |
| $tmp = $this->get_tmp_file(); | |
| $cmd = "cat " . escapeshellarg($this->src_file) . " | " . | |
| implode(' | ', $this->seds) . | |
| ($enable_gzip ? ' | gzip ' : '') . " > " . | |
| $tmp; | |
| $this->_exec($cmd); | |
| return $tmp; | |
| } | |
| function fix_serailized_arrays() { | |
| $this->seds[] = "php fix-php-serialized-array.php"; | |
| } | |
| function replace_tables () { | |
| $tables_declarations = $this->_exec("grep \"^CREATE TABLE\" $this->src_file"); | |
| preg_match_all('~`(.*?)`~', $tables_declarations, $tables); | |
| $tables = $tables[1]; | |
| $posts_tables = array_values(preg_grep('~posts$~', $tables)); | |
| if (count($posts_tables) > 1) { | |
| # mutlistie -- take the table with shortest name | |
| $shortest = ''; | |
| foreach ($posts_tables as $posts_table_name) { | |
| if (strlen($shortest)==0) { $shortest = $posts_table_name; continue; } | |
| if (strlen($posts_table_name) < strlen($shortest)) { | |
| $shortest = $posts_table_name; | |
| } | |
| } | |
| $posts_table = $shortest; | |
| } else { | |
| $posts_table = $posts_tables[0]; | |
| } | |
| $this->old_prefix = $old_prefix = preg_replace('~posts$~', '', $posts_table); | |
| foreach ($tables as $old_table) { | |
| $new_table = preg_replace('~^' . $old_prefix . '~', $this->new_prefix, $old_table); | |
| $this->seds[] = "sed s/$old_table/$new_table/g"; | |
| } | |
| } | |
| function replace_urls() { | |
| $home_declaration = $this->_exec("grep \"'home'\" $this->src_file | head -n 1 | sed 's/),(/),\\n(/g' | grep \"home\" | head -n 1"); | |
| preg_match('~\'(http.*?)\'~', $home_declaration, $home); | |
| $old_home = $home[1]; | |
| $new_home = $this->new_home; | |
| if (has_trailing_slash($old_home) && !has_trailing_slash($new_home)) { | |
| $new_home = add_trailing_slash($new_home); | |
| } else if (!has_trailing_slash($old_home) && has_trailing_slash($new_home)) { | |
| $new_home = remove_trailing_slash($new_home); | |
| } | |
| $this->seds[] = "sed 's/" . escape_for_sed($old_home) . "/" . escape_for_sed($new_home) . "/g'"; | |
| } | |
| function replace_misc() { | |
| $misc = array( | |
| 'user_roles', | |
| 'capabilities', | |
| 'user_level', | |
| 'user-settings', | |
| ); | |
| foreach ($misc as $replace) { | |
| $this->seds[] = "sed s/" . escape_for_sed("$this->old_prefix$replace") . "/" . escape_for_sed("$this->new_prefix$replace") . "/g"; | |
| } | |
| } | |
| } | |
| function is_valid_url($url) { | |
| return preg_match('~^https?://.+~i', $url); | |
| } | |
| function escape_for_sed($string) { | |
| return str_replace('/', '\/', $string); | |
| } | |
| function has_trailing_slash($string) { | |
| return preg_match('~/$~', $string); | |
| } | |
| function remove_trailing_slash($string) { | |
| return preg_replace('~/$~', '', $string);; | |
| } | |
| function add_trailing_slash($string) { | |
| return $string . "/"; | |
| } | |
| ?> | |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
| <html xmlns="http://www.w3.org/1999/xhtml"> | |
| <head> | |
| <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> | |
| <title>WordPress Migration Tool</title> | |
| <style type="text/css" media="screen"> | |
| * { padding:0; margin:0; } | |
| body { | |
| font-family: Georgia, sans-serif; | |
| font-size: 13px; | |
| line-height: 1.4; | |
| background: #f5f5f5; | |
| padding: 20px; | |
| } | |
| code { | |
| display:block; | |
| background:lightyellow; | |
| border:solid 1px #ddd; | |
| margin:10px 0; | |
| padding:5px; | |
| font-weight:bold; | |
| -moz-border-radius: 5px; | |
| -webkit-border-radius: 5px; | |
| } | |
| h2 { font-size: 19px; } | |
| h2 span { cursor: pointer; font-size: 14px;} | |
| .hidden { display: none; } | |
| .red { color:red; } | |
| strong.red { font-size:1.5em } | |
| .info { padding:10px 30px; font-size:1em; } | |
| h3 { font-size:1.3em; } | |
| ol { padding:20px 40px } | |
| ol ul li { margin-left: 35px; } | |
| li { padding-bottom:20px; border-bottom:solid 1px #eee; margin-bottom:20px; } | |
| li li { padding-bottom:10px; margin-bottom:0; border:0; } | |
| p { font-size:1em; padding:10px 0; } | |
| small { font-size:0.9em; font-weight:normal; } | |
| #wrapper { width:1000px; margin:0 auto; padding:10px; background:#fff; border:solid 10px #fff; -moz-border-radius: 20px; -webkit-border-radius: 20px; } | |
| .admin-path { background: #eee; padding: 2px 5px; } | |
| h1 { color:darkred; border-bottom:solid 1px #eee; padding-bottom:15px; } | |
| .checkbox { width:18px; height:18px; vertical-align:top; position:relative; top:5px; margin-right:10px; } | |
| form { padding: 20px; } | |
| .row label, .row input { float: left; margin-bottom: 10px } | |
| .row label { width: 120px; } | |
| label.second { border-left: solid 3px #ddd; padding-left: 10px; margin-left: 10px } | |
| .error { width: 300px; background: #eee; text-align: center; margin: 30px auto 0; border: solid 1px red; color: red; padding: 10px; } | |
| label.inline-label { margin-left: 5px; } | |
| input[type=checkbox] { vertical-align:top; position:relative; top:3px;} | |
| .cl { clear: both; height: 0px; font-size: 0px; line-height: 0px; } | |
| </style> | |
| <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript" charset="utf-8"></script> | |
| </head> | |
| <body> | |
| <div id="wrapper"> | |
| <h1>WordPress Migration Tool</h1> | |
| <?php if (!empty($error)) : ?> | |
| <p class="error"><?php echo $error ?></p> | |
| <?php endif ?> | |
| <form method="POST" enctype="multipart/form-data"> | |
| <div class="row"> | |
| <label>File: </label> | |
| <input type="file" name="dump" /> | |
| <label class="second">Or URL: </label> | |
| <input type="text" name="dump-url" /> | |
| <div class="cl"> </div> | |
| </div> | |
| <div class="row"> | |
| <label>New Home URL: </label> | |
| <input type="text" name="new-home" value="http://" /> | |
| <div class="cl"> </div> | |
| </div> | |
| <div class="row"> | |
| <label>New Prefix: </label> | |
| <input type="text" name="new-prefix" value="wp_" /> | |
| <div class="cl"> </div> | |
| </div> | |
| <div class="row"> | |
| <label> </label> | |
| <input type="checkbox" name="gzip" id="gzip" /> | |
| <label for="gzip" class="inline-label">gzip result?</label> | |
| <div class="cl"> </div> | |
| </div> | |
| <div class="row"> | |
| <label> </label> | |
| <input type="submit" value="Go" /> | |
| </div> | |
| </form> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment