وردپرس

Woocommerce product sorting not working as expected


<?php

if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}

class WC_Vote_Price {

private static $instance = null;

public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}

public function __construct() {
add_action( ‘wp_enqueue_scripts’, array( $this, ‘enqueue_scripts’ ) );
add_action( ‘woocommerce_single_product_summary’, array( $this, ‘display_vote_buttons’ ), 25 );
add_action( ‘wp_ajax_wc_vote_price’, array( $this, ‘handle_vote’ ) );
add_action( ‘wp_ajax_nopriv_wc_vote_price’, array( $this, ‘handle_vote’ ) );
add_action( ‘admin_menu’, array( $this, ‘add_settings_page’ ) );
add_action( ‘admin_post_wc_vote_price_reset’, array( $this, ‘handle_reset’ ) );
add_filter( ‘woocommerce_get_price_html’, array( $this, ‘custom_woocommerce_get_price_html’), 10, 2 );
add_action(‘save_post_product’, array($this, ‘handle_product_price_update’), 10, 3);
}

public function handle_product_price_update($post_id, $post, $update) {
if ($post->post_type !== ‘product’) {
return;
}

// Ensure we only run on price updates
if (isset($_POST[‘meta_input’])) {
$meta_input = $_POST[‘meta_input’];
if (isset($meta_input[‘_price’])) {
try {
wc_update_product_lookup_tables();
wc_delete_product_transients(); // Clear WooCommerce product cache

// Forcefully regenerate lookup tables
wc_get_container()->get( \Automattic\WooCommerce\Internal\Product\Lookup\LookupDataStore::class )->regenerate();

} catch (Exception $e) {
error_log(‘Error updating lookup tables: ‘ . $e->getMessage());
}
}
}
}

public function enqueue_scripts() {
wp_enqueue_style( ‘wc-vote-price-style’, plugins_url( ‘../assets/css/style.css’, __FILE__ ) );
wp_enqueue_script( ‘wc-vote-price-script’, plugins_url( ‘../assets/js/script.js’, __FILE__ ), array( ‘jquery’ ), null, true );
wp_localize_script( ‘wc-vote-price-script’, ‘wc_vote_price_params’, array(
‘ajax_url’ => admin_url( ‘admin-ajax.php’ ),
‘nonce’ => wp_create_nonce( ‘wc-vote-price-nonce’ )
) );
}

public function display_vote_buttons() {
global $product;

$votes = get_post_meta( $product->get_id(), ‘_wc_vote_price_votes’, true ) ?: 0;
$downvotes = get_post_meta( $product->get_id(), ‘_wc_vote_price_downvotes’, true ) ?: 0;

$user_ip = $_SERVER[‘REMOTE_ADDR’];
$voted_up = get_post_meta( $product->get_id(), ‘_wc_vote_price_voted_up_’ . $user_ip, true );
$voted_down = get_post_meta( $product->get_id(), ‘_wc_vote_price_voted_down_’ . $user_ip, true );

$upvote_class = $voted_up ? ‘voted’ : ”;
$downvote_class = $voted_down ? ‘voted’ : ”;

echo ‘<div class=”wc-vote-price”>’;
echo ‘<button class=”vote-button ‘ . esc_attr( $upvote_class ) . ‘” data-vote=”up” data-product=”‘ . esc_attr( $product->get_id() ) . ‘”>Vote Up (‘ . esc_html( $votes ) . ‘)</button>’;
echo ‘<button class=”vote-button ‘ . esc_attr( $downvote_class ) . ‘” data-vote=”down” data-product=”‘ . esc_attr( $product->get_id() ) . ‘”>Vote Down (‘ . esc_html( $downvotes ) . ‘)</button>’;
echo ‘</div>’;
echo ‘<div id=”loading-overlay”><div class=”loading-message”>Your vote is being processed<span class=”dots”><span></span><span></span><span></span></span></div></div>’;
}

public function handle_vote() {
check_ajax_referer( ‘wc-vote-price-nonce’, ‘nonce’ );

if ( ! isset( $_POST[‘product_id’], $_POST[‘vote_type’] ) ) {
wp_send_json_error( ‘Invalid data’ );
}

$product_id = absint( $_POST[‘product_id’] );
$vote_type = sanitize_text_field( $_POST[‘vote_type’] );

$user_ip = $_SERVER[‘REMOTE_ADDR’];
$voted_up = get_post_meta( $product_id, ‘_wc_vote_price_voted_up_’ . $user_ip, true );
$voted_down = get_post_meta( $product_id, ‘_wc_vote_price_voted_down_’ . $user_ip, true );

$votes = get_post_meta( $product_id, ‘_wc_vote_price_votes’, true ) ?: 0;
$downvotes = get_post_meta( $product_id, ‘_wc_vote_price_downvotes’, true ) ?: 0;

if ( $vote_type === ‘up’ ) {
if ( $voted_up ) {
$votes–;
delete_post_meta( $product_id, ‘_wc_vote_price_voted_up_’ . $user_ip );
} else {
if ( $voted_down ) {
$downvotes–;
delete_post_meta( $product_id, ‘_wc_vote_price_voted_down_’ . $user_ip );
}
$votes++;
update_post_meta( $product_id, ‘_wc_vote_price_voted_up_’ . $user_ip, true );
}
} elseif ( $vote_type === ‘down’ ) {
if ( $voted_down ) {
$downvotes–;
delete_post_meta( $product_id, ‘_wc_vote_price_voted_down_’ . $user_ip );
} else {
if ( $voted_up ) {
$votes–;
delete_post_meta( $product_id, ‘_wc_vote_price_voted_up_’ . $user_ip );
}
$downvotes++;
update_post_meta( $product_id, ‘_wc_vote_price_voted_down_’ . $user_ip, true );
}
}

update_post_meta( $product_id, ‘_wc_vote_price_votes’, $votes );
update_post_meta( $product_id, ‘_wc_vote_price_downvotes’, $downvotes );

// Trigger price adjustment
$this->adjust_product_prices();
wc_delete_product_transients();

wp_send_json_success( array( ‘votes’ => $votes, ‘downvotes’ => $downvotes ) );
}

private function adjust_product_prices() {
global $wpdb;

// Fetch all products and their votes
$products = $wpdb->get_results(“
SELECT p.ID, COALESCE(v.meta_value, 0) AS votes
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} v ON p.ID = v.post_id AND v.meta_key = ‘_wc_vote_price_votes’
WHERE p.post_type=”product” AND p.post_status=”publish”
ORDER BY votes DESC, p.ID ASC
“);

$max_price = 10000;
$min_price = 1;
$price_range = $max_price – $min_price;
$num_products = count($products);

if ($num_products == 0) {
return; // No products to adjust
}

$rank = 0;
foreach ($products as $product) {
$sale_price = $max_price – ($rank * $price_range / ($num_products – 1));
$sale_price = round($sale_price);
$regular_price = $sale_price + 1;

// Update sale price and regular price
$wpdb->update(
$wpdb->postmeta,
array( ‘meta_value’ => $sale_price ),
array( ‘post_id’ => $product->ID, ‘meta_key’ => ‘_sale_price’ ),
array( ‘%d’ ),
array( ‘%d’, ‘%s’ )
);
$wpdb->update(
$wpdb->postmeta,
array( ‘meta_value’ => $regular_price ),
array( ‘post_id’ => $product->ID, ‘meta_key’ => ‘_regular_price’ ),
array( ‘%d’ ),
array( ‘%d’, ‘%s’ )
);

update_post_meta($product->ID, ‘_price’, $sale_price);
update_post_meta($product->ID, ‘_wc_vote_price_adjusted_price’, $sale_price);
$rank++;

// Logging the price update
error_log(“Updating product ID {$product->ID} to sale price {$sale_price} and regular price {$regular_price}”);
}

wc_delete_product_transients();

// Clear sorting transients
$transients = array(
‘wc_products_onsale’,
‘wc_layered_nav_counts’,
‘wc_products_will_display’,
‘wc_hidden_term_ids’
);

foreach ( $transients as $transient ) {
delete_transient( $transient );
}

// Ensure the class exists before regenerating lookup tables
if (class_exists(‘Automattic\WooCommerce\Internal\Product\Lookup\LookupDataStore’)) {
try {
wc_get_container()->get( \Automattic\WooCommerce\Internal\Product\Lookup\LookupDataStore::class )->regenerate();
} catch (Exception $e) {
error_log(‘Error regenerating lookup tables: ‘ . $e->getMessage());
}
} else {
error_log(‘LookupDataStore class does not exist.’);
}
}

public function custom_woocommerce_get_price_html($price, $product) {
$adjusted_price = get_post_meta($product->get_id(), ‘_wc_vote_price_adjusted_price’, true);
if ($adjusted_price) {
$price = wc_price($adjusted_price);
}
return $price;
}

public function add_settings_page() {
add_menu_page(
‘WC Vote Price Settings’,
‘Vote Price’,
‘manage_options’,
‘wc-vote-price’,
array( $this, ‘settings_page_content’ ),
‘dashicons-thumbs-up’,
56
);
}

public function settings_page_content() {
?>
<div class=”wrap”>
<h1>Vote Price Settings</h1>
<form action=”admin-post.php” method=”post”>
<input type=”hidden” name=”action” value=”wc_vote_price_reset”>
<button type=”submit” class=”button button-primary”>Reset All Votes</button>
</form>
</div>
<?php
}

public function handle_reset() {
if ( ! current_user_can( ‘manage_options’ ) ) {
return;
}

global $wpdb;

$wpdb->query(“
DELETE FROM {$wpdb->postmeta}
WHERE meta_key IN (‘_wc_vote_price_votes’, ‘_wc_vote_price_downvotes’)
“);

$wpdb->query(“
DELETE FROM {$wpdb->postmeta}
WHERE meta_key LIKE ‘_wc_vote_price_voted_%’
“);

// Reset prices
$this->adjust_product_prices();

// Redirect back to the settings page
wp_redirect( admin_url( ‘admin.php?page=wc-vote-price&reset=true’ ) );
exit;
}
}

WC_Vote_Price::instance();

?>

این خبر را در ایران وب سازان مرجع وب و فناوری دنبال کنید

مشاهده پاسخ های این مطلب
———————————————
این مطلب از سایت انجمن وردپرس گردآوری شده است و کلیه حقوق مطلق به انجمن وردپرس می باشد در صورت مغایرت و یا بروز مشکل اطلاع دهید تا حذف گردد

منبع: انجمن وردپرس

دکمه بازگشت به بالا