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 );
Related
We use a plugin which add a filter to hide some order meta. Now we want to remove them via child theme instead of editing the plugin file. I tried every answer from here but the action is not removed: https://wordpress.stackexchange.com/questions/240929/how-to-remove-action-from-plugin and Removing action added by a plugin in Wordpress
This is the Plugin function:
public function __construct() {
add_filter( 'woocommerce_order_item_get_formatted_meta_data', [ $this, 'hide_extra_data' ] );
}
I tried with that already, but I'm not sure if this is the right way to do it.
add_action( 'woocommerce_order_item_get_formatted_meta_data', 'remove_my_action', 1 );
function remove_my_action(){
remove_action('woocommerce_order_item_get_formatted_meta_data', 'hide_extra_data', 10, 1);
}
remove_action( 'wp_fwoocommerce_order_item_get_formatted_meta_dataooter', 'hide_extra_data', 1 );
Try like this:
add_action( 'plugins_loaded', 'webearth_remove_plugin_filter' );
function webearth_remove_plugin_filter() {
remove_filter( 'woocommerce_order_item_get_formatted_meta_data',
array('ClassName', 'hide_extra_data'),
10 );
}
Change ClassName with the name of the class used by the plugin, the Class where the constructor is.
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 (
I have a review plugin that overrides the comment form in a specific posttype.
Now I'm trying to seperate the reviews and comments.
My first step is to remove the filter that modifies the current comment template and use that filter inside a second comment form.
The plugin uses this code (simplified)
final class DM_Reviews {
public function hooks() {
do_action_ref_array( 'dm_reviews_before_setup_actions', array( &$this ) );
add_filter( 'comment_form_defaults', array( $this, 'reviews_form' ) );
do_action_ref_array( 'dm_reviews_after_setup_actions', array( &$this ) );
}
public function review_form( $args ) {
$form = 'plugin code to modify form';
return wp_parse_args( $form, $args );
}
}
In my child theme's function.php file, I tried to use this but it didn't worked.
global $DM_Reviews;
remove_filter( 'comment_form_defaults', array($DM_Reviews, 'reviews_form'),1 );
WP Codex
If someone can put me in the right direction on how to solve it, it would help me a lot.
I think you can achieve this goal, using one of the following solutions depending on the way this plugin instantiates the class:
if( class_exists('DM_Reviews' ) ){
//This should work in whatever case, not tested
remove_filter('comment_form_defaults', array( 'DM_Reviews', 'reviews_form'));
//or Instantiating a new instance, not tested
remove_filter('comment_form_defaults', array( new DM_Reviews(), 'reviews_form'));
//or Targeting the specific instance, not tested
remove_filter('comment_form_defaults', array( DM_Reviews::get_instance(), 'reviews_form'));
}
Hope it helps, let me know if you get stuck.
for me remove_filter didn't work from function.php i wanted to remove a specific behavior of a plugin so what i did :
add_action( 'init', 'remove_filters' );
function remove_filters(){
global $wp_filter;
unset( $wp_filter["_filter_name"]);
}
Try this :
$instance = DM_Reviews::this();
remove_filter('comment_form_defaults', array( $instance, 'reviews_form'));
I'm switching to a new Wordpress plugin I've written myself that will run along side an old plugin on top of the Woocommerce cart. While I'm running the two plugins I want to remove the old plugin's action that calls it's table to display in the users my account page. I will be adding logic after to work out if it's needed, but for now I just need to remove it.
This is how the action is being called in the old plugin.
class WC_Subscriptions {
public static function init() {
// Display Subscriptions on a User's account page
add_action( 'woocommerce_before_my_account', __CLASS__ . '::get_my_subscriptions_template' );
}
}
WC_Subscriptions::init();
So far in my own plugin I have called the following and none of them work.
remove_action( 'woocommerce_before_my_account', array('WC_Subscriptions', 'get_my_subscriptions_template' ) );
// no error but still shows the table
and the last one
remove_action( 'woocommerce_before_my_account', array( WC_Subscriptions::init(), 'get_my_subscriptions_template' ) );
// Fatal error: Class 'WC_Subscriptions' not found in /var/sites/XXXXX on line 45
I have tried changing/adding the $priority from 1, 9, 10, 11 and 99 and that doesn't work either.
It's frustrating as I'm sure it would work if the old plugin was initiated with a new instance so I could do this
global $my_class;
remove_action( 'woocommerce_before_my_account', array( $my_class, 'get_my_subscriptions_template' ) );
Can anyone help?
This always happens, just worked it out.
I needed to hook the remove_action into another action that is called much later.
In the end I did this
class My_new_plugin {
public function __construct() {
add_action( 'wp_head', array($this, 'remove_action_woosubscription_table' ) );
}
public function remove_action_woosubscription_table() {
remove_action( 'woocommerce_before_my_account', array( 'WC_Subscriptions', 'get_my_subscriptions_template' ) );
}
}
You can set third attribute 'priority' as 999
<?php remove_action( $tag, $function_to_remove, $priority ); ?>
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 );
}