How to properly initialize Woocommerce Cart - wordpress

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.

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.

Aramex plugin errors

I use this plugin: https://wordpress.org/plugins/aramex-shipping-woocommerce/
But I try any means but I failed to solve the issue . I have active Aramex account with all details, I setup plugin in woocommerce settings, but after click view cart show Aramex: ERR52 - Destination my city and address are invalid while I start shop as a guest. Also is it possible to disable ZIP code while use Aramex? Please any one with idea what cause this
the zipcode requirements are based on each country , for eg: GCC countries do not need zip code and most other countries need zipcode.
You can have WooCommerce override the default setting that makes the field required by adding a filter to your theme's functions.php. It would be best practice is to create a child theme so it won't get overwritten each time you update the theme.
For example, this code will remove the "required" state from the billing and shipping postal codes during checkout (if the shipping country is not 'US'):
add_filter( 'woocommerce_checkout_fields','custom_override_default_address_fields' );
function custom_override_default_address_fields($fields){
global $woocommerce;
$country = $woocommerce->customer->get_shipping_country();
if($country !== 'US'){
$fields['billing']['billing_postcode']['required'] = false;
$fields['shipping']['shipping_postcode']['required'] = false;
}
return $fields;
}
For more details on filters and fields available to edit via filtering see WooCommerce Customizing checkout fields using actions and filters doc

Woocommerce product archive displays nothing when called from custom Page

I have a woocommerce shop page which shows me all of the products perfectly. This page is also set as the "Shop" page in the settings. Now I want a second page called Home, which should use the same template as the shop page. (basically a second shop page without categories and some news)
home-template.php
<?php /* Template Name: Homepage */
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
wc_get_template( 'archive-product.php' );
?>
I'm using the standard archive-product template from woocommerce's github.
I can see the template being loaded, like the header, but certain woocommerce functions don't return the expected value. woocommerce_before_shop_loop doesn't return anything, even though it should display the orderby dropdown. woocommerce_product_loop() returns true, but wc_get_loop_prop('total') returns zero.
I've also tried renaming the file to front-page.php but that didn't help. The home page is set correctly in the reading settings.
Am i missing a call to a query, or is it something else? Thank you in advance for your help!
When WooCommerce creates the builtin shop page it saves the id of the created page in the wp_options database table with option_name 'woocommerce_shop_page_id'. When WordPress loads a page WooCommerce checks if the page id of the page being loaded is equal to the option_value of option_name 'woocommerce_shop_page_id' and then executes code to generate the HTML of the shop page. If you have looked at the shop page in the page editor you will notice that the content is empty. The magic is being done with hard coded routines that execute for this special id.
Since, your custom page has a different page id none of the custom code for generating the shop page will be execute. So, you need to execute this magic code for your custom page. It can be done but you need a good understanding of WooCommerce.
I suggest you reconsider your design and instead of a new page just customize the existing shop page using actions and filters.

Should I use wp_reset_postdata() or just save the global $post variable myself?

I have a Wordpress 4.3 site that uses Yoast for SEO. I have a custom post type and a shortcode that can be used to generate a list of posts of that type. The shortcode function uses what I believe to be the recommended approach in Wordpress for generating a list of posts of a certain type:
$query = new WP_Query(...);
while ($query->have_posts())
{
$query->the_post();
// Now I can call methods like the_ID(), the_permalink(), etc
// I can also access details of the post directly, because at
// this point it is stored in the global $post variable.
}
wp_reset_postdata(); // To restore original copy of global $post variable
When viewing the actual page that contains the shortcode, everything works fine because the global $wp_query variable stashes a copy of the global $post variable before the shortcode function gets called, which enables wp_reset_postdata() to successfully restore the state of the global $post variable.
However, I recently discovered a problem when editing the page and although I have fixed the issue, I would like to know if my solution is correct practice in the Wordpress world.
The problem was that whenever I edited the page, several fields would get changed without me having actually touched any of the settings. Further investigation revealed that the reason for this was that the HTML for the edit page, specifically the contents of some form fields, had already been altered by the time they reached my browser. Compounding this problem was the fact that the permalink field, which is highly visible, was not being altered, but a hidden field called slug was being altered, and so when the page was submitted, Wordpress was updating the permalink with the value of this now corrupted, hidden slug field. My permalink wasn't so perma after all!
The only clue I had about what was causing the problem was that the permalink that was being set belonged to another post; in fact, one of the posts that comes up when the shortcode function gets executed.
After a day and a half of debugging, I figured out the precise reason why the form fields were being trashed:
When preparing the edit page for a post, Wordpress calls all the related plugins in case they need to add any additional information or controls to the sidebar.
One such plugin is Yoast, which reports an SEO Status. In order to calculate this status, Yoast silently renders the post so that it can then analyse the contents of the page, taking into account the focus keywords, etc.
In order for Yoast to silently render a page, all of the shortcode functions that contribute output to that page must also be executed.
When my shortcode function gets executed as part of Yoast's silent page rendering, it does what I beleive to be the right thing by calling wp_reset_postdata() at the end to restore the contents of the global $post variable.
However, the problem was that wp_reset_postdata() was not, in fact, restoring the global $post variable, because the global $wp_query variable did not have a copy. I would have expected wp_reset_postdata() or WP_Query->reset_postdata() to throw an error at that point, but they don't.
So every form field in the edit page that was generated after Yoast did its work ended up with values from the wrong post, because the global $post variable had been left with the wrong contents.
I have resolved the problem by adding the following defensive/unobtrusive code to the top of my shortcode function:
global $wp_query;
if ( $wp_query->post == null )
{
return '';
}
This means my shortcode function will only execute "the loop" when there is a guarantee that it will be able to restore the global $post variable using wp_reset_postdata().
Should I stick to this solution or take it one step further and simply save a copy of the global $post variable myself and just ignore wp_reset_postdata() altogether?

how to hide a page from being seen in wordpress backend and frontend

In my plugin i have created a custom template that prints a requested sidebar. and for running the code of this template i assigned a custom page to it (by calling update_metadata) .
Is it a good idea for getting content of a specific sidebar into Ajax call ?
Now my problem is that WORDPRESS shows it in the dashboard and front page , and after searching i have not found any easy to understand solution for Hiding a page completely so only can be accessed by its id .
Can any one tell me how to do that ?
you are going about this the wrong way. You can create a function that can create anything that can be created on a wordpress page.
But if you really must you can create a page outside of the database, etc:
add_action('init', 'add_rewrite_rule');
function add_rewrite_rule(){
// add_rewrite_rule(REGEX url, location, priority (i.e. top is before other rewrite rules)
// I created a custom post type for this plugin called market -- replace post_type with whatever you want
//basically tell wordress to add a query var if sidebar is added to url.
add_rewrite_rule('^sidebar?','index.php?is_sidebar_page=1&post_type=market','top');
}
// register a query var
add_action('query_vars','market_set_query_var');
function market_set_query_var($vars) {
array_push($vars, 'is_sidebar_page');
return $vars;
}
// associate a template with your quer_var
add_filter('template_include', 'market_include_template', 1000, 1);
function market_include_template($template){
if(get_query_var('is_sidebar_page')){
$new_template = (theme or plugin path).'/pages/yourpage.php'; // change this path to your file
if(file_exists($new_template))
$template = $new_template;
}
return $template;
}
This will not be a page that will be in the admin section or in any query that relates to pages but someone could of course navigate to this page. But as i said above you would be better to create a function to create your sidebar. If you want a seperate file to handle the "view" you use require_once 'filename'; a file and keep your functions area free of html.
If you are creating functions in a wordpress plugin dont forget many functions may not be available until later in the load process. Use add_action() if you run into any undefined functions
edit:
you are loading wordpress before you get to the template so you have all the functions. (google wp load for more info) + get_header() / get_footer() will also load a few things like css, etc. I had a small typo in the code above, fixed that but basically what you are doing is telling wordpress if someone lands on www.example.com/sidebar to apply a query_var (rewrite rule). Wordpress will look up its saved vars (final function) and return the template assoc. The 2nd function just registers the var.
You also have wp_functions in any file you create and include in a plugin, etc hence why you can create a file that does exactly the same as this page.

Resources