2015-10-15 22:52:37 +10:00
< ? php
class MainWP_Clone_Install {
protected $file ;
public $config ;
/** @var $archiver Tar_Archiver */
protected $archiver ;
/**
* Class constructor
*
* @ param string $file The zip backup file path
*/
public function __construct ( $file ) {
2020-03-26 14:11:33 +00:00
require_once ABSPATH . 'wp-admin/includes/class-pclzip.php' ;
2015-10-15 22:52:37 +10:00
$this -> file = $file ;
if ( '.zip' === substr ( $this -> file , - 4 ) ) {
$this -> archiver = null ;
2020-03-26 14:11:33 +00:00
} elseif ( '.tar.gz' === substr ( $this -> file , - 7 ) ) {
2015-10-15 22:52:37 +10:00
$this -> archiver = new Tar_Archiver ( null , 'tar.gz' );
2020-03-26 14:11:33 +00:00
} elseif ( '.tar.bz2' === substr ( $this -> file , - 8 ) ) {
2015-10-15 22:52:37 +10:00
$this -> archiver = new Tar_Archiver ( null , 'tar.bz2' );
2020-03-26 14:11:33 +00:00
} elseif ( '.tar' === substr ( $this -> file , - 4 ) ) {
2015-10-15 22:52:37 +10:00
$this -> archiver = new Tar_Archiver ( null , 'tar' );
}
}
/**
* Check for default PHP zip support
*
* @ return bool
*/
public function checkZipSupport () {
return class_exists ( 'ZipArchive' );
}
/**
* Check if we could run zip on console
*
* @ return bool
*/
public function checkZipConsole () {
2020-03-26 20:01:04 +00:00
// todo: implement
// return function_exists('system');
2015-10-15 22:52:37 +10:00
return false ;
}
public function checkWPZip () {
return function_exists ( 'unzip_file' );
}
public function removeConfigFile () {
if ( ! $this -> file || ! file_exists ( $this -> file ) ) {
return false ;
}
if ( null !== $this -> archiver ) {
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipConsole () ) {
2020-03-26 20:01:04 +00:00
// todo: implement
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipSupport () ) {
2015-10-15 22:52:37 +10:00
$zip = new ZipArchive ();
$zipRes = $zip -> open ( $this -> file );
if ( $zipRes ) {
$zip -> deleteName ( 'wp-config.php' );
$zip -> deleteName ( 'clone' );
$zip -> close ();
return true ;
}
return false ;
} else {
2020-03-26 20:01:04 +00:00
// use pclzip
2015-10-15 22:52:37 +10:00
$zip = new PclZip ( $this -> file );
$list = $zip -> delete ( PCLZIP_OPT_BY_NAME , 'wp-config.php' );
$list2 = $zip -> delete ( PCLZIP_OPT_BY_NAME , 'clone' );
if ( 0 === $list ) {
return false ;
}
return true ;
}
return false ;
}
public function testDownload () {
if ( ! $this -> file_exists ( 'wp-content/' ) ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'This is not a full backup.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
if ( ! $this -> file_exists ( 'wp-admin/' ) ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'This is not a full backup.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
if ( ! $this -> file_exists ( 'wp-content/dbBackup.sql' ) ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'Database backup is missing.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
}
private function file_exists ( $file ) {
if ( 'extracted' === $this -> file ) {
return file_get_contents ( '../clone/config.txt' );
}
if ( ! $this -> file || ! file_exists ( $this -> file ) ) {
return false ;
}
if ( null !== $this -> archiver ) {
if ( ! $this -> archiver -> isOpen () ) {
$this -> archiver -> read ( $this -> file );
}
return $this -> archiver -> file_exists ( $file );
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipConsole () ) {
2020-03-26 20:01:04 +00:00
// todo: implement
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipSupport () ) {
2015-10-15 22:52:37 +10:00
$zip = new ZipArchive ();
$zipRes = $zip -> open ( $this -> file );
if ( $zipRes ) {
$content = $zip -> locateName ( $file );
$zip -> close ();
return false !== $content ;
}
return false ;
} else {
return true ;
}
return false ;
}
public function readConfigurationFile () {
$configContents = $this -> getConfigContents ();
if ( false === $configContents ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'Cant read configuration file from the backup.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
2015-12-05 17:38:52 +01:00
$this -> config = maybe_unserialize ( base64_decode ( $configContents ) );
2015-10-15 22:52:37 +10:00
if ( isset ( $this -> config [ 'plugins' ] ) ) {
MainWP_Helper :: update_option ( 'mainwp_temp_clone_plugins' , $this -> config [ 'plugins' ] );
}
if ( isset ( $this -> config [ 'themes' ] ) ) {
MainWP_Helper :: update_option ( 'mainwp_temp_clone_themes' , $this -> config [ 'themes' ] );
}
}
public function setConfig ( $key , $val ) {
$this -> config [ $key ] = $val ;
}
public function testDatabase () {
$link = @ MainWP_Child_DB :: connect ( $this -> config [ 'dbHost' ], $this -> config [ 'dbUser' ], $this -> config [ 'dbPass' ] );
if ( ! $link ) {
throw new Exception ( __ ( 'Invalid database host or user/password.' , 'mainwp-child' ) );
}
$db_selected = @ MainWP_Child_DB :: select_db ( $this -> config [ 'dbName' ], $link );
if ( ! $db_selected ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'Invalid database name.' , 'mainwp-child' ) );
2015-10-15 22:52:37 +10:00
}
}
public function clean () {
2015-12-22 19:18:07 +01:00
$files = glob ( WP_CONTENT_DIR . '/dbBackup*.sql' );
foreach ( $files as $file ) {
@ unlink ( $file );
2015-10-15 22:52:37 +10:00
}
if ( file_exists ( ABSPATH . 'clone/config.txt' ) ) {
@ unlink ( ABSPATH . 'clone/config.txt' );
}
if ( MainWP_Helper :: is_dir_empty ( ABSPATH . 'clone' ) ) {
@ rmdir ( ABSPATH . 'clone' );
}
try {
$dirs = MainWP_Helper :: getMainWPDir ( 'backup' , false );
$backupdir = $dirs [ 0 ];
$files = glob ( $backupdir . '*' );
foreach ( $files as $file ) {
if ( MainWP_Helper :: isArchive ( $file ) ) {
@ unlink ( $file );
}
}
} catch ( Exception $e ) {
}
}
public function updateWPConfig () {
$wpConfig = file_get_contents ( ABSPATH . 'wp-config.php' );
$wpConfig = $this -> replaceVar ( 'table_prefix' , $this -> config [ 'prefix' ], $wpConfig );
if ( isset ( $this -> config [ 'lang' ] ) ) {
$wpConfig = $this -> replaceDefine ( 'WPLANG' , $this -> config [ 'lang' ], $wpConfig );
}
file_put_contents ( ABSPATH . 'wp-config.php' , $wpConfig );
}
public function update_option ( $name , $value ) {
/** @var $wpdb wpdb */
global $wpdb ;
2015-12-05 17:38:52 +01:00
$var = $wpdb -> get_var ( $wpdb -> prepare ( 'SELECT option_value FROM ' . $this -> config [ 'prefix' ] . 'options WHERE option_name = %s' , $name ) );
2015-10-15 22:52:37 +10:00
if ( null === $var ) {
2016-01-18 19:40:51 +01:00
$wpdb -> query ( $wpdb -> prepare ( 'INSERT INTO ' . $this -> config [ 'prefix' ] . 'options (`option_name`, `option_value`) VALUES (%s, "' . MainWP_Child_DB :: real_escape_string ( maybe_serialize ( $value ) ) . '")' , $name ) );
2015-10-15 22:52:37 +10:00
} else {
2016-01-18 19:40:51 +01:00
$wpdb -> query ( $wpdb -> prepare ( 'UPDATE ' . $this -> config [ 'prefix' ] . 'options SET option_value = "' . MainWP_Child_DB :: real_escape_string ( maybe_serialize ( $value ) ) . '" WHERE option_name = %s' , $name ) );
2015-10-15 22:52:37 +10:00
}
}
public function install () {
/** @var $wpdb wpdb */
global $wpdb ;
$table_prefix = $this -> config [ 'prefix' ];
$home = get_option ( 'home' );
$site_url = get_option ( 'siteurl' );
// Install database
define ( 'WP_INSTALLING' , true );
define ( 'WP_DEBUG' , false );
$query = '' ;
$tableName = '' ;
$wpdb -> query ( 'SET foreign_key_checks = 0' );
2015-12-22 19:18:07 +01:00
$files = glob ( WP_CONTENT_DIR . '/dbBackup*.sql' );
foreach ( $files as $file ) {
$handle = @ fopen ( $file , 'r' );
$lastRun = 0 ;
if ( $handle ) {
$readline = '' ;
while ( ( $line = fgets ( $handle , 81920 ) ) !== false ) {
if ( time () - $lastRun > 20 ) {
2020-03-26 20:01:04 +00:00
@ set_time_limit ( 0 ); // reset timer..
2015-12-22 19:18:07 +01:00
$lastRun = time ();
}
2015-10-15 22:52:37 +10:00
2015-12-22 19:18:07 +01:00
$readline .= $line ;
if ( ! stristr ( $line , " ; \n " ) && ! feof ( $handle ) ) {
continue ;
}
2015-10-15 22:52:37 +10:00
2015-12-22 19:18:07 +01:00
$splitLine = explode ( " ; \n " , $readline );
$splitLineLength = count ( $splitLine );
for ( $i = 0 ; $i < $splitLineLength - 1 ; $i ++ ) {
$wpdb -> query ( $splitLine [ $i ] );
2015-10-15 22:52:37 +10:00
}
2015-12-22 19:18:07 +01:00
$readline = $splitLine [ count ( $splitLine ) - 1 ];
2015-10-15 22:52:37 +10:00
}
2015-12-22 19:18:07 +01:00
if ( trim ( $readline ) != '' ) {
$wpdb -> query ( $readline );
2015-10-15 22:52:37 +10:00
}
2015-12-22 19:18:07 +01:00
if ( ! feof ( $handle ) ) {
2016-10-24 20:33:37 +02:00
throw new Exception ( __ ( 'Error: unexpected end of file for database.' , 'mainwp-child' ) );
2015-12-22 19:18:07 +01:00
}
fclose ( $handle );
2015-10-15 22:52:37 +10:00
}
}
2015-12-22 19:18:07 +01:00
$tables = array ();
$tables_db = $wpdb -> get_results ( 'SHOW TABLES FROM `' . DB_NAME . '`' , ARRAY_N );
2015-10-15 22:52:37 +10:00
2015-12-22 19:18:07 +01:00
foreach ( $tables_db as $curr_table ) {
// fix for more table prefix in one database
if ( ( strpos ( $curr_table [ 0 ], $wpdb -> prefix ) !== false ) || ( strpos ( $curr_table [ 0 ], $table_prefix ) !== false ) ) {
$tables [] = $curr_table [ 0 ];
2015-10-15 22:52:37 +10:00
}
}
2015-12-22 19:18:07 +01:00
// Replace importance data first so if other replace failed, the website still work
$wpdb -> query ( $wpdb -> prepare ( 'UPDATE ' . $table_prefix . 'options SET option_value = %s WHERE option_name = "siteurl"' , $site_url ) );
$wpdb -> query ( $wpdb -> prepare ( 'UPDATE ' . $table_prefix . 'options SET option_value = %s WHERE option_name = "home"' , $home ) );
// Replace others
$this -> icit_srdb_replacer ( $wpdb -> dbh , $this -> config [ 'home' ], $home , $tables );
$this -> icit_srdb_replacer ( $wpdb -> dbh , $this -> config [ 'siteurl' ], $site_url , $tables );
2015-10-15 22:52:37 +10:00
$wpdb -> query ( 'SET foreign_key_checks = 1' );
return true ;
}
protected function recalculateSerializedLengths ( $pObject ) {
return preg_replace_callback ( '|s:(\d+):"(.*?)";|' , array (
$this ,
'recalculateSerializedLengths_callback' ,
), $pObject );
}
protected function recalculateSerializedLengths_callback ( $matches ) {
return 's:' . strlen ( $matches [ 2 ] ) . ':"' . $matches [ 2 ] . '";' ;
}
/**
* Check value to find if it was serialized .
*
* If $data is not an string , then returned value will always be false .
* Serialized data is always a string .
*
* @ since 2.0 . 5
*
* @ param mixed $data Value to check to see if was serialized .
*
* @ return bool False if not serialized and true if it was .
*/
function is_serialized ( $data ) {
// if it isn't a string, it isn't serialized
if ( ! is_string ( $data ) ) {
return false ;
}
$data = trim ( $data );
if ( 'N;' === $data ) {
return true ;
}
$length = strlen ( $data );
if ( $length < 4 ) {
return false ;
}
if ( ':' !== $data [ 1 ] ) {
return false ;
}
$lastc = $data [ $length - 1 ];
if ( ';' !== $lastc && '}' !== $lastc ) {
return false ;
}
$token = $data [ 0 ];
switch ( $token ) {
2020-03-26 14:05:04 +00:00
case 's' :
2015-10-15 22:52:37 +10:00
if ( '"' !== $data [ $length - 2 ] ) {
return false ;
}
2020-03-26 14:05:04 +00:00
case 'a' :
case 'O' :
2015-10-15 22:52:37 +10:00
return ( bool ) preg_match ( " /^ { $token } :[0-9]+:/s " , $data );
2020-03-26 14:05:04 +00:00
case 'b' :
case 'i' :
case 'd' :
2015-10-15 22:52:37 +10:00
return ( bool ) preg_match ( " /^ { $token } :[0-9.E-]+; \$ / " , $data );
}
return false ;
}
public function cleanUp () {
// Clean up!
2015-12-22 19:18:07 +01:00
$files = glob ( '../dbBackup*.sql' );
foreach ( $files as $file ) {
@ unlink ( $file );
}
2015-10-15 22:52:37 +10:00
}
public function getConfigContents () {
if ( 'extracted' === $this -> file ) {
return file_get_contents ( '../clone/config.txt' );
}
if ( ! $this -> file || ! file_exists ( $this -> file ) ) {
return false ;
}
if ( null !== $this -> archiver ) {
if ( ! $this -> archiver -> isOpen () ) {
$this -> archiver -> read ( $this -> file );
}
$content = $this -> archiver -> getFromName ( 'clone/config.txt' );
return $content ;
} else {
if ( $this -> checkZipConsole () ) {
2020-03-26 20:01:04 +00:00
// todo: implement
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipSupport () ) {
2015-10-15 22:52:37 +10:00
$zip = new ZipArchive ();
$zipRes = $zip -> open ( $this -> file );
if ( $zipRes ) {
$content = $zip -> getFromName ( 'clone/config.txt' );
2020-03-26 20:01:04 +00:00
// $zip->deleteName('clone/config.txt');
// $zip->deleteName('clone/');
2015-10-15 22:52:37 +10:00
$zip -> close ();
return $content ;
}
return false ;
} else {
2020-03-26 20:01:04 +00:00
// use pclzip
2015-10-15 22:52:37 +10:00
$zip = new PclZip ( $this -> file );
$content = $zip -> extract ( PCLZIP_OPT_BY_NAME , 'clone/config.txt' ,
PCLZIP_OPT_EXTRACT_AS_STRING );
if ( ! is_array ( $content ) || ! isset ( $content [ 0 ][ 'content' ] ) ) {
return false ;
}
return $content [ 0 ][ 'content' ];
}
}
return false ;
}
/**
* Extract backup
*
* @ return bool
*/
public function extractBackup () {
if ( ! $this -> file || ! file_exists ( $this -> file ) ) {
return false ;
}
if ( null !== $this -> archiver ) {
if ( ! $this -> archiver -> isOpen () ) {
$this -> archiver -> read ( $this -> file );
}
return $this -> archiver -> extractTo ( ABSPATH );
2020-03-26 14:11:33 +00:00
} elseif ( ( filesize ( $this -> file ) >= 50000000 ) && $this -> checkWPZip () ) {
2015-10-15 22:52:37 +10:00
return $this -> extractWPZipBackup ();
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipConsole () ) {
2015-10-15 22:52:37 +10:00
return $this -> extractZipConsoleBackup ();
2020-03-26 14:11:33 +00:00
} elseif ( $this -> checkZipSupport () ) {
2015-10-15 22:52:37 +10:00
return $this -> extractZipBackup ();
2020-03-26 14:11:33 +00:00
} elseif ( ( filesize ( $this -> file ) < 50000000 ) && $this -> checkWPZip () ) {
2015-10-15 22:52:37 +10:00
return $this -> extractWPZipBackup ();
} else {
return $this -> extractZipPclBackup ();
}
}
/**
* Extract backup using default PHP zip library
*
* @ return bool
*/
public function extractZipBackup () {
$zip = new ZipArchive ();
$zipRes = $zip -> open ( $this -> file );
if ( $zipRes ) {
@ $zip -> extractTo ( ABSPATH );
$zip -> close ();
return true ;
}
return false ;
}
public function extractWPZipBackup () {
MainWP_Helper :: getWPFilesystem ();
global $wp_filesystem ;
$tmpdir = ABSPATH ;
if ( ( 'ftpext' === $wp_filesystem -> method ) && defined ( 'FTP_BASE' ) ) {
$ftpBase = FTP_BASE ;
$ftpBase = trailingslashit ( $ftpBase );
$tmpdir = str_replace ( ABSPATH , $ftpBase , $tmpdir );
}
unzip_file ( $this -> file , $tmpdir );
return true ;
}
public function extractZipPclBackup () {
$zip = new PclZip ( $this -> file );
if ( 0 === $zip -> extract ( PCLZIP_OPT_PATH , ABSPATH , PCLZIP_OPT_REPLACE_NEWER ) ) {
return false ;
}
if ( $zip -> error_code !== PCLZIP_ERR_NO_ERROR ) {
throw new Exception ( $zip -> errorInfo ( true ) );
}
return true ;
}
/**
* Extract backup using zip on console
*
* @ return bool
*/
public function extractZipConsoleBackup () {
2020-03-26 20:01:04 +00:00
// todo implement
// system('zip');
2015-10-15 22:52:37 +10:00
return false ;
}
/**
* Replace define statement to work with wp - config . php
*
* @ param string $constant The constant name
* @ param string $value The new value
* @ param string $content The PHP file content
*
* @ return string Replaced define statement with new value
*/
protected function replaceDefine ( $constant , $value , $content ) {
return preg_replace ( '/(define *\( *[\'"]' . $constant . '[\'"] *, *[\'"])(.*?)([\'"] *\))/is' , '${1}' . $value . '${3}' , $content );
}
/**
* Replace variable value to work with wp - config . php
*
* @ param string $varname The variable name
* @ param string $value The new value
* @ param string $content The PHP file content
*
* @ return string Replaced variable value with new value
*/
protected function replaceVar ( $varname , $value , $content ) {
return preg_replace ( '/(\$' . $varname . ' *= *[\'"])(.*?)([\'"] *;)/is' , '${1}' . $value . '${3}' , $content );
}
function recurse_chmod ( $mypath , $arg ) {
$d = opendir ( $mypath );
while ( ( $file = readdir ( $d ) ) !== false ) {
if ( '.' !== $file && '..' !== $file ) {
$typepath = $mypath . '/' . $file ;
if ( 'dir' === filetype ( $typepath ) ) {
recurse_chmod ( $typepath , $arg );
}
chmod ( $typepath , $arg );
}
}
}
/**
* The main loop triggered in step 5. Up here to keep it out of the way of the
* HTML . This walks every table in the db that was selected in step 3 and then
* walks every row and column replacing all occurences of a string with another .
* We split large tables into 50 , 000 row blocks when dealing with them to save
* on memmory consumption .
*
2020-03-26 14:05:04 +00:00
* @ param mysql $connection The db connection object
2015-10-15 22:52:37 +10:00
* @ param string $search What we want to replace
* @ param string $replace What we want to replace it with .
2020-03-26 14:05:04 +00:00
* @ param array $tables The tables we want to look at .
2015-10-15 22:52:37 +10:00
*
* @ return array Collection of information gathered during the run .
*/
function icit_srdb_replacer ( $connection , $search = '' , $replace = '' , $tables = array () ) {
global $guid , $exclude_cols ;
$report = array (
'tables' => 0 ,
'rows' => 0 ,
'change' => 0 ,
'updates' => 0 ,
'start' => microtime (),
'end' => microtime (),
'errors' => array (),
);
if ( is_array ( $tables ) && ! empty ( $tables ) ) {
foreach ( $tables as $table ) {
$report [ 'tables' ] ++ ;
$columns = array ();
// Get a list of columns in this table
$fields = MainWP_Child_DB :: _query ( 'DESCRIBE ' . $table , $connection );
while ( $column = MainWP_Child_DB :: fetch_array ( $fields ) ) {
$columns [ $column [ 'Field' ] ] = 'PRI' === $column [ 'Key' ] ? true : false ;
}
// Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley
$row_count = MainWP_Child_DB :: _query ( 'SELECT COUNT(*) as count FROM ' . $table , $connection ); // to fix bug
$rows_result = MainWP_Child_DB :: fetch_array ( $row_count );
$row_count = $rows_result [ 'count' ];
if ( 0 === $row_count ) {
continue ;
}
$page_size = 50000 ;
$pages = ceil ( $row_count / $page_size );
for ( $page = 0 ; $page < $pages ; $page ++ ) {
$current_row = 0 ;
$start = $page * $page_size ;
$end = $start + $page_size ;
// Grab the content of the table
$data = MainWP_Child_DB :: _query ( sprintf ( 'SELECT * FROM %s LIMIT %d, %d' , $table , $start , $end ), $connection );
if ( ! $data ) {
$report [ 'errors' ][] = MainWP_Child_DB :: error ();
}
while ( $row = MainWP_Child_DB :: fetch_array ( $data ) ) {
$report [ 'rows' ] ++ ; // Increment the row counter
$current_row ++ ;
$update_sql = array ();
$where_sql = array ();
$upd = false ;
foreach ( $columns as $column => $primary_key ) {
if ( 1 === $guid && in_array ( $column , $exclude_cols ) ) {
continue ;
}
$edited_data = $data_to_fix = $row [ $column ];
// Run a search replace on the data that'll respect the serialisation.
$edited_data = $this -> recursive_unserialize_replace ( $search , $replace , $data_to_fix );
// Something was changed
if ( $edited_data !== $data_to_fix ) {
$report [ 'change' ] ++ ;
$update_sql [] = $column . ' = "' . MainWP_Child_DB :: real_escape_string ( $edited_data ) . '"' ;
$upd = true ;
}
if ( $primary_key ) {
$where_sql [] = $column . ' = "' . MainWP_Child_DB :: real_escape_string ( $data_to_fix ) . '"' ;
}
}
if ( $upd && ! empty ( $where_sql ) ) {
$sql = 'UPDATE ' . $table . ' SET ' . implode ( ', ' , $update_sql ) . ' WHERE ' . implode ( ' AND ' , array_filter ( $where_sql ) );
$result = MainWP_Child_DB :: _query ( $sql , $connection );
if ( ! $result ) {
$report [ 'errors' ][] = MainWP_Child_DB :: error ();
} else {
$report [ 'updates' ] ++ ;
}
} elseif ( $upd ) {
$report [ 'errors' ][] = sprintf ( '"%s" has no primary key, manual change needed on row %s.' , $table , $current_row );
}
}
}
}
}
$report [ 'end' ] = microtime ();
return $report ;
}
/**
* Take a serialised array and unserialise it replacing elements as needed and
* unserialising any subordinate arrays and performing the replace on those too .
*
* @ param string $from String we ' re looking to replace .
* @ param string $to What we want it to be replaced with
* @ param array $data Used to pass any subordinate arrays back to in .
* @ param bool $serialised Does the array passed via $data need serialising .
*
* @ return array The original array with all elements replaced as needed .
*/
2020-03-26 14:05:04 +00:00
2018-02-21 18:38:50 +01:00
/* Fixed serialize issue */
2015-10-15 22:52:37 +10:00
function recursive_unserialize_replace ( $from = '' , $to = '' , $data = '' , $serialised = false ) {
// some unseriliased data cannot be re-serialised eg. SimpleXMLElements
try {
2020-03-26 17:03:00 +00:00
if ( is_string ( $data ) && is_serialized ( $data ) && ! is_serialized_string ( $data ) && ( $unserialized = @ unserialize ( $data ) ) !== false ) {
2015-10-15 22:52:37 +10:00
$data = $this -> recursive_unserialize_replace ( $from , $to , $unserialized , true );
} elseif ( is_array ( $data ) ) {
$_tmp = array ();
foreach ( $data as $key => $value ) {
$_tmp [ $key ] = $this -> recursive_unserialize_replace ( $from , $to , $value , false );
}
$data = $_tmp ;
unset ( $_tmp );
} elseif ( is_object ( $data ) ) {
2020-03-26 19:45:07 +00:00
$_tmp = $data ;
2018-02-21 18:38:50 +01:00
$props = get_object_vars ( $data );
foreach ( $props as $key => $value ) {
2015-10-15 22:52:37 +10:00
$_tmp -> { $key } = $this -> recursive_unserialize_replace ( $from , $to , $value , false );
}
$data = $_tmp ;
unset ( $_tmp );
2020-03-26 17:03:00 +00:00
} elseif ( is_serialized_string ( $data ) && is_serialized ( $data )) {
2018-02-21 18:38:50 +01:00
// TODO: apply solution like phpmyadmin project have!
2020-03-26 15:29:54 +00:00
if ( ( $data = @ unserialize ( $data ) ) !== false ) {
2018-02-21 18:38:50 +01:00
$data = str_replace ( $from , $to , $data );
$data = serialize ( $data );
}
2015-10-15 22:52:37 +10:00
} else {
if ( is_string ( $data ) ) {
$data = str_replace ( $from , $to , $data );
}
}
if ( $serialised ) {
return serialize ( $data );
}
} catch ( Exception $error ) {
}
return $data ;
}
}