File "search-replace.php"

Full path: /home/bud/public_html/swamp/wp-admin/wp-content/plugins/backup-backup/includes/database/search-replace.php
File size: 3.86 KB
MIME-type: text/x-php
Charset: utf-8

<?php

/**
 * Modifications by: MikoĊ‚aj `iClyde` Chodorowski
 * Modified by e-mail contact: kontakt@iclyde.pl
 * Package: Safe Search and Replace on Database with Serialized Data v2.0.1
 *
 * Please contact above e-mail if you see any credits problem.
 */

// Namespace
namespace BMI\Plugin\Database;

// Use
use BMI\Plugin\BMI_Logger AS Logger;
use BMI\Plugin\Backup_Migration_Plugin as BMP;
use BMI\Plugin\Progress\BMI_ZipProgress AS Progress;

// Exit on direct access
if (!defined('ABSPATH')) exit;

/**
 * Database Search and Replace for Enginge v3
 */
class BMI_Search_Replace_Engine {

  function __construct($tables) {

  	$this->all_tables = $tables;

  }

  public function perform($search, $replace) {

    return $this->search_replace($search, $replace, $this->all_tables);

  }

  private function recursive_unserialize_replace($from = '', $to = '', $data = '', $serialised = false) {

  	try {

  		if (is_string($data) && ($unserialized = @unserialize($data)) !== false) {

  			$data = $this->recursive_unserialize_replace($from, $to, $unserialized, true);

  		} elseif (is_array($data)) {

  			$_tmp = [];
  			foreach ($data as $key => $value) {
  				$_tmp[$key] = $this->recursive_unserialize_replace($from, $to, $value, false);
  			}

  			$data = $_tmp;
  			unset($_tmp);

  		} else if (is_string($data)) $data = str_replace($from, $to, $data);

  		if ($serialised) return serialize($data);

  	}
    catch (\Exception $error) {}
    catch (\Throwable $error) {}

  	return $data;

  }

  private function search_replace($search = '', $replace = '', $tables = []) {

    global $wpdb;

    $excluded_columns = ['guid', 'id', 'ID'];
  	$report = ['tables' => 0, 'rows' => 0, 'change' => 0, 'updates' => 0];

  	if (is_array($tables) && !empty($tables)) {

      $wpdb->show_errors();

  		foreach($tables as $table) {

  			$report['tables']++;
  			$columns = [];

		    $fields = $wpdb->get_results('DESCRIBE ' . $table);
        foreach ($fields as $index => $object) {
          $columns[$object->Field] = $object->Key == 'PRI' ? true : false;
        }

        $row_count = $wpdb->get_results('SELECT COUNT(*) AS num FROM ' . $table);
        $row_count = $row_count[0]->num;
        if ($row_count == 0) continue;

  			$page_size = 1000;
  			$pages = ceil($row_count / $page_size);

  			for ($page = 0; $page < $pages; $page++) {

  				$current_row = 0;
  				$start = $page * $page_size;
  				$end = $start + $page_size;

          $data = $wpdb->get_results(sprintf('SELECT * FROM %s LIMIT %d, %d', $table, $start, $end));
          for ($i = 0; $i < sizeof($data); ++$i) {

            $row = $data[$i];
            $report['rows']++;
            $current_row++;

            $update_sql = [];
            $where_sql = [];
            $upd = false;

            foreach ($columns as $column => $primary_key) {

              if (in_array($column, $excluded_columns)) continue;

              $edited_data = $data_to_fix = $row->$column;
              $edited_data = $this->recursive_unserialize_replace($search, $replace, $data_to_fix);

              if ($edited_data != $data_to_fix) {
  							$report['change']++;
  							$update_sql[] = $column . ' = "' . mysqli_real_escape_string($wpdb->dbh, $edited_data) . '"';
  							$upd = true;
                $where_sql[] = $column . ' = "' . mysqli_real_escape_string($wpdb->dbh, $data_to_fix) . '"';
  						}

            }

            if ($upd && !empty($where_sql)) {
              $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $update_sql) . ' WHERE ' . implode(' AND ', array_filter($where_sql));
              $wpdb->query($sql);
              $report['updates']++;

              if ($wpdb->last_error !== '') {
                error_log($wpdb->last_query);
                error_log($wpdb->last_result);
                error_log($wpdb->last_error);
              }
            }

          }

  			}

  		}

  	}

  	return $report;
  }

}