I'm want to clear all items in cart when a new session is started. I've tried
add_action( 'init', 'clear_cart_on_it' );
function clear_cart_on_it() {
global $woocommerce;
$woocommerce->cart->empty_cart();
}
It is throwing this error:
Fatal error: Call to a member function empty_cart() on null in /home/shuggapa/public_html/wp-content/plugins/candy-scoops/scoops.php on line 53
I have no idea why. Please how can I implement this.
Adding to #"Vidish Purohit"'s answer, you want to additionally confirm the referer, and use a more suitable hook.
On the page initiating the delete, use:
<form method="post">
<input type="hidden" name="action" value="empty_cart">
<?php wp_nonce_field("empty_cart", "empty_cart"); ?>
<button type="submit">Remove all</button>
</form>
To handle the delete, add this hook in your functions:
add_action('woocommerce_init', 'my_woocommerce_init');
function my_woocommerce_init() {
if (isset($_POST["action"]) && $_POST["action"] === "empty_cart") {
wp_verify_nonce("empty_cart", "empty_cart");
WC()->cart->empty_cart();
}
}
First it checks that the submit happened ($_POST['action'] present and matching), then wp_verify_nonce checked that the POST really was initiated from a reliable origin.
And most essentially, the woocommerce_init hook makes sure the global WC() returns something to work with.
In your code, init hook is triggered before Woocommerce object is instantiated. You can use this hook:
add_action( 'template_redirect', 'clear_cart_on_it' );
or
add_action( 'wp_loaded', 'clear_cart_on_it' );
Related
Problem:
I need to add a shortcode [wc_sc_available_coupons] below the product table on the checkout page.
I added the following code in functions.php
The problem is the shortcode displays at the very bottom of the checkout form.
I changed the number 10 to 120 but still the same.
Would you please let me know how to add the shortcode below the product table (=above the payment)?
Code I tried:
add_action( 'woocommerce_after_checkout_form', 'wnd_checkout_code', 10 );
function wnd_checkout_code( ) {
echo do_shortcode('[wc_sc_available_coupons]');
}
Thank you.
Would woocommerce_checkout_after_customer_details hook work for you? So your code would be something like this:
add_action( 'woocommerce_checkout_after_customer_details', 'wnd_checkout_code' );
function wnd_checkout_code( )
{
echo do_shortcode('[wc_sc_available_coupons]');
}
If not then you could try other hooks such as woocommerce_checkout_before_order_review or you could try this woocommerce_before_order_notes as well.
This one is right before the payment:
add_action( 'woocommerce_review_order_before_payment', 'wnd_checkout_code' );
function wnd_checkout_code( )
{
echo do_shortcode('[wc_sc_available_coupons]');
}
Use the action:
add_action("woocommerce_after_cart_table", $action)
OR
add_action("woocommerce_before_cart_collaterals", $action)
Result
https://imgur.com/a/zQVNedb
In general for WooCommerce you can find hook info here:
https://woocommerce.github.io/code-reference/hooks/hooks.html
and for your template:
https://woocommerce.github.io/code-reference/files/woocommerce-templates-cart-cart.html#source-view.159
You can see information on the actions allowed by looking at the source code in woocommerce/templates/ and checking the do_action() functions.
I've encountered a weird thing in WP WooCommerce and I can't understand nor fix it myself.
Thing is I've added a clear button in my checkout page,
that button redirects me to my homepage and adds a ?clear param.
Then I check if that param is set and if it is set then the cart is cleared;
Code:
if(isset($_POST["clear_cart"]))
{
header("Location: https://examplepage.com?clear");
}
add_action( 'init', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url()
{
global $woocommerce;
if(isset( $_GET['clear']))
{
$woocommerce->cart->empty_cart();
}
}
Now the bug/error thing.
This code works... Once. I'll do my best to explain now.
When I click the clear button for the first time - it works.
I'm being redirected to my homepage, cart is cleared, everything works.
When I go and add some products again and then I clear the cart
I get redirected to my homepage again (first 4 lines of code)
but my cart isn't cleared now. To get it cleared I have to change my param to something like
?clear=true
Then I do the same thing and after clicking clear cart button it redirects me again and the cart isn't cleared. If I again change the param to
?clear=true
it doesn't work this time - because it worked before. Changing the param to
?clear=true1
clears the cart.
I hope you've already understand what I'm talking about.
I've tried various params instead of "clear" and everytime the same thing happens.
When I also tried echoing something within
function woocommerce_clear_cart_url()
it also worked only once. I'm out of ideas.
Thank you.
Try below code
add_action( 'init', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url() {
global $woocommerce;
if(isset($_POST["clear_cart"]))
{
$data= $woocommerce->cart->empty_cart();
if(is_null($data) == 1 ){
wp_redirect( site_url() );
exit;
}
}
Assuming your html code is something like below :
<form method="post">
<input type="submit" name="clear_cart" value="1">
</form>
You need to try this code for your error.
add_action("template_redirect", 'e_coding_hub_redirection_function');
function e_coding_hub_redirection_function(){
global $woocommerce;
if( is_cart() && WC()->cart->cart_contents_count == 0){
//wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'shop' ) ) );
wp_redirect( site_url() );
}
}
I want to display the header cart (located on the menu) only if the user is logged in. Here's what I got so far:
add_action('init','remove_header_cart_if_user_not_logged_in');
function remove_header_cart_if_user_not_logged_in() {
if (is_user_logged_in()) {
return;
} else {
add_action( 'init', 'woa_remove_header_cart' );
function woa_remove_header_cart() {
remove_action( 'storefront_header', 'storefront_header_cart', 60 );
}
}
This code creates an error and prevents my website to display. " The [domain] page isn’t working [domain] is currently unable to handle this request.
HTTP ERROR 500"
The else part alone (woa_remove_header_cart) works well, but when I try to put it inside of the "if user logged in" condition, it generates the error.
What if you simplified it to:
add_action( 'storefront_header','remove_header_cart_if_user_not_logged_in' );
function remove_header_cart_if_user_not_logged_in() {
if ( ! is_user_logged_in() ) {
remove_action( 'storefront_header', 'storefront_header_cart', 60 );
}
}
You are adding two functions to the init hook at the same time/priority? It's weird at best, and may be causing your error. I'm also not sure if WP knows the user is logged in by init. Don't have time to check now, but you can avoid it. You don't have to remove a function on the init hook, you just have to do it before the function is executed. In my example, I'm using the storefront_header hook, but since the default (10) priority is lower than 60 it should work.
i need a hook for the moment when an admin updates a post. (Click on update button). After the post is successfully updated.
The reason is, i have to call a function to update something for another plugin.
Everything i tried so far, is not working.
add_action( 'save_post', 'wpse41912_save_post' );
add_action( 'edit_post', 'wpse41912_edit_post' );
add_action( 'transition_post_status', 'wpse41912_transition_post_status' );
add_filter( "edit_post_{$field}", 'filter_edit_post_field', 10, 2 );
add_action( 'admin_head-post.php', 'admin_head_post_editing' );
add_action( 'admin_head-post-new.php', 'admin_head_post_new' );
add_action( 'admin_head-edit.php', 'admin_head_post_listing' );
In Everything function i wrote this, and i didnt see the echo or the alert box.
echo "my_update_user_meta";
$text = "my_update_user_meta";
echo '<script type="text/javascript">alert("' . $text . '")</script>';
Edit: i was missing the 3,4th parameter.
My Code now
add_action( 'save_post', 'mmx_save_post_action', 10, 3 );
function mmx_save_post_action( $post_id, $post, $update ) {
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) { // keine Aktion bei Autosave
//autosave
}else{
//no autosave
if ( is_admin() && current_user_can( 'manage_options' ) ) {
//admin panel && permission ok
//call function
}
}
}
When a post is updated there are some hooks that are fired:
'pre_post_update' is an action fired just before the post is updated, the argument passed are 2: $post_ID and $data that is an array of all the other database colums of the post table
'transition_post_status' is an hook fired on update, and pass 3 arguments: $new_post_status, $old_post_status and $post (object).
Then, there are other 2 transition hooks fired, but they are dynamic named, it means that the effective action fired depends on the old and the new post status.
"{$old_status}_to_{$new_status}" and "{$new_status}_{$post->post_type}". First pass the only the post object as argument, the second pass the post id and the post object. Find documentation here.
'edit_post' that pass 2 arguments: $post_ID and $post (object)
'post_updated' that pass 3 arguments: $post_ID, $post_after (post object after the update), $post_before (post object before the update)
Another dynamic hook: "save_post_{$post->post_type}" that depends on post type, e.g. for standard posts is 'save_post_post' and for pages is 'save_post_page', this hook pass 3 arguments: $post_ID, $post (object) and $update that is a boolean (true or false) that is true when you perform an update, in fact this hook is fired also when a post is saved for first time.
'save_post' that is fired both on update and on first saving, and pass the same 3 arguments of the previous hook.
'save_post_{$post_type}' that is fired both on update and on first saving, and pass the same first 2 arguments of the previous hook.
Finally you have 'wp_insert_post', that is fired both on update and on first saving, and pass the same 3 arguments of the previous 2 hooks.
These hook are fired every time a post is updated, both via admin pages in backend and via when updated "manually" using wp_update_post or wp_insert_post functions.
When the post is updated using admin pages there are additional hooks fired, an example is 'update_post_redirect' or 'post_updated_messages'. (See this and this WPSE answers for usage examples).
Note that if you want make use of some hooks argument, that isn't the first, one you have to explicitly declare it in add_action call.
E.g. if you want to use the '$update' argument (that is the 3rd) of the 'save_post' hook you need to add 3 as $accepted_args param on add_action (see docs):
// if you don't add 3 as as 4th argument, this will not work as expected
add_action( 'save_post', 'my_save_post_function', 10, 3 );
function my_save_post_function( $post_ID, $post, $update ) {
$msg = 'Is this un update? ';
$msg .= $update ? 'Yes.' : 'No.';
wp_die( $msg );
}
Last note regard timing: you must be sure that add_action is called before the action is triggered, or it will do nothing.
E.g. this code:
wp_update_post( $post );
add_action( 'save_post', 'my_function', 10, 3 );
will do nothing, because the action is added after the hook is fired. Here is simple to recognize it, in real world code isn't always so.
I created my own child theme. Everything works great except I can't seem to unregister a hoook.
$this is class TC_footer_main and the following code is in the __construct
add_action ( '__colophon' , array( $this , 'tc_colophon_center_block' ), 20 );
I tried several remove actions with no success. I am just trying to change/remove the footer:
remove_action( '__colophon' , 'tc_colophon_center_block' , 55);
or
remove_action( '__colophon' , array('TC_footer_main','tc_colophon_center_block') , 55);
I've also tried
remove_action( '__colophon' , TC_footer_main::$instance->tc_colophon_center_block() , 55);
But that threw an error as TC_footer_main was not loaded by the time my functions.php file ran.
I am just trying to change/remove the footer:
I think you're making it way more complex, to modify the output of the tc_colophon_center_block() method, than it has to be.
Just use the tc_credits_display filter:
add_filter( 'tc_credits_display', function( $html )
{
// Modify output to your needs!
return $html;
} );
to modify that block to your needs.
To totally remove the output (if that's allowed), simply use:
add_filter( 'tc_credits_display', '__return_null', PHP_INT_MAX );
You have further access to filters like:
tc_copyright_link
tc_credit_link
tc_wp_powered
to choose from.
That's it!
For your purpose add the following code in function.php. It will get call on after_setup_theme hook.
// replace parent function
function child_theme_function () {
// your code goes here
}
function my_theme_setup () {
remove_action( '__colophon', 'tc_colophon_center_block', 1000 );
add_action( '__colophon', 'child_theme_function', 1000 );
}
add_action( 'after_setup_theme', 'my_theme_setup' );
You can also try for overriding the parent class from child class as described here: https://thethemefoundry.com/tutorials/advanced-customization-replacing-theme-functions/
you werent too far away...one problem you may have is you are trying to remove the hook before it has been added by your parent theme..the class could be initialized at a later stage...
im not too sure when your hook runs, but hopefully its after init
add_action('init', 'remove_parent_hook');
function remove_parent_hook(){
remove_action( '__colophon' , array('TC_footer_main','tc_colophon_center_block') , 20); // needs to be the same priority
}
you can obviously now just add a action for your new function.
There is a offchance that a anonymous function has been added, often the significance of &$this is overlooked when trying to remove a hooked function. This is a pain because wp will assign a random string as the key name & the function name for the function, its different every time so it cant be guessed. But we can search for the function name within the key so something like this will work
function remove_anon_hk($hook, $function, $priority=10 ){
global $wp_filter;
$hooks= $wp_filter[$hook][$priority];
if(empty ($hooks))
return;
foreach($hooks as $hk=>$data):
if(stripos($hk, $function) !== false ){
unset($wp_filter[$hook][$priority][$hk]);
}
endforeach;
}
add_action('init', function(){
remove_anon_hk('__colophon', 'tc_colophon_center_block');
});