Ask your WordPress questions! Pay money and get answers fast! (more info)

Remove thankyou_page function from WooCommerce payment gateway WordPress

  • SOLVED

I want to customise the content and layout of the information that is displayed by the core payment gateways on the thank you page in WooCommerce.

My approach so far has been to attempt to remove the thank_you page action from the woocommerce_thankyou_bacs hook, and add a new action to the same location, with my desired layout and content.

I am trying to remove the action, using the following code:
remove_action( 'woocommerce_thankyou_bacs', array(&$order, 'thankyou_page'));

I know that I am using the correct hook ('woocommerce_thankyou_bacs'), because I have used it to add a quick test function using add_action, but the remove action does not work. I need to remove the function because it displays content on the thank you page that I want to replace, not just add to.

I have attached a screenshot showing the exact section that I want to remove/replace. Please note that this content was added by me via the admin interface of WooCommerce and it corresponds to the 'description' field for that gateway.

I believe that my problem is an incorrect reference to the function name for the thankyou_page function in the BACS payment gateway.

What is the specific code that I need to use to specify the correct function name and get this remove action to work?

I want to do this for the cheque, and e-path (a plugin) methods as well, so I need a generic answer, using the BACS gateway as a specific example, that reflects the correct path through the order, payment gateway and WooCommerce objects and classes and arrays, to remove this specific function.

I did wade through the code trying to understand which objects were where, and it seems like there's a payment gateways object, containing all the available payment methods, that the woocommerce object uses when accessing an order, based on the payment_methods value of the order. I just don't know the syntax to access it correctly, or even if this approach will work.

I have also played with including a priority with the remove action, using this code:
$priority = has_action('woocommerce_thankyou_bacs', array($order, 'thankyou_page'));
but this too suffers from the same 'incorrect reference' problem as above.

In the _construct method for the BACS payment gateway class, the action is added as follows:
add_action( 'woocommerce_thankyou_bacs', array( $this, 'thankyou_page' ) );
but in the context of the thankyou page (thankyou.php) I don't know what '$this' refers to and how to address it.

My questions are:
1. What is the correct code to remove the 'thankyou_page' function/action from the woocommerce_thankyou_bacs hook (as an example, that I can then translate to all core payment gateways)
2. Do I need to include the priority in this remove_action call before it will work, and what is the correct code to do this?
3. Is this the optimal way to solve this problem? Is this approach inherently flawed? Is it even possible to do what I want this way? Is there a better way to solve this problem?

<strong>Notes:</strong>
- I am placing all code in my theme's functions.php file.
- I've been editing the templates to change things where I can, and have already heavily customised the thankyou.php page this way (in my child theme), but the code for this particular section is embedded in the payment gateway code, not in the template, hence why I'm trying to override it with remove/add.
- I don't want to write a custom gateway, as that just creates more maintenance, which I am trying to minimise by using hooks, actions and filters instead.
- I will also want to remove the email_instructions function as well, and replace it with my own code, so if the answer for that is along the same lines, please include it as well.
- I am very comfortable with PHP, CSS, and HTML, I just haven't got my head fully around the WooCommerce/WordPress underlying frameworks yet, but I want to become very familiar with them through solving problems like these.

<strong>System information</strong>
Wordpress v3.8
WooCommerce v2.0.20
Theme: Genesis with Dynamik Website Builder child theme
Site URL http://wp1.yawarra.com.au/ - not accessible to the outside world

Please let me know if you need any more information to answer my question.

Answers (1)

2014-01-24

Dbranes answers:


I wonder if you could copy

/wp-content/plugins/woocommerce/templates/checkout/thankyou.php

(or [[LINK href="https://github.com/woothemes/woocommerce/blob/master/templates/checkout/thankyou.php"]]this file[[/LINK]]) to

/wp-content/themes/YOUR_THEME/woocommerce/checkout/thankyou.php

and then remove these lines from the copy:

<?php do_action( 'woocommerce_thankyou_' . $order->payment_method, $order->id ); ?>
<?php do_action( 'woocommerce_thankyou', $order->id ); ?>


Nikki comments:

Thanks for the suggestion. I hadn't considered that possibility. And dropping out the first line is, in fact, all I need to do to remove the payment description from thank you page, and it does it exactly that when I comment it out in my modified copy of the template. And it does appear that all the thankyou_page function does is output content to the page, so it definitely achieves the goal of removing the content.

However, I'm a little reluctant to drop out the hook entirely, because that kind of undermines the whole hook-action-filter model, as I understand it. If at any point I, or another plugin, tried to hook into that location, it would invisibly fail, if I understand things correctly. And in fact, all my other custom payment gateways that I have built (by adapting another plugin), use this exact hook to display their payment instructions, so doing this would prevent them from working as desired.

And ultimately, I'm also looking for a definitive answer as to whether the function CAN be removed using remove_action and HOW - because it seems like the simplest, most elegant, and lowest-maintenance way to achieve this. And also because I want to learn more about how hooks and actions work in general.

So it's definitely in the right direction, thank you, but not quite was I was after.


Dbranes comments:

Yes I agree that using the hooks is better.

ps: did you test the <em>get_class</em> part?


Dbranes comments:

sorry ignore the get_class, it will not give you informations about the instance name, only the class name ;-)


Nikki comments:

Darn. And it sounded so promising!

And no, I haven't played with classes, even though I know it's inside one, because that's the bit I'm most unfamiliar with.

I really need to rely on someone else's understanding of the hierarchy/relationship of the classes and objects, or at least how to figure it out, because that's exactly the piece that's missing: how do I access and modify the instance and its behaviour?


Dbranes comments:

You could perhaps check the registered callbacks for a given hook with:

add_action( 'wp_footer', function(){

$hook = 'woocommerce_thankyou'; // Edit this to your needs.

global $wp_filter;

if( isset( $wp_filter[$hook] ) )
printf( '%s: <pre>%s</pre>', $hook, print_r( $wp_filter[$hook], TRUE ) );

});


Nikki comments:

OK, so I've added this code to my site, for the 'woocommerce_thankyou_bacs' hook for now, and loaded a 'thank you' page for an order that specified bacs as the payment method. And it spits out this fabulously long array of arrays of arrays etc.

So what the heck do I do with the information? And do you want me to share the output with you so you can make sense of it?


Nikki comments:

Here's a file with the output, in case it helps you make sense of the objects & classes.

And now I'm off to bed (it's almost tomorrow already) and I'll come back to this tomorrow. Thanks for your help.