Last active
November 15, 2017 09:13
-
-
Save yavir-me/2b49b6e833899814fdb646400551351d to your computer and use it in GitHub Desktop.
Replace domain wordpress (whole db)
This file contains 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 | |
require 'DBConnector.php'; | |
class DBProcessor | |
{ | |
protected $textFieldTypes = ['text', 'blob', 'varchar', 'longtext', 'tinytext', 'text', 'mediumtext']; | |
public $replacement; | |
public $replacementWith; | |
public $dbName; | |
/** | |
* DBProcessor constructor. | |
* @param string $replacement | |
* @param string $replacementWith | |
*/ | |
public function __construct($dbName, $replacement, $replacementWith) | |
{ | |
$this->replacement = $replacement; | |
$this->replacementWith = $replacementWith; | |
$this->dbName = $dbName; | |
} | |
public function process() | |
{ | |
$dbh = DBConnector::getConnection(); | |
$sth = $dbh->query('SHOW TABLES'); | |
$sth->execute(); | |
foreach ($sth->fetchAll() as $table) { | |
$tableName = $table["Tables_in_$this->dbName"]; | |
$tableFieldsStmt = $dbh->query('DESCRIBE ' . $tableName); | |
$tableFieldsStmt->execute(); | |
$primaryKey = ''; | |
foreach ($tableFieldsStmt->fetchAll() as $columnName) { | |
// set primary key for a table. do not process replacements in the primary key column | |
if (!$primaryKey) { | |
$primaryKey = $columnName['Field']; | |
continue; | |
} | |
// check if filed type is text | |
if ($this->checkAppropriateType($columnName['Type'])) { | |
$specifiedColumnData = $dbh->query("SELECT `{$primaryKey}`, `{$columnName['Field']}` FROM `{$tableName}`"); | |
// skip iteration for empty strings | |
if (!$specifiedColumnData) { | |
continue; | |
} | |
$specifiedColumnData->execute(); | |
// for each row of the given column check for unserialized data and replace needed content | |
foreach ($specifiedColumnData->fetchAll() as $curRow) { | |
$rowValue = array_slice($curRow, 1, 1); | |
$currentId = $curRow[key($curRow)]; | |
if (!isset($rowValue[key($rowValue)])) { | |
continue; // for null values | |
} | |
$curValue = $rowValue[key($rowValue)]; | |
// check for serializing | |
if ($this->is_serialized($curValue)) { // data serialized | |
$deserialize = $this->maybe_unserialize($curValue); | |
if (is_array($deserialize)) { | |
try { | |
$updatedValue = serialize($this->parseSerializedData($deserialize)); | |
} catch (Exception $e) { | |
print $e->getMessage(); | |
} | |
} elseif (is_object($deserialize)) { | |
print 'value has object type' . PHP_EOL; | |
} elseif (is_array($deserialize)) { | |
print 'value has array type' . PHP_EOL; | |
} else { | |
$updatedValue = str_ireplace("'", "\'", $curValue); | |
} | |
// update reserialized value | |
try { | |
$this->updateValue($tableName, $primaryKey, $columnName['Field'], $currentId, $updatedValue); | |
} catch (Exception $e) { | |
print $e->getMessage() . ' [SERIALIZED DATA ERROR]' . PHP_EOL; | |
} | |
print 'Serialized data updated' . PHP_EOL; | |
} elseif (stripos($curValue, $this->replacement)) { | |
$updatedValue = str_ireplace($this->replacement, $this->replacementWith, $curValue); | |
try { | |
$this->updateValue($tableName, $primaryKey, $columnName['Field'], $currentId, $updatedValue); | |
} catch (Exception $e) { | |
print $e->getMessage() . ' [UNSERIALIZED DATA ERROR]' . PHP_EOL; | |
} | |
print 'Unserialized data updated' . PHP_EOL; | |
} | |
} | |
} | |
} | |
} | |
} | |
/* | |
* Checks for an appropriate type in a field | |
* @fieldType mixed - type of the given string | |
* @return bool | |
*/ | |
function maybe_unserialize($original) | |
{ | |
if ($this->is_serialized($original)) // don't attempt to unserialize data that wasn't serialized going in | |
return @unserialize($original); | |
return $original; | |
} | |
protected function is_serialized($data, $strict = true) | |
{ | |
// if it isn't a string, it isn't serialized. | |
if (!is_string($data)) { | |
return false; | |
} | |
$data = trim($data); | |
if ('N;' == $data) { | |
return true; | |
} | |
if (strlen($data) < 4) { | |
return false; | |
} | |
if (':' !== $data[1]) { | |
return false; | |
} | |
if ($strict) { | |
$lastc = substr($data, - 1); | |
if (';' !== $lastc && '}' !== $lastc) { | |
return false; | |
} | |
} else { | |
$semicolon = strpos($data, ';'); | |
$brace = strpos($data, '}'); | |
// Either ; or } must exist. | |
if (false === $semicolon && false === $brace) | |
return false; | |
// But neither must be in the first X characters. | |
if (false !== $semicolon && $semicolon < 3) | |
return false; | |
if (false !== $brace && $brace < 4) | |
return false; | |
} | |
$token = $data[0]; | |
switch ($token) { | |
case 's' : | |
if ($strict) { | |
if ('"' !== substr($data, - 2, 1)) { | |
return false; | |
} | |
} elseif (false === strpos($data, '"')) { | |
return false; | |
} | |
// or else fall through | |
case 'a' : | |
case 'O' : | |
return (bool) preg_match("/^{$token}:[0-9]+:/s", $data); | |
case 'b' : | |
case 'i' : | |
case 'd' : | |
$end = $strict ? '$' : ''; | |
return (bool) preg_match("/^{$token}:[0-9.E-]+;$end/", $data); | |
} | |
return false; | |
} | |
protected function checkAppropriateType($fieldType) | |
{ | |
$fieldType = strtolower(explode('(', $fieldType)[0]); | |
return in_array($fieldType, $this->textFieldTypes); | |
} | |
protected function parseSerializedData($deserialize) | |
{ | |
foreach ($deserialize as $key => $value) { | |
if (is_string($value)) { | |
$deserialize[$key] = str_ireplace($this->replacement, $this->replacementWith, $value); | |
} elseif (is_array($value)) { | |
$deserialize[$key] = $this->parseSerializedData($value); | |
} elseif (is_object($value)) { | |
continue; | |
// throw new Exception("We don't support object"); | |
} | |
} | |
return $deserialize; | |
} | |
protected function updateValue($tableName, $primaryKey, $columnName, $curRowId, $newValue) | |
{ | |
$dbh = DBConnector::getConnection(); | |
$sql = "UPDATE `$tableName` SET `$columnName` = :newValue WHERE `$primaryKey` = $curRowId"; | |
$sth = $dbh->prepare($sql); | |
$sth->bindParam(':newValue', $newValue); | |
$result = $sth->execute(); | |
if (!$result) { | |
throw new Exception($sth->errorInfo()); | |
} | |
} | |
} | |
$processor = new DBProcessor('gsm_replacement', '//gsm-uk.co.uk', '//gsm-uk.co.uk.allbugs.info'); | |
$processor->process(); | |
echo 'Script completed', PHP_EOL; | |
die(); |
This file contains 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
#!/usr/bin/php | |
<?php | |
/* | |
* Blogestudio Fix Serialization 1.2 | |
* Fixer script of length attributes for serialized strings (e.g. Wordpress databases) | |
* License: GPL version 3 or later - http://www.gnu.org/licenses/gpl.txt | |
* By Pau Iglesias | |
* http://blogestudio.com | |
* | |
* Inspiration and regular expression code base from David Coveney: | |
* http://davidcoveney.com/575/php-serialization-fix-for-wordpress-migrations/ | |
* | |
* Usage: | |
* | |
* /usr/bin/php fix-serialization.php my-sql-file.sql | |
* | |
* Versions: | |
* | |
* 1.0 2011-08-03 Initial release | |
* 1.1 2011-08-18 Support for backslashed quotes, added some code warnings | |
* 1.2 2011-09-29 Support for null or zero length strings after preg_replace is called, and explain how to handle these errors | |
* | |
* Knowed errors: | |
* | |
* - Memory size exhausted | |
* Allowed memory size of 67108864 bytes exhausted (tried to allocate 35266489 bytes) | |
* How to fix: update php.ini memory_limit to 512M or more, and restart cgi service or web server | |
* | |
* - Function preg_replace returns null or 0 length string | |
* If preg_last_error = PREG_BACKTRACK_LIMIT_ERROR (value 2), increase pcre.backtrack_limit in php.ini (by default 100k, change to 2M by example) | |
* Same way for others preg_last_error codes: http://www.php.net/manual/en/function.preg-last-error.php | |
* | |
* TODO next versions | |
* | |
* - Check if needed UTF-8 support detecting and adding u PCRE modifier | |
* | |
*/ | |
// Unescape to avoid dump-text issues | |
function unescape_mysql($value) { | |
return str_replace(array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'), | |
array("\\", "\0", "\n", "\r", "\x1a", "'", '"'), | |
$value); | |
} | |
// Fix strange behaviour if you have escaped quotes in your replacement | |
function unescape_quotes($value) { | |
return str_replace('\"', '"', $value); | |
} | |
// Check command line arguments | |
if (!(isset($argv) && isset($argv[1]))) { | |
// Error | |
echo 'Error: no input file specified'."\n\n"; | |
// With arguments | |
} else { | |
// Compose path from argument | |
$path = dirname(__FILE__).'/'.$argv[1]; | |
if (!file_exists($path)) { | |
// Error | |
echo 'Error: input file does not exists'."\n"; | |
echo $path."\n\n"; | |
// File exists | |
} else { | |
// Get file contents | |
if (!($fp = fopen($path, 'r'))) { | |
// Error | |
echo 'Error: can`t open input file for read'."\n"; | |
echo $path."\n\n"; | |
// File opened for read | |
} else { | |
// Initializations | |
$do_preg_replace = false; | |
// Copy data | |
if (!($data = fread($fp, filesize($path)))) { | |
// Error | |
echo 'Error: can`t read entire data from input file'."\n"; | |
echo $path."\n\n"; | |
// Check data | |
} elseif (!(isset($data) && strlen($data) > 0)) { | |
// Warning | |
echo "Warning: the file is empty or can't read contents\n"; | |
echo $path."\n\n"; | |
// Data ok | |
} else { | |
// Tag context | |
$do_preg_replace = true; | |
// Replace serialized string values | |
$data = preg_replace('!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!e', "'s:'.strlen(unescape_mysql('$3')).':\"'.unescape_quotes('$3').'\";'", $data); | |
} | |
// Close file | |
fclose($fp); | |
// Check data | |
if (!(isset($data) && strlen($data) > 0)) { | |
// Check origin | |
if ($do_preg_replace) { | |
// Error | |
echo "Error: preg_replace returns nothing\n"; | |
if (function_exists('preg_last_error')) echo "preg_last_error() = ".preg_last_error()."\n"; | |
echo $path."\n\n"; | |
} | |
// Data Ok | |
} else { | |
// And finally write data | |
if (!($fp = fopen($path, 'w'))) { | |
// Error | |
echo "Error: can't open input file for writing\n"; | |
echo $path."\n\n"; | |
// Open for write | |
} else { | |
// Write file data | |
if (!fwrite($fp, $data)) { | |
// Error | |
echo "Error: can't write input file\n"; | |
echo $path."\n\n"; | |
} | |
// Close file | |
fclose($fp); | |
} | |
} | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment