I'm trying to create a remove action for the woocommerce points and rewards plugin but I cannot get it to work.
I haven't tried to remove an action that's like this before so any help would be appreciated :)
Thank you for reading
My remove_action is :
remove_action( 'woocommerce_before_add_to_cart_button', 'add_variation_message_to_product_summary', 25 );
The original add_actions in their class:
class WC_Points_Rewards_Product {
/**
* Add product-related hooks / filters
*
* #since 1.0
*/
public function __construct() {
// add single product message immediately after product excerpt
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'render_product_message' ), 15 );
// add variation message before the price is displayed
add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_variation_message_to_product_summary' ), 25 );
// add the points message just before the variation price.
add_filter( 'woocommerce_variation_price_html', array( $this, 'render_variation_m
essage' ), 10, 2 );
add_filter( 'woocommerce_variation_sale_price_html', array( $this, 'render_variation_message' ), 10, 2 );
add_filter( 'woocommerce_available_variation', array( $this, 'render_available_variation_message' ), 10, 3 );
add_filter( 'woocommerce_show_variation_price', '__return_true' );
// delete transients
add_action( 'woocommerce_delete_product_transients', array( $this, 'delete_transients' ) );
}
and the function which im trying to remove:
/**
* Add a message about the points to the product summary
*
* #since 1.2.6
*/
public function add_variation_message_to_product_summary() {
global $product;
// make sure the product has variations (otherwise it's probably a simple product)
if ( method_exists( $product, 'get_available_variations' ) ) {
// get variations
$variations = $product->get_available_variations();
// find the variation with the most points
$points = $this->get_highest_points_variation( $variations, $product->get_id() );
$message = '';
// if we have a points value let's create a message; other wise don't print anything
if ( $points ) {
$message = $this->create_variation_message_to_product_summary( $points );
}
echo $message;
}
}
EDIT
I forgot to mention that if you comment out this then the info im trying to remove is actually removed.
//add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'add_variation_message_to_product_summary' ), 25 );
Additional info
I didn't mention this before because i thought it would only bloat the question but the goal is to remove it from where it is (before add to cart) and add it back in under the price, so effectively moving it up the page.
I didn't include this before as i thought it would be a simple remove add action.
add_filter( 'wc_points_rewards_single_product_message',
'remove_rewards_earn_points_message_single', 15, 2 );
function remove_rewards_earn_points_message_single( $message, $data ) {
if( is_product() )
return '';
return $message;
}
Can be removed by this, but i don`t know how to add it back to another location (
Related
Based on Customize “subsription option” string generated by WooCommerce Subscribe All The Things plugin answer code, this is my attempt:
function filter_wcsatt_single_product_subscription_option_description(
$option_description, $sub_price_html, $has_price_filter, $force_subscription, $product, $subscription_scheme ) {
// Class
$option_price_class = 'subscription-option';
// New description
$option_description = '<span>Subscription: </span>
<span>' . $sub_price_html . '</span>';
return $option_description;
}
add_filter( 'wcsatt_single_product_subscription_option_description', 'filter_wcsatt_single_product_subscription_option_description', 10, 6 );
Any advice?
This should suffice, basically anything you assign to the $none_string variable will be displayed
function filter_wcsatt_single_product_one_time_option_description( $none_string, $product ) {
$none_string = $product->get_price_html();
return $none_string;
}
add_filter( 'wcsatt_single_product_one_time_option_description', 'filter_wcsatt_single_product_one_time_option_description', 10, 2 );
The main price above "choose a purchase plan" is added by WooCommerce, and not by the WCSATT plugin. So to hide it, you can use:
function filter_woocommerce_available_variation( $data, $product, $variation ) {
$data['price_html'] = '';
return $data;
}
add_filter( 'woocommerce_available_variation', 'filter_woocommerce_available_variation', 10, 3 );
I'm trying to send a custom email when a post is published using the Woocommerce email template.
I have included the template and class which Woocommerce loads using the woocommerce_email_classes and have also registered the custom action send_entry_list in the woocommerce_email_actions filter.
do_action('send_entry_list', $competition_id, $entry_list_url);
When adding add_action to this within the class-entry-list-email.php which triggers the email, it's not printing out 'triggered' in the debug.log file.
Does anyone know why this isn't firing?
public function __construct() {
add_action( 'send_entry_list', array( $this, 'trigger' ) );
}
public function trigger( $competition_id, $entry_list_url ) {
error_log(print_r('triggered', true));
}
add_filter( 'woocommerce_email_classes', array($this, 'add_draw_number_email'));
function add_draw_number_email( $email_classes ) {
// include our custom email class
require( 'includes/class-entry-list-email.php' );
// add the email class to the list of email classes that WooCommerce loads
$email_classes['Entry_List_Email'] = new Entry_List_Email();
return $email_classes;
}
add_filter( 'woocommerce_email_actions', array($this, 'crwc_register_custom_order_status_action'));
function crwc_register_custom_order_status_action( $actions ) {
$actions[] = 'send_entry_list';
return $actions;
}
Actually, you are missing _notification in the add_action hook. In WooCommerce email, you need to add _notification in the tag name of do_action.
In your case, you are using send_entry_list in both do_action and add_action whereas in add_action you just need to append _notification in the tag name so hook name becomes send_entry_list_notification.
To make this easy for you just do the following change.
Replace this line:
add_action( 'send_entry_list', array( $this, 'trigger' ) );
with this:
add_action( 'send_entry_list_notification', array( $this, 'trigger' ), 10, 2 );
Hope, it works for you.
Change hook as below and try,
add_action( 'send_entry_list', array( $this, 'trigger' ), 10, 2 );
I have an issue how to remove a cart from a category product. It works just fine if I apply it to a specific id or all in general, but I am unable to do it for a category. Below is my code I have done regarding it.
Also, I am struggling to apply this same pattern to Related Articles section, so any help would be appreciated.
Thank you.
//function for deleting ....
function remove_product_description_add_cart_button(){
global $product;
//Remove Add to Cart button from product description of product with id 1234
if ($product->id == 188){
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
add_action('wp','remove_product_description_add_cart_button');
}
Nov 2020 Update
To make it work with a product category you can use the WordPress conditional function has_term() this way:
add_action('woocommerce_single_product_summary', 'remove_product_description_add_cart_button', 1 );
function remove_product_description_add_cart_button() { // function for deleting ...
// Set HERE your category ID, slug or name (or an array)
$categories = array('your-category-1');
//Remove Add to Cart button from product description of product with id 1234
if ( has_term( $categories, 'product_cat', get_the_id() ) ) {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}
Code goes in function.php file of your active child theme (or active theme). Or also in any plugin php file. Tested and works.
You can try something like this
function western_custom_buy_buttons(){
$product = get_product();
if ( has_term( 'category1', 'product_cat') ){
// removing the purchase buttons
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
remove_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
remove_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
}
}
add_action( 'wp', 'western_custom_buy_buttons' );
Reference : https://www.themelocation.com/how-to-remove-add-to-cart-button-from-a-certain-category-woocommerce/
you can add your own category name in line 3
add_filter('woocommerce_is_purchasable', 'set_catalog_mode_on_for_category', 10, 2 );
function set_catalog_mode_on_for_category( $is_purchasable, $product ) {
if( has_term( 'Category Name', 'product_cat', $product->get_id() ) ) { //Change Category name here
return false; }
return $is_purchasable;
}
Source: https://webtalkhub.com/how-to-remove-add-to-cart-button-in-woocommerce/
You have try something like this:
function remove_product_description_add_cart_button(){
global $product;
$termsOfProduct = wp_get_post_terms( $product->id, 'product_cat' );
if (in_array("CatToFind", $termsOfProduct)) {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
add_action('wp','remove_product_description_add_cart_button');
}
Category products in Woocommerce are simply terms. Wp_get_post_terms allow you to find any categories associated to post (product id).
Reference: https://codex.wordpress.org/Function_Reference/wp_get_post_terms
Use this code
/*
Plugin Name: Remove 'Add to cart' conditionally
Plugin URI: https://www.damiencarbery.com/2020/03/remove-add-to-cart-conditionally/
Description: Conditionally remove the 'Add to cart' button in WooCommerce.
Author: Damien Carbery
Version: 0.2
*/
class IsPurchasableConditionalFiltering {
// A reference to an instance of this class.
private static $instance;
// Store whether 'Add to cart' button should be displayed.
private $purchasable;
// Returns an instance of this class.
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new IsPurchasableConditionalFiltering;
}
return self::$instance;
}
// Initialize the plugin variables.
public function __construct() {
$this->purchasable = array();
$this->init();
}
// Set up WordPress specfic actions.
public function init() {
add_filter( 'woocommerce_is_purchasable', array( $this, 'is_purchasable_conditionals' ), 10, 2 );
add_filter( 'woocommerce_variation_is_purchasable', array( $this, 'variation_is_purchasable_conditionals' ), 10, 2 );
// Remove variations dropdown and 'Add to cart' button for variable products.
add_action( 'woocommerce_before_single_product_summary', array( $this, 'before_single_product_summary' ) );
}
public function is_purchasable_conditionals( $whether_purchasable, $product ) {
// Return cached result.
if ( array_key_exists( $product->get_id(), $this->purchasable ) ) {
return $this->purchasable[ $product->get_id() ];
}
// Only do our conditional checks if WooCommerce deems the item to be purchasable.
if ( $whether_purchasable ) {
$result = true; // Default to allowing purchase.
// Check our specific conditions - some examples.
/* // Product over a certain price.
if ( $product->get_price() > 2 ) {
$result = false;
}*/
// Check if product in a certain categores.
if ( has_term( array( 'hoodies', 'accessories' ), 'product_cat', $product->get_id() ) ) {
$result = false;
}
$this->purchasable[ $product->get_id() ] = $result;
}
else {
// Store that this item cannot be purchased.
$this->purchasable[ $product->get_id() ] = false;
}
return $this->purchasable[ $product->get_id() ];
}
public function variation_is_purchasable_conditionals( $whether_purchasable, $product ) {
return $whether_purchasable;
}
public function before_single_product_summary() {
$product_id = get_the_ID();
if ( array_key_exists( $product_id, $this->purchasable ) && !$this->purchasable[ $product_id ] ) {
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
remove_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
}
}
}
$IsPurchasableConditionalFiltering = new IsPurchasableConditionalFiltering;
Reference : https://www.damiencarbery.com/2020/03/remove-add-to-cart-button-conditionally/
Every time you try and set a custom/action topic within webhooks (from WooCommerce > Settings > Webhooks) it would unset it as soon as you update your changes to the webhook. In other words, it will undo your custom topic and return it back to 'Select an option' for the topic dropdown.
Any help at all is appreciated. Thank you very much!
edit: In addition to my comment below, I've also attempted to create my own custom topic via the following filter woocommerce_webhook_topic_hooks, however, it doesn't show within the dropdown list as an option.
The below code runs from functions.php as with any WordPress hook..
Code
function custom_woocommerce_webhook_topics( $topic ) {
$topic['order.refunded'] = array(
'woocommerce_process_shop_order_meta',
'woocommerce_api_edit_order',
'woocommerce_order_edit_status',
'woocommerce_order_status_changed'
);
return $topic;
}
add_filter( 'woocommerce_webhook_topic_hooks', 'custom_woocommerce_webhook_topics', 10, 1 );
edit 2: Added more context
I was having the same issue. Selecting any of the built-in topics worked fine. But selection Action and entering any WooCommerce Subscription actions kept reverting. I had also tried creating a new custom topic in the same file (wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-webhooks.php) that the built-in topics are created, mirroring 1:1 the code of one of the topics that 'stick' (e.g subscription.created) for a new 'subscription.paymentcomplete' topic. It appears in the drop down, but after saving the drop-down reverts to the default 'Selection an option...'.
//wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-webhooks.php
public static function init() {
...
add_action( 'woocommerce_subscription_created_for_order', __CLASS__ . '::add_subscription_created_callback', 10, 2 );
add_action( 'woocommerce_subscription_payment_complete', __CLASS__ . '::add_subscription_payment_complete_callback', 10, );
...
}
public static function add_topics( $topic_hooks, $webhook ) {
if ( 'subscription' == $webhook->get_resource() ) {
$topic_hooks = apply_filters( 'woocommerce_subscriptions_webhook_topics', array(
'subscription.created' => array(
'wcs_api_subscription_created',
'wcs_webhook_subscription_created',
'woocommerce_process_shop_subscription_meta',
),
'subscription.paymentcomplete' => array(
'wcs_webhook_subscription_payment_complete'
'woocommerce_process_shop_subscription_meta',
),
...
), $webhook );
}
return $topic_hooks;
}
public static function add_topics_admin_menu( $topics ) {
$front_end_topics = array(
'subscription.created' => __( ' Subscription Created', 'woocommerce-subscriptions' ),
'subscription.paymentcomplete' => __( ' Subscription Payment Complete', 'woocommerce-subscriptions' ),
...
);
return array_merge( $topics, $front_end_topics );
}
public static function add_subscription_created_callback( $order, $subscription ) {
do_action( 'wcs_webhook_subscription_created', $subscription->id );
}
public static function add_subscription_payment_complete_callback( $order, $subscription ) {
do_action( 'wcs_webhook_subscription_payment_complete', $subscription->id );
}
The solution was:
add_filter( 'woocommerce_valid_webhook_events', __CLASS__ . '::add_event', 10, 1 );
public static function add_event( $events) {
$events[] = 'paymentcomplete';
return $events;
}
Hello I am trying to remove an action from a wordpress plugin file. The plugin is called Woocommerce Points and Rewards. I have found the action I want to remove in one of the class files. When I comment out the "add_action" it does exactly what I want. But I am trying to remove the action from functions.php in my child them. I have been reading on this and I think my problem is I need to "globalize" the class variable that the action is in; but I am not sure what that class variable is…
here is the code where it adds the action (part of a file):
class WC_Points_Rewards_Cart_Checkout {
/**
* Add cart/checkout related hooks / filters
*
* #since 1.0
*/
public function __construct() {
// Coupon display
add_filter( 'woocommerce_cart_totals_coupon_label', array( $this, 'coupon_label' ) );
// Coupon loading
add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'points_last' ) );
add_action( 'woocommerce_applied_coupon', array( $this, 'points_last' ) );
// add earn points/redeem points message above cart / checkout
add_action( 'woocommerce_before_cart', array( $this, 'render_earn_points_message' ), 15 );
add_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 );
add_action( 'woocommerce_before_checkout_form', array( $this, 'render_earn_points_message' ), 5 );
add_action( 'woocommerce_before_checkout_form', array( $this, 'render_redeem_points_message' ), 6 );
// handle the apply discount submit on the cart page
add_action( 'wp', array( $this, 'maybe_apply_discount' ) );
// handle the apply discount AJAX submit on the checkout page
add_action( 'wp_ajax_wc_points_rewards_apply_discount', array( $this, 'ajax_maybe_apply_discount' ) );
}
The function I want to remove is this one:
add_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 );
so far no luck in getting it removed; here is what I have in functions.php:
global $woocommerce, $wc_points_rewards;
/*
global $this;
*/
remove_action( 'woocommerce_before_cart', array( $this, 'render_redeem_points_message' ), 16 );
so - I am sure this can be done in this way at least I have read that it can be done, I think I just have some thing wrong on this…
I tried globalizing $this, but that just gave me an error message...
if you need to see the entire file or something else please just let me know…
So I am hoping someone on here can help me identify what I am doing wrong…
** UPDATE Monday 8/18 ********
Looking for where class is instantiated; I have found this in the "woo commerce-points-and-rewards.php" file; this looks like this may be it but not sure what I am looking at;
does this look like where the "WC_Points_Rewards_Cart_Checkout" is instantiated?
And if so I am not sure how i use this to write my "remove action" in functions.php...
private function includes() {
// product class
require( 'classes/class-wc-points-rewards-product.php' );
$this->product = new WC_Points_Rewards_Product();
// cart / checkout class
require( 'classes/class-wc-points-rewards-cart-checkout.php' );
$this->cart = new WC_Points_Rewards_Cart_Checkout();
// order class
require( 'classes/class-wc-points-rewards-order.php' );
$this->order = new WC_Points_Rewards_Order();
// discount class
require( 'classes/class-wc-points-rewards-discount.php' );
$this->discount = new WC_Points_Rewards_Discount();
// actions class
require( 'classes/class-wc-points-rewards-actions.php' );
$this->actions = new WC_Points_Rewards_Actions();
// manager class
require( 'classes/class-wc-points-rewards-manager.php' );
// points log access class
require( 'classes/class-wc-points-rewards-points-log.php' );
if ( is_admin() )
$this->admin_includes();
}
Thanks so much...
Try this:
// Use the class name instead of a globalized $this
remove_action( 'woocommerce_before_cart', array( 'WC_Points_Rewards_Cart_Checkout', 'render_redeem_points_message' ), 16 );
As $this is an internal referrer to the class it is used in, globalizing it may not be a good thing.
Does the plugin allow you to extend the class with your own and use it instead?
you found a solution for this? having the same problem with another wc plugin ;)
alright. found an answer in the wc docs. in my case:
function wc_move_checkout_addons() {
remove_action( 'woocommerce_checkout_after_customer_details', array( $GLOBALS['wc_checkout_add_ons']->frontend, 'render_add_ons' ) );
add_action( 'woocommerce_checkout_before_customer_details', array( $GLOBALS['wc_checkout_add_ons']->frontend, 'render_add_ons' ) );
}
add_action( 'init', 'wc_move_checkout_addons' );
so in your case it should be something like that:
function wc_remove_message() {
remove_action( 'woocommerce_before_cart', array( $GLOBALS['wc_points_rewards_cart_checkout']->frontend, 'render_redeem_points_message' ) );
}
add_action( 'init', 'wc_remove_message' );
In case anyone else is wondering, I just accomplished removing the action in this plugin in the following way.
I wanted to remove the action defined in class-wc-points-rewards.php on line 34:
add_action( 'woocommerce_single_product_summary', array( $this, 'render_product_message' ) );
To do that, I looked at woocommerce-points-and-rewards.php. On line 46 it shows:
$GLOBALS['wc_points_rewards'] = new WC_Points_Rewards();
And in the same file for the definition of the WC_Points_Rewards class, on line 249-250 it shows:
require( 'includes/class-wc-points-rewards-product.php' );
$this->product = new WC_Points_Rewards_Product();
With that information, I was able to remove the action:
remove_action( 'woocommerce_single_product_summary', array( $GLOBALS['wc_points_rewards']->product, 'render_product_message' ) );
I was able to figure out how to remove the render_redeem_points_message effectively with the following code:
/* Removes render_redeem_points_message() */
function wc_remove_points_message() {
global $woocommerce;
global $wc_points_rewards;
// Removes message from cart page
remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 );
// Removes message from checkout page
remove_action( 'woocommerce_before_checkout_form', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 6 );
}
// Removes action on init
add_action( 'init', 'wc_remove_points_message' );
To share a bit more, I wanted to create a minimum purchase amount to be able to redeem points:
/* Adds Minimum Order for Points Redemption */
function wc_min_order_points_message() {
global $woocommerce;
global $wc_points_rewards;
// Get cart subtotal, excluding tax
$my_cart_total = $woocommerce->cart->subtotal_ex_tax;
if ($my_cart_total < 30) { // $30 minimum order
remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 );
remove_action( 'woocommerce_before_checkout_form', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 6 );
} // endif $my_cart_total
}
// Adds action for cart and checkout pages instead of on init
add_action( 'woocommerce_before_cart', 'wc_min_order_points_message' );
add_action( 'woocommerce_before_checkout_form', 'wc_min_order_points_message' );
I hope this helps anyone else trying to similarly expand on the WooCommerce Points and Rewards plugin.
SOLUTION-1:
In this case, as we have the plugin object's global instance, then we can do it easily:
remove_action('woocommerce_before_cart',array($GLOBALS['wc_points_rewards']->cart,'render_redeem_points_message'),16);
SOLUTION-2:
We will not be lucky always like the above solution getting the instance of the class object if any plugin author creates the class object anonymously without storing it to any global variables or keeping no method which can return it's own instance. In those cases, we can use the following :)
//keeping this function in our functions.php
function remove_anonymous_object_action( $tag, $class, $method, $priority=null ){
if( empty($GLOBALS['wp_filter'][ $tag ]) ){
return;
}
foreach ( $GLOBALS['wp_filter'][ $tag ] as $filterPriority => $filter ){
if( !($priority===null || $priority==$filterPriority) )
continue;
foreach ( $filter as $identifier => $function ){
if( is_array( $function)
and is_a( $function['function'][0], $class )
and $method === $function['function'][1]
){
remove_action(
$tag,
array ( $function['function'][0], $method ),
$filterPriority
);
}
}
}
}
And calling the following line appropriately when we need (may be with a hook or something):
//-->Actual Target: this line does not work;
//remove_action( 'personal_options', array('myCRED_Admin','show_my_balance') );
//-->But instead this line will work ;)
remove_anonymous_object_action('personal_options','myCRED_Admin','show_my_balance');
exactly this function worked for me
if (class_exists('WC_Points_Rewards')) {
global $woocommerce, $wc_points_rewards;
remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_earn_points_message' ), 15 );
remove_action( 'woocommerce_before_cart', array( $wc_points_rewards->cart, 'render_redeem_points_message' ), 16 );
}