<?php
/*Plugin Name: Product data content processing
Description: If there is data from the original website in the product title and description, use this plug-in to process it (new version features: added product details, a new modal window for product pictures, and a shortcut for hiding other shipping costs for the product) Buttons and product descriptions are de-hyperlinked)
Version: 2.3.4
Author: Dora*/
if (!defined('ABSPATH')) {
exit; //If accessed directly, exit
}
class ContentReplacer {
public function __construct() {
//Add backend menu
add_action('admin_menu', array($this, 'add_admin_menu'));
//Handle form submission
add_action('admin_post_replace_content', array($this, 'handle_form_submission'));
//Handle rollback
add_action('admin_post_rollback_content', array($this, 'handle_rollback'));
//Handle form submission for free shipping hidden button
add_action('admin_post_toggle_shipping', array($this, 'handle_toggle_shipping'));
//Handle form submission for product modal button
add_action('admin_post_toggle_modal', array($this, 'handle_toggle_modal'));
add_action('admin_post_toggle_hyperlink', array($this, 'handle_toggle_hyperlink'));
add_action('admin_post_close_hyperlink', array($this, 'handle_close_hyperlink'));
//AJAX handling of checking shortcode status
add_action('wp_ajax_check_shortcode_status', array($this, 'check_shortcode_status'));
//Add styles and scripts
add_action('admin_enqueue_scripts', array($this, 'enqueue_styles'));
}
//Add background menu items
public function add_admin_menu() {
add_menu_page(
'Product data content processing', //Page title
'Product data content processing', //menu title
'manage_options', //Permissions
'content-replacer', //Menu alias
array($this, 'create_admin_page'), //Callback function for page content
'dashicons-admin-tools' //icon
);
}
public function enqueue_styles() {
wp_enqueue_style('content-replacer-styles', plugins_url('', __FILE__));
wp_enqueue_script('content-replacer-scripts', plugins_url('', __FILE__), array('jquery'), null, true);
wp_add_inline_style('content-replacer-styles', '
#adminmenu .toplevel_page_content-replacer .wp-menu-image:before {
content: "";
display: inline-block;
width: 20px;
height: 20px;
background-image: url(' . plugins_url('img/', __FILE__) . ');
background-size: cover;
}
');
}
//Create backend page
public function create_admin_page() {
?>
<div class="wrap content-replacer-container">
<h1>Product data content processing</h1>
<form method="post" action="<?php echo admin_url(''); ?>" id="content-replacer-form">
<input type="hidden" name="action" value="replace_content">
<?php wp_nonce_field('replace_content_nonce', 'replace_content_nonce_field'); ?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label for="original_text">Original content</label></th>
<td><input type="text" id="original_text" name="original_text" required /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="new_text">New content</label></th>
<td><input type="text" id="new_text" name="new_text" required /></td>
</tr>
</table>
<p class="submit"><input type="submit" class="button-primary" value="Replace content" /></p>
<div id="loading" class="loading">Processing, please wait...</div>
<divclass="progress-bar" id="progress-bar">
<div class="progress-bar-inner" id="progress-bar-inner"></div>
</div>
</form>
<h2>Replacement History</h2>
<ul>
<?php
$history = get_option('content_replacer_history', array());
if (empty($history)) {
echo '<li>No substitutions have been made. </li>';
} else {
$history_by_date = [];
foreach ($history as $entry) {
$date = date('Y-m-d H:i:s', strtotime($entry['date']));
if (!isset($history_by_date[$date])) {
$history_by_date[$date] = ['entries' => [], 'count' => 0];
}
$history_by_date[$date]['entries'][] = '"' . esc_html($entry['original_text']) . '" Replace with "' . esc_html($entry['new_text']) . '"';
$history_by_date[$date]['count'] += $entry['replacements'];
}
foreach ($history_by_date as $date => $data) {
$entries = array_unique($data['entries']); //remove duplicates
echo '<li>';
echo 'At' . esc_html($date) . 'replace:';
echo implode(', ', $entries);
echo 'common' . $data['count'] . 'Change everywhere';
echo ' <a href="' . wp_nonce_url(admin_url('?action=rollback_content&date=' . urlencode($date)), 'rollback_content_nonce', 'rollback_content_nonce_field') . '">Rollback</a>';
echo '</li>';
}
}
?>
</ul>
</div>
<div class="wrap content-replacer-container">
<!-- New button: Free shipping hidden -->
<form method="post" action="<?php echo admin_url(''); ?>" id="shipping-toggle-form">
<input type="hidden" name="action" value="toggle_shipping">
<?php wp_nonce_field('toggle_shipping_nonce', 'toggle_shipping_nonce_field'); ?>
<p class="submit"><input type="submit" class="button-primary" id="toggle-shipping-button" value="free shipping hidden"/></p>
</form>
<!-- New button: Product modal window -->
<form method="post" action="<?php echo admin_url(''); ?>" id="modal-toggle-form">
<input type="hidden" name="action" value="toggle_modal">
<?php wp_nonce_field('toggle_modal_nonce', 'toggle_modal_nonce_field'); ?>
<p class="submit"><input type="submit" class="button-primary" id="toggle-modal-button" value="Product modal window"/></p>
</form>
<!-- New button: Go to product hyperlink -->
<form method="post" action="<?php echo admin_url(''); ?>" id="hyperlink-toggle-form">
<input type="hidden" name="action" value="toggle_hyperlink">
<?php wp_nonce_field('toggle_hyperlink_nonce', 'toggle_hyperlink_nonce_field'); ?>
<p class="submit"><input type="submit" class="button-primary" id="toggle-hyperlink-button" value="Checking..."/></p>
</form>
<!-- New button: Turn off the description hyperlink function -->
<form method="post" action="<?php echo admin_url(''); ?>" id="hyperlink-close-form" style="display:none;">
<input type="hidden" name="action" value="close_hyperlink">
<?php wp_nonce_field('close_hyperlink_nonce', 'close_hyperlink_nonce_field'); ?>
<p class="submit"><input type="submit" class="button-primary" id="close-hyperlink-button" value="Turn off the description hyperlink function" /></p>
</form>
</div>
<script>
jQuery(document).ready(function($) {
$('#content-replacer-form').on('submit', function() {
$('#loading').hide();
$('#progress-bar').show();
var progressBar = $('#progress-bar-inner');
var width = 0;
var interval = setInterval(function() {
if (width >= 100) {
clearInterval(interval);
$('#progress-bar').hide();
} else {
width += 1; //Increase the step size of progress
('width', width + '%');
(width + '%');
}
}, 50); //Simulation progress, gradually increasing
});
//Hide other plug-in prompts
$('.notice, .update-nag, .updated, .error, .is-dismissible').not('.content-replacer-container .notice').hide();
//Check if there are relevant shortcodes in
$.ajax({
url: ajaxurl,
data: {
'action': 'check_shortcode_status'
},
success: function(response) {
if (response.shipping_hidden) {
$('#toggle-shipping-button').val('Other shipping charges are hidden');
}
if (response.modal_enabled) {
$('#toggle-modal-button').val('Product image modal window has been opened');
}
if (response.hyperlinks_exist) {
$('#toggle-hyperlink-button').val('There is a hyperlink in the description, click to remove it').css({
'background-color': '#ff6666',
'color': '#f5f5dc'
}).prop('disabled', false);
} else {
$('#toggle-hyperlink-button').val('There is no link to the product, no need to click this button').css({
'background-color': '#add8e6',
'color': '#ffffff'
}).prop('disabled', true);
}
}
});
//When the remove hyperlink button is clicked
$('#hyperlink-toggle-form').on('submit', function() {
$('#toggle-hyperlink-button').val('The hyperlink has been removed, no need to click this button').prop('disabled', true);
$('#close-hyperlink-button').parent().show();
});
//When the close hyperlink function button is clicked
$('#hyperlink-close-form').on('submit', function() {
$('#toggle-hyperlink-button').val('There is a hyperlink in the description, click to remove it').prop('disabled', false);
$('#close-hyperlink-button').parent().hide();
});
});
</script>
<?php
}
//Handle form submission
public function handle_form_submission() {
if (!isset($_POST['replace_content_nonce_field']) || !wp_verify_nonce($_POST['replace_content_nonce_field'], 'replace_content_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$original_text = sanitize_text_field($_POST['original_text']);
$new_text = sanitize_text_field($_POST['new_text']);
global $wpdb;
//Get all products
$products = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt FROM {$wpdb->posts} WHERE post_type = 'product'");
//Save original data before replacement
$history = get_option('content_replacer_history', array());
$total_replacements = 0;
foreach ($products as $product) {
$original_data = array(
'ID' => $product->ID,
'post_title' => $product->post_title,
'post_content' => $product->post_content,
'post_excerpt' => $product->post_excerpt,
);
$title_replacements = substr_count($product->post_title, $original_text);
$content_replacements = substr_count($product->post_content, $original_text);
$excerpt_replacements = substr_count($product->post_excerpt, $original_text);
$total_replacements += $title_replacements + $content_replacements + $excerpt_replacements;
$history_entry = array(
'date' => current_time('mysql'),
'original_text' => $original_text,
'new_text' => $new_text,
'data' => $original_data,
'replacements' => $total_replacements,
);
array_unshift($history, $history_entry); //Add to the beginning of the array
}
update_option('content_replacer_history', $history);
//Perform replacement
foreach ($products as $product) {
$updated_post = array(
'ID' => $product->ID,
'post_title' => str_replace($original_text, $new_text, $product->post_title),
'post_content' => str_replace($original_text, $new_text, $product->post_content),
'post_excerpt' => str_replace($original_text, $new_text, $product->post_excerpt),
);
$wpdb->update(
$wpdb->posts,
$updated_post,
array('ID' => $product->ID)
);
}
wp_redirect(admin_url('?page=content-replacer'));
exit;
}
//Handle rollback operations
public function handle_rollback() {
if (!isset($_GET['rollback_content_nonce_field']) || !wp_verify_nonce($_GET['rollback_content_nonce_field'], 'rollback_content_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$date = urldecode($_GET['date']);
$history = get_option('content_replacer_history', array());
//Filter out history records for a specified date
$entries_to_rollback = array_filter($history, function($entry) use ($date) {
return date('Y-m-d H:i:s', strtotime($entry['date'])) === $date;
});
if (!empty($entries_to_rollback)) {
global $wpdb;
foreach ($entries_to_rollback as $entry) {
$original_data = $entry['data'];
$wpdb->update(
$wpdb->posts,
array(
'post_title' => $original_data['post_title'],
'post_content' => $original_data['post_content'],
'post_excerpt' => $original_data['post_excerpt'],
),
array('ID' => $original_data['ID'])
);
}
//Remove rolled back history
$history = array_filter($history, function($entry) use ($date) {
return date('Y-m-d H:i:s', strtotime($entry['date'])) !== $date;
});
update_option('content_replacer_history', $history);
wp_redirect(admin_url('?page=content-replacer'));
exit;
} else {
wp_die('Invalid history date');
}
}
//Handle form submission for free shipping hidden button
public function handle_toggle_shipping() {
if (!isset($_POST['toggle_shipping_nonce_field']) || !wp_verify_nonce($_POST['toggle_shipping_nonce_field'], 'toggle_shipping_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$function_code = "
function js_hide_all_shipping_when_free_is_available( \$shipping_rates ) {
foreach ( \$shipping_rates as \$key => \$rate ) {
if ( \$rate->get_method_id() == 'free_shipping' ) {
\$shipping_rates = array( \$key => \$rate );
}
}
return \$shipping_rates;
}
add_filter( 'woocommerce_package_rates', 'js_hide_all_shipping_when_free_is_available' );
";
$functions_path = get_template_directory() . '/';
$functions_content = file_get_contents($functions_path);
if (strpos($functions_content, 'js_hide_all_shipping_when_free_is_available') === false) {
file_put_contents($functions_path, $functions_content . PHP_EOL . $function_code);
} else {
$functions_content = str_replace($function_code, '', $functions_content);
file_put_contents($functions_path, $functions_content);
}
wp_redirect(admin_url('?page=content-replacer'));
exit;
}
//Handle form submission for product modal button
public function handle_toggle_modal() {
if (!isset($_POST['toggle_modal_nonce_field']) || !wp_verify_nonce($_POST['toggle_modal_nonce_field'], 'toggle_modal_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$function_code = "
function theme_enqueue_scripts_and_styles() {
wp_enqueue_style('custom-style', get_stylesheet_directory_uri() . '/css/');
wp_enqueue_script('custom-script', get_template_directory_uri() . '/js/', array('jquery'), null, true);
\$inline_script = \"jQuery(document).ready(function($) {
\$('body').append('<div id=\\\"myModal\\\" class=\\\"modal\\\"><span class=\\\"close\\\">×</span><img class=\\\"modal-content\\\" id=\\\"img01\\\"></div>');
var modal_css = '<style>\
.modal {display: none; position: fixed; z-index: 1000; padding-top: 100px; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.9);}\
.modal-content {margin: auto; display: block; max-width: 40%; transition: transform 0.3s;}\
.close {position: absolute; top: 15px; right: 35px; color: white; font-size: 40px; font-weight: bold; cursor: pointer;}\
</style>';
\$('head').append(modal_css);
var isZoomed = false;
\$('.woocommerce-product-gallery__image a').click(function(event) {
event.preventDefault();
var imgSrc = \$(this).find('img').attr('src');
\$('#img01').attr('src', imgSrc);
\$('#myModal').css('display', 'block');
isZoomed = false;
\$('#img01').css('transform', 'scale(1)');
});
\$('.close, .modal').on('click', function(event) {
if (event.target !== this) return;
\$('#myModal').css('display', 'none');
});
\$('#img01').on('dblclick', function() {
if (isZoomed) {
\$(this).css('transform', 'scale(1)');
isZoomed = false;
} else {
\$(this).css('transform', 'scale(2)');
isZoomed = true;
}
});
});
\";
wp_add_inline_script('custom-script', \$inline_script);
}
add_action('wp_enqueue_scripts', 'theme_enqueue_scripts_and_styles');
";
$functions_path = get_template_directory() . '/';
$functions_content = file_get_contents($functions_path);
if (strpos($functions_content, 'theme_enqueue_scripts_and_styles') === false) {
file_put_contents($functions_path, $functions_content . PHP_EOL . $function_code);
} else {
$functions_content = str_replace($function_code, '', $functions_content);
file_put_contents($functions_path, $functions_content);
}
wp_redirect(admin_url('?page=content-replacer'));
exit;
}
//Handle form submission to product hyperlink button
public function handle_toggle_hyperlink() {
if (!isset($_POST['toggle_hyperlink_nonce_field']) || !wp_verify_nonce($_POST['toggle_hyperlink_nonce_field'], 'toggle_hyperlink_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$function_code = "
function remove_product_hyperlinks(\$content) {
if (is_product()) {
\$content = preg_replace('/<a href=\".*?\">(.*?)<\/a>/', '\$1', \$content);
}
return \$content;
}
add_filter('the_content', 'remove_product_hyperlinks');
";
$functions_path = get_template_directory() . '/';
$functions_content = file_get_contents($functions_path);
if (strpos($functions_content, 'remove_product_hyperlinks') === false) {
file_put_contents($functions_path, $functions_content . PHP_EOL . $function_code);
}
wp_redirect(admin_url('?page=content-replacer'));
exit;
}
//Handle form submission that closes hyperlink removal button
public function handle_close_hyperlink() {
if (!isset($_POST['close_hyperlink_nonce_field']) || !wp_verify_nonce($_POST['close_hyperlink_nonce_field'], 'close_hyperlink_nonce')) {
wp_die('Nonce verification failed');
}
if (!current_user_can('manage_options')) {
wp_die('No permission');
}
$functions_path = get_template_directory() . '/';
$functions_content = file_get_contents($functions_path);
$function_code = "
function remove_product_hyperlinks(\$content) {
if (is_product()) {
\$content = preg_replace('/<a href=\".*?\">(.*?)<\/a>/', '\$1', \$content);
}
return \$content;
}
add_filter('the_content', 'remove_product_hyperlinks');
";
if (strpos($functions_content, 'remove_product_hyperlinks') !== false) {
$functions_content = str_replace($function_code, '', $functions_content);
file_put_contents($functions_path, $functions_content);
}
wp_redirect(admin_url('?page=content-replacer'));
exit;
}
//Added AJAX processing function to detect shortcode status//Added AJAX processing function to detect hyperlink status in product descriptions
public function check_shortcode_status() {
$functions_path = get_template_directory() . '/';
$functions_content = file_get_contents($functions_path);
$response = array(
'shipping_hidden' => strpos($functions_content, 'js_hide_all_shipping_when_free_is_available') !== false,
'modal_enabled' => strpos($functions_content, 'theme_enqueue_scripts_and_styles') !== false,
'hyperlinks_exist' => false
);
global $wpdb;
$products = $wpdb->get_results("SELECT post_content FROM {$wpdb->posts} WHERE post_type = 'product'");
foreach ($products as $product) {
if (preg_match('/<a href=\".*?\">/', $product->post_content)) {
$response['hyperlinks_exist'] = true;
break;
}
}
wp_send_json($response);
}
}
//Instantiate plugin class
new ContentReplacer();