Clear out some woocommerce cart meta on logout - woocommerce

I have some personal information that I'm building during the checkout process and saving on the cart object.
If the user logs out then I want to leave the product selection in the cart intact, but remove the pii that I've added to the cart.
I've tested this code elsewhere, in a normal template and it clears out the cart:
public function clear_pii_from_cart()
{
if (WC()->cart == null) {
return;
}
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
unset(WC()->cart->cart_contents[$cart_item_key]['personalinfo']);
}
// save to cart
WC()->cart->set_session();
}
But when I call it from the wp_logout action the info is still in the cart after logout.
I can't figure out how to get any logging into it to be able to see what data structures I'm dealing with.
It just logs out and seems to do nothing.
I know the hook is working because if I put a die(); in then I get a blank page.
I've combed the WooCommerce source code on github looking for a hint, and not found anything, nor by general searches.
I know this is super niche but does anybody have an idea?

False alarm, I set the priority of wp_logout to 5 and it suddenly started working.
I was imagining that the session had been destroyed just as I was trying to use it or something like that.

Related

Wordpress errors from shortcodes being executed on edit page

I am writing a wordpress plugin.
I have noticed in my debug log that i get a lot of PHP errors thrown because my shortcodes are being executed on the admin edit pages and therefore the relevant data is not available because the shortcode is loading dynamic data based upon the user front end. For example i have a function:
function myFunction_availability() {
if (is_admin()) return; // tried adding this but still get the issue
$product = $this->myFunction_get_current_product();
return "<div class='product-availability'>{$product->availability}</div>";
}
Works fine from the front end, but whenever i load the edit page from admin area i get in my log:
PHP Warning: Attempt to read property "availability" on null in /home/vagrant/yodahwp/wp-content/plugins/yodah/class.yodah.php on line 1602
As you can see from my code, i tried adding is_admin() to exit out of the function if viewing an admin page (i.e. the edit post page) but this does not seem to work.
Do any wordpress whizzes have an answer for this? I am a bit surprised that shortcodes are executed on the admin edit pages, or am I missing something?!
Thanks
This is an old question. Usually, this happens when using visual builders.
One solution is to write a condition to check if the product exists.
If using woocommerce you can try:
$product = wc_get_product( get_the_ID() );
if($product){
//continue
}
In your case, you should edit your myFunction_get_current_product() method and verify there if the product exists.

How to properly initialize Woocommerce Cart

I have a custom template file, rendering some products and their Add To Cart buttons, that I am trying to implement manually. When Add to Cart is pressed, the page is reloaded and a $_POST variable containing some data adds the new products. 'cart_contents_count' also reflects the added item. However, when I go to the cart page, it's empty. Please see the following code.
global $woocommerce;
if ( isset( $_POST['AddedToCart'] ) ) {
$woocommerce->cart->add_to_cart($_POST['event'], $_POST['qty']);
}
$cart_total = $woocommerce->cart->cart_contents_count;
When I however go to the normal default shop page ( /shop/ ) and add a product from there, my cart page indicates that this product has been added. When I NOW go to my custom page and add products from that Add To Cart button, it works perfectly.
It seems to me that, before I run the above-mentioned code, I must check if a Cart Session has been initialized, and if not, initialize it. Could someone please confirm for me that I understand it right and show me how to initialize the cart?
Here is a solution if your custom form is on a page template. This code goes in your functions.php file. Be sure to change yourtheme_template to something more unique. Also, change the items in the $session_templates array to the template filenames where you want this filter to be used. It uses the template_include filter, which isn't an easy filter to track down, let alone $woocommerce->session->set_customer_session_cookie(true) - Special thanks to #vrazer (on twitter) for the help.
function yourtheme_template($template) {
//List of template file names that require WooCommerce session creation
$session_templates = array(
'page-template-file-name.php', 'another-page-template-filename.php'
);
//Split up the template path into parts so the template file name can be retrieved
$parts = explode('/', $template);
//Check the template file name against the session_templates list and instantiate the session if the
//template is in the list and the user is not already logged in. If the session already exists from
//having created a cart, WooCommerce will not destroy the active session
if (in_array($parts[count($parts) - 1], $session_templates) && !is_user_logged_in()) {
global $woocommerce;
$woocommerce->session->set_customer_session_cookie(true);
}
return $template;
}
//Filter to run the WooCommerce conditional session instantiation code
add_filter('template_include', 'yourtheme_template');
I resolved this problem by making sure the $woocommerce->cart->add_to_cart() line is positioned before any headers are sent. I.E, before get_header() is called on my custom template.
In the WooCommerce version 2.5 they change the way the sessions works. https://woocommerce.wordpress.com/2015/10/07/new-session-handler-in-2-5/
What i did was install this plugin https://github.com/kloon/woocommerce-large-sessions then my cart is not empty any more with guess users.
I hope it helps someone else.

WordPress: Stop spam posts programmatically

I have an image sharing site built on WordPress and recently I've had a lot of bots registering a user and creating a spam post with links to various sites.
After installing WP-reCAPTCHA the numbers have reduced but there are still 'attacks' every hour or so.
I'm trying to handle this programmatically now, by hooking into wp_insert_post_data (which is called whenever a post/revision is saved). I inspect the post data and if it contains a link I remove the post's content and set the status to draft so that it isn't published.
But it's still a nuisance to delete spam users and posts from the back end.
Is there a better hook I can use to stop the saving of the post even happening? i.e. can I reject the call to save the post?
Here is the code I'm currently using:
function block_spam_posts($data, $postarr) {
// if the post contains a link, set it to draft status
$post_content = $data['post_content'];
if (strpos($post_content,'http') !== false) {
$data['post_content'] = 'Post data removed by anti-spam measures.';
$data['post_status'] = 'draft';
}
}
add_filter('wp_insert_post_data', 'block_spam_posts',1,2);
Thanks for your help.
I found the answer here:
https://wordpress.stackexchange.com/questions/82354/how-can-i-hook-into-creating-a-new-post-and-execute-wp-die-before-the-post-is
I'm using the right hook. All I need to do is call wp_die() once the criteria for a spam post has been met.
Hope this helps others.

How to create a wordpress custom settings page for a subscriber

Please let me first try to explain what I want to accomplish:
I am building a wordpress website for a small, local, but public swimming pool. The pool is only open when the weather is 'fine'. The lifeguard decides in the morning whether the pool will be open or not. This information should be easily maintained and be visible on the website.
I created a widget that displays whether the pool is open or not. The widget recieves the data from a custom table in de wordpress database. The background of the widget will be green when open, red when closed and orange if the lifeguard has not made a decission yet.
So far no problem. For the lifeguard I made an useraccount to login. The only thing he should be able to set/modify, is whether the pool is open today. He should not be allowed to edit/publish pages/posts or see anything else on the dashboard.
So my thoughts are to make the lifeguard a 'subscriber'. But now I am struggling how he can access an settingspage for the 'open or not option'. And where to make this settingspage?
First idea: Make it availaible in backend, but how can I assure it's available for a subcriber?
Second idea: Make it availaible in the frontend. But then, how can I do this?
Has anyone done such a thing? Can anyone point me to a solution for this?
Thanks!
Luc
To make things as clean as possible, I'd register a new custom lifeguard role and an open_pool capability that gets assigned to that role. You would give all your lifeguards the lifeguard role.
You could then add a dialog to either the front or back end using:
if (current_user_can ( 'open_pool' ) {
print $pool_open_close_form;
}
To get you started, take a look at this WPSE thread and the Roles and Capabilities section of the Codex.
Instead of basing this off a subscription, you could base if off a single log in using wp_get_current_user();
For example, in your functions.php file you could place the following.
$current_user = wp_get_current_user();
if($current_user->user_login == 'User1') {
function example_add_dashboard_widgets() {
wp_add_dashboard_widget(
'example_dashboard_widget', // Widget slug.
'Example Dashboard Widget', // Title.
'example_dashboard_widget_function' // Display function.
);
}
add_action( 'wp_dashboard_setup', 'example_add_dashboard_widgets' );
function example_dashboard_widget_function() {
// Display whatever it is you want to show.
echo "Hello World, I'm a great Dashboard Widget";
}
}
This would check the username matches 'User1', then would add a dashboard widget, meaning it would be the first thing the lifeguard sees when they log in. Of course this does mean potentially having a shared log if there are multiple lifeguards.
Sources:
http://codex.wordpress.org/Function_Reference/wp_get_current_user
http://codex.wordpress.org/Dashboard_Widgets_API
You could use a plugin like Adminimize (https://wordpress.org/plugins/adminimize/) to only display the lifeguard some menu function to change the status for the pool and remove all other posts/pages related menu items.

WooCommerce Show Payment Gateways for Logged In Customers Only

I am setting up an ecommerce site using Wordpress and WooCommerce. We are using the wordpress member accounts to track customer information, and we need a way for logged in members only to be able to choose to purchase their cart "on credit", meaning no payment is required to place the order. Basically what I have done is hi-jacked the "Check" option (since we don't need it anywhere else) and renamed it "Credit" since it allows for the functionality we need.
However, I need a way for the "Credit" (check) option to only display if the user is logged in. Is there any way I can just "unhook" this option if the user isn't logged in? This seems like something that would be easy to do, but I couldn't find anything about it. Any help is appreciated.
The original answer to this question (from BWDesign) no longer works due to changes in WooCommerce (at least from WooCommerce 2.1.7 onwards, possibly before). This does the trick now (tested on 2.1.7 and 2.1.8), add it to e.g. your functions.php file:
add_filter( "woocommerce_available_payment_gateways", "rp_filter_gateways", 9999 );
function rp_filter_gateways($args) {
if(!is_user_logged_in() && isset($args['cheque'])) {
unset($args['cheque']);
}
return $args;
}
I just found the solution. In the class-wc-cheque.php file, the check or "cheque" (crazy brits) option is hooked using add_filter('woocommerce_payment_gateways', 'add_cheque_gateway' );. So the solution was simply to add this code to my functions.php file:
if(!is_user_logged_in()){
remove_filter('woocommerce_payment_gateways', 'add_cheque_gateway' );
}
Hope this helps!

Resources