0
votes

I have a jQuery script which successfully retrieves data from local storage and then returns to a PHP function (within a child theme). Within this function I have an if/else block which I want to use in order to change all buttons on all shop pages and linked product pages when opened. depending on the result obtained from the jQuery script.

There are 3 options : default "check coverage", standard "add to cart" and finally "register your interest"

I have 3 categories and want to exclude the 'hardware category

How can I apply a filter to all product pages matching a tag? The code below applies this to all the shop pages items on the store, but not the linked product page for the current customer without overwriting other customers views.

add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );
function replacing_add_to_cart_button( $button, $product  ) {
    $button_text = __("Check Coverage", "woocommerce");
    $button = '<a class="button" href="******/coverage">' . $button_text . '</a>';
    return $button;
}

Any guidance, criticisms or thoughts are appreciated.


EDIT - The Ajax code that I use:

jQuery script enqueued from functions.php in child theme:

jQuery.ajax({
    type: "POST",
    url: "/wp-admin/admin-ajax.php",
    data: {
        action: 'dynamic_product_links',
        // add your parameters here
        cat1: localStorage.getItem("cat1"),
        cat2: localStorage.getItem("cat2"),          
    },
    success: function (output) {
        console.log(output);
    }
});

functions.php

add_action('wp_enqueue_scripts', 'woocommerce_ajax_check_coverage_js', 99);
function woocommerce_ajax_check_coverage_js(){

    //echo "<script type='text/javascript'>alert('called woocommerce_ajax_check_coverage_js ');</script>";
    wp_register_script( 'woocommerce-ajax-check-coverage-js', get_stylesheet_directory_uri() . "/assets/ajax-check-coverage.js", array('jquery'), null, true );
    wp_enqueue_script('woocommerce-ajax-check-coverage-js');
}

// register the ajax action for authenticated users
add_action('wp_ajax_dynamic_product_links', 'dynamic_product_links');

// register the ajax action for unauthenticated users
add_action('wp_ajax_nopriv_dynamic_product_links', 'dynamic_product_links');
function dynamic_product_links() {
    // ajax data received from jQuery script which retrieves data from local storage
    $cat1_speed = $_REQUEST['cat1']; // can be either 'Check Coverage','No Coverage' or a number linked to  a custom atttribute
    $cat2_speed = $_REQUEST['cat2'];

    if ($cat1_speed == 'check ooverage' || $cat2_speed == 'check coverage') {
        // set all matching categories except hardware to check coverage
    }
    if ($cat1_speed == 'No Coverage' ) {
        // remove this catogory item set from the store (hide?) -> change any product/* pages add to cart button to "register your interest"
    }
    if ($cat1_speed == '20' || $cat2_speed == 'check coverage') {
        // remove this catogory item set from the store (hide?) if the products atttribute is greater than the number
    }

    // in the end, returns success json data
    wp_send_json_success([/* some data here */$wireless_speed ,$fusion_fibre_speed]);

    // or, on error, return error json data
    wp_send_json_error([/* some data here */]);
}
1
Thank you Yes since hardware category must always use the default add to cart behaviour. The rest of the products I want to change based on the underlying attribute which is a number or text. If local storage category value is 'check coverage' then I want to update those category items to 'Check Coverage' otherwise the value willl be a number in which case I want to apply a filter to the store to remove options which don't match the number. I need to apply to both the store and product views because otherwise custom can still add to cart through quick view.Johnathan Enslin

1 Answers

1
votes

To exclude product categories, try use one of the following:

1). Direct product categories handling (no parent terms):

add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );
function replacing_add_to_cart_button( $button, $product  ) {
    if( ! has_term( array('hardware'), 'product_cat', $product->get_id() ) ) {
        $button_text = __("Check Coverage", "woocommerce");
        $button = '<a class="button" href="******/coverage">' . $button_text . '</a>';
    }
    return $button;
}

2). Product categories handling (and parent terms too):

add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );
function replacing_add_to_cart_button( $button, $product  ) {
    if( ! has_product_categories( $product->get_id(), array('hardware') ) ) {
        $button_text = __("Check Coverage", "woocommerce");
        $button = '<a class="button" href="******/coverage">' . $button_text . '</a>';
    }
    return $button;
}

// Custom conditional function that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
    $parent_term_ids = $categories_ids = array(); // Initializing
    $taxonomy        = 'product_cat';
    $product_id      = $product_id == 0 ? get_the_id() : $product_id;

    if( is_string( $categories ) ) {
        $categories = (array) $categories; // Convert string to array
    }

    // Convert categories term names and slugs to categories term ids
    foreach ( $categories as $category ){
        $result = (array) term_exists( $category, $taxonomy );
        if ( ! empty( $result ) ) {
            $categories_ids[] = reset($result);
        }
    }

    // Loop through the current product category terms to get only parent main category term
    foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
        if( $term->parent > 0 ){
            $parent_term_ids[] = $term->parent; // Set the parent product category
            $parent_term_ids[] = $term->term_id; // (and the child)
        } else {
            $parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
        }
    }
    return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.