WooCommerce function to display total product sales on site homepage - woocommerce

I am trying to find a function and shortcode to display the total amount of products sold as simply as possible on our website.
Don't want to show product names or any info just a count.
I found this function / shortcode that displays total orders. Just wondering fo anyone can help adapt it to display total products sold?
Thanks so much..
function display_woocommerce_order_count( $atts, $content = null ) {
$args = shortcode_atts( array(
'status' => 'completed',
), $atts );
$statuses = array_map( 'trim', explode( ',', $args['status'] ) );
$order_count = 0;
foreach ( $statuses as $status ) {
// if we didn't get a wc- prefix, add one
if ( 0 !== strpos( $status, 'wc-' ) ) {
$status = 'wc-' . $status;
}
$order_count += wp_count_posts( 'shop_order' )->$status;
}
ob_start();
echo number_format( $order_count );
return ob_get_clean();
}
add_shortcode( 'wc_order_count', 'display_woocommerce_order_count' );

Related

Show order details in a new column on My account / order table

In WooCommerce, I would like to add a new column to the "My Account" orders table and show the order details.
I have this code, which adds the column, but the values don't show (e.g. get_formatted_meta_data).
Can anyone help rewrite the code to make it work?
function wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
if ( 'order-status' === $key ) {
$new_columns['order-details'] = __( 'Order details', 'textdomain' );
}
}
return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'wc_add_my_account_orders_column' );
function wc_my_orders_order_details_column( $order ) {
$order_details = get_post_meta( $order->get_id(), 'order_details', true );
echo ! empty( $order_details ) ? $order_details : '–';
}
add_action( 'woocommerce_my_account_my_orders_column_order_details', 'wc_my_orders_order_details_column' );
The woocommerce_my_account_my_orders_columns filter has been deprecated since WooCommerce 2.6.0. So although it still functions you should use the woocommerce_account_orders_columns filter to add an additional column.
To populate the column with your data you can use the woocommerce_my_account_my_orders_column_ action which expects you to append the column ID of your custom column. So in your case that would be order-details. In your example you've used order_details (with an underscore instead of a hyphen). That is why your data doesn't show up.
Also it is best practice to retrieve order meta data via the internal WooCommerce getter function get_meta() instead of using get_post_meta().
add_filter( 'woocommerce_account_orders_columns', 'wc_add_my_account_orders_column', 10, 1 );
function wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
if ( 'order-status' === $key ) {
$new_columns['order-details'] = __( 'Order details', 'textdomain' );
}
}
return $new_columns;
}
add_action( 'woocommerce_my_account_my_orders_column_order-details', 'wc_my_orders_order_details_column', 10, 1 );
function wc_my_orders_order_details_column( $order ) {
$item_meta = '';
foreach ( $order->get_items() as $item ) {
$item_meta .= wc_display_item_meta( $item, array( 'echo' => false ) );
}
echo !empty( $item_meta ) ? $item_meta : '-';
}

Woocommerce - Calculate Exta Fee Based on Amount of People

I've added in a function for a custom field on the product general options:
// Add Custom Field to Product under General
function create_extra_fee_field() {
$args = array(
'id' => 'park_fee',
'label' => __( 'Natl Park Entrance Fee', 'tranq-lsx-child' ),
'class' => 'tranq-custom-field',
'desc_tip' => true,
'description' => __( 'This sets the Fee that will be added to the car.', 'tranq-lsx-child' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'create_extra_fee_field' );
// Save Custom Field Data
function save_extra_fee_field( $post_id ) {
$product = wc_get_product( $post_id );
$title = isset( $_POST['park_fee'] ) ? $_POST['park_fee'] : '';
$product->update_meta_data( 'park_fee', sanitize_text_field( $title ) );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'save_extra_fee_field' );
I would like to add this as an extra fee to the Cart Totals which multiplied based on the amount of Person/People that were selected from the Woocommerce Bookings.
Something like this:
// Calculate Extra Fee Based on Amount of People.
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
function add_custom_fees( WC_Cart $cart ){
$park_fee = get_post_meta($item['product_id'] , 'park_fee', true);
foreach( $cart->get_cart() as $item ){
$fees += $item[ 'park_fee' ] * 14706;
}
if( $fees != 0 ){
$cart->add_fee( 'Park Fee', $fees);
}
}
How do I go about in achieving this? Any Links to a walkthrough would be greatly appreciated.
I've added this and it seems to work:
// Add Custom Field to Cart Totals
function woo_add_cart_fee() {
global $woocommerce;
foreach( WC()->cart->get_cart() as $cart_item ){
// Get the WC_Product object (instance)
$product = $cart_item['data'];
$product_id = $product->get_id(); // get the product ID
$custom_field_value = get_post_meta( $product->get_id(), 'park_fee', true );
$person = array_sum( $cart_item['booking']['_persons'] );
}
$additional_fee_name = "Natl Park Entrance Fee";
$extra_fee = $custom_field_value * $person;
$addedFee = false;
// first check to make sure it isn’t already there
foreach ( $woocommerce->cart->get_fees() as $_fee )
{
if ($_fee->id == sanitize_title($additional_fee_name) )
{
$_fee->amount = (float) esc_attr( $extra_fee );
}
}
if (!$addedFee)
{
$woocommerce->cart->add_fee( __($additional_fee_name, "woocommerce"),
$extra_fee, $additional_fee_taxable );
}
}
add_action( "woocommerce_before_calculate_totals", "woo_add_cart_fee" );

How to display woocommerce PRICE on product's BODY text - using SHORTCODE?

I'm writing some details of each prodcuts (short/long description) on woocommerce.
i'd like to insert a SHORTCODE inside the description that shows the current PRICE (sale / regular).
it should look something like that on the backend:
"Buy it now, for only [wc_price] $"
is there any shortcode i can use for that?
This is one the most simple snippet that does what you want without the need of inputting the id manually:
function my_shortcode_product_price() {
$html = '';
global $product;
$price = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) );
$args = array(
'ex_tax_label' => false,
'currency' => 'USD',
'decimal_separator' => '.',
'thousand_separator' => ' ',
'decimals' => 2,
'price_format' => '%2$s %1$s',
);
$html = "<span>" . wc_price( $price, $args ) . "</span>";
return $html;
}
add_shortcode( 'product_price', 'my_shortcode_product_price' );
The above code goes in the functions.php file of your active theme. After that you can use the shortcode like this:
[product_price]
Here You Go: add this code in your function.php
function short_code_woo_comm_desc( $atts ) {
$atts = shortcode_atts( array(
'id' => null
), $atts, 'tag_for_short_code_price' );
if ( empty( $atts[ 'id' ] ) ) {
return '';
}
$product = wc_get_product( $atts['id'] );
if ( ! $product ) {
return '';
}
return $product->get_price_html();
}
add_shortcode( 'tag_for_short_code_price', 'short_code_woo_comm_desc' );
Use:
[tag_for_short_code_price id="101"]

Woocommerce recently viewed Products

I have created a recently viewed script which generated a shortcode which I then inserted into my home page.
The script is designed so that people who may have visited my website and left, once they come back can see instantly what products they had been viewing on their last visit.
I have placed the shortcode [woocommerce_recently_viewed_products]
and have generated the shortcode using the following script:
function rc_woocommerce_recently_viewed_products( $atts, $content = null ) {
// Get shortcode parameters
extract(shortcode_atts(array(
"per_page" => '5'
), $atts));
// Get WooCommerce Global
global $woocommerce;
// Get recently viewed product cookies data
$viewed_products = ! empty( $_COOKIE['woocommerce_recently_viewed'] ) ? (array) explode( '|', $_COOKIE['woocommerce_recently_viewed'] ) : array();
$viewed_products = array_filter( array_map( 'absint', $viewed_products ) );
// If no data, quit
if ( empty( $viewed_products ) )
return __( 'You have not viewed any product yet!', 'rc_wc_rvp' );
// Create the object
ob_start();
wc_setcookie( 'woocommerce_recently_viewed', implode( '|', $viewed_products ) );
}
// Get products per page
if( !isset( $per_page ) ? $number = 4 : $number = $per_page )
// Create query arguments array
$query_args = array(
'posts_per_page' => $number,
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'post__in' => $viewed_products,
'orderby' => 'rand'
);
// Add meta_query to query args
$query_args['meta_query'] = array();
// Check products stock status
$query_args['meta_query'][] = $woocommerce->query->stock_status_meta_query();
// Create a new query
$r = new WP_Query($query_args);
// If query return results
if ( $r->have_posts() ) {
$content = '<ul class="rc_wc_rvp_product_list_widget">';
// Start the loop
while ( $r->have_posts()) {
$r->the_post();
global $product;
$content .= '<li>
<a href="' . get_permalink() . '">
' . ( has_post_thumbnail() ? get_the_post_thumbnail( $r->post->ID, 'shop_thumbnail' ) : woocommerce_placeholder_img( 'shop_thumbnail' ) ) . ' ' . get_the_title() . '
</a> ' . $product->get_price_html() . '
</li>';
}
$content .= '</ul>';
}
// Get clean object
$content .= ob_get_clean();
// Return whole content
return $content;
}
// Register the shortcode
add_shortcode("woocommerce_recently_viewed_products",
"rc_woocommerce_recently_viewed_products");
Everything seems to have registered. However,when I test this myself. I view a few products, go back to the homepage where the shortcode is registered and I see the text
You have not viewed any product yet!
I can not figure out what might be missing in order to register and show the products which I or a potential customer may have viewed.
Woocommerce only save the recently viewed cookie IF woocommerce_recently_viewed_products WIDGET is ACTIVE! See code in wc-product-functions.php wc_track_product_view() function.
Code to save the cookie always in functions.php:
/**
* Track product views. Always.
*/
function wc_track_product_view_always() {
if ( ! is_singular( 'product' ) /* xnagyg: remove this condition to run: || ! is_active_widget( false, false, 'woocommerce_recently_viewed_products', true )*/ ) {
return;
}
global $post;
if ( empty( $_COOKIE['woocommerce_recently_viewed'] ) ) { // #codingStandardsIgnoreLine.
$viewed_products = array();
} else {
$viewed_products = wp_parse_id_list( (array) explode( '|', wp_unslash( $_COOKIE['woocommerce_recently_viewed'] ) ) ); // #codingStandardsIgnoreLine.
}
// Unset if already in viewed products list.
$keys = array_flip( $viewed_products );
if ( isset( $keys[ $post->ID ] ) ) {
unset( $viewed_products[ $keys[ $post->ID ] ] );
}
$viewed_products[] = $post->ID;
if ( count( $viewed_products ) > 15 ) {
array_shift( $viewed_products );
}
// Store for session only.
wc_setcookie( 'woocommerce_recently_viewed', implode( '|', $viewed_products ) );
}
remove_action('template_redirect', 'wc_track_product_view', 20);
add_action( 'template_redirect', 'wc_track_product_view_always', 20 );
You need to set the cookie when you are viewing a single product page so use something like this where I set the cookie to equal the product ID I just viewed. In your case you'll need to get the cookie value if it exists then append the new product to the list of products.
function set_user_visited_product_cookie() {
global $post;
if ( is_product() ){
// manipulate your cookie string here, explode, implode functions
wc_setcookie( 'woocommerce_recently_viewed', $post->ID );
}
}
add_action( 'wp', 'set_user_visited_product_cookie' );
Below code to set cookie 'woocommerce_recently_viewed' worked for me. Hope it helps other
$Existing_product_id = $_COOKIE['woocommerce_recently_viewed'];
if ( is_product() )
{
$updated_product_id = $Existing_product_id.'|'.$post->ID;
wc_setcookie( 'woocommerce_recently_viewed', $updated_product_id );
}

How to make custom form-tag in contact form 7 required

So i make custom form-tag in contact form 7! It is a drop down with list of my courses and now I want to make it required because that is the main thing in whole form.
So can someone give me a tip how to do that?
When I do the [myCustomField* course-name class:custom-field]
It does not working with *
So if someone can help it will be great!
I have been working on this myself this afternoon and I do not think Mahmoud has added everything that is needed to get the validation working well and the messages showing up.
using what I have learnt from the posts on contact form 7 here:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/
and looking at this file in the plugin: contact-form-7/modules/select.php which helped a lot.
I think this will work better and needs to be added to your functions.php file in your child-theme.
add_action( 'wpcf7_init', 'custom_add_form_tag_myCustomField' );
function custom_add_form_tag_myCustomField() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*' ),
'custom_myCustomField_form_tag_handler', true );
}
function custom_myCustomField_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$validation_error = wpcf7_get_validation_error( $tag->name );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts = array();
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
if ( $tag->is_required() ) {
$atts['aria-required'] = 'true';
}
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$myCustomField = '';
$query = new WP_Query(array(
'post_type' => 'CUSTOM POST TYPE HERE',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
));
while ($query->have_posts()) {
$query->the_post();
$post_title = get_the_title();
$myCustomField .= sprintf( '<option value="%1$s">%1$s</option>',
esc_html( $post_title ) );
}
wp_reset_query();
$myCustomField = sprintf(
'<span class="wpcf7-form-control-wrap %1$s"><select %2$s>%3$s</select>%4$s</span>',
sanitize_html_class( $tag->name ),
$atts,
$myCustomField,
$validation_error
);
return $myCustomField;
}
That is how we create the custom tag. The important differences here are the addition of the $validation_error variables as wells the aria-required and aria-invalid data. It is also important to include the $validation_error in the final output so that we can see the validation messages being created.
Then to finish it off we need to add some validation via filters.
There is no documentation on this yet, but I used the functions from the select.php and altered them to what I needed.
/* Validation filter */
add_filter( 'wpcf7_validate_myCustomField', 'wpcf7_myCustomField_validation_filter', 10, 2 );
add_filter( 'wpcf7_validate_myCustomField*', 'wpcf7_myCustomField_validation_filter', 10, 2 );
function wpcf7_myCustomField_validation_filter( $result, $tag ) {
$tag = new WPCF7_FormTag( $tag );
$name = $tag->name;
if ( isset( $_POST[$name] ) && is_array( $_POST[$name] ) ) {
foreach ( $_POST[$name] as $key => $value ) {
if ( '' === $value ) {
unset( $_POST[$name][$key] );
}
}
}
$empty = ! isset( $_POST[$name] ) || empty( $_POST[$name] ) && '0' !== $_POST[$name];
if ( $tag->is_required() && $empty ) {
$result->invalidate( $tag, wpcf7_get_message( 'invalid_required' ) );
}
return $result;
}
This code should also go in your functions.php file just under the code for the custom CF7 tag.
Here the filter's first string $tag should match with the class that is being generated in the custom CF7 tag so if your custom tag->type = 'myCustomField' then the $tag of the filter must include the name, like so wpcf7_validate_myCustomField as well as the required version of it, wpcf7_validate_myCustomField*.
I hope that helps anyone else looking for this.
If you want even more of the options available from the backend of Contact Form 7 check the select.php file as it lays it out quite nicely on how to get each option and include it.
You can use [select*] to output a required drop-down menu.
[select* course-name include_blank "English" "Math"]
Check https://contactform7.com/checkboxes-radio-buttons-and-menus/
EDIT:
So you have your own shortcode [myCustomField]. To make two versions of your shortcode as [myCustomField] and [myCustomField*] you have to pass both shortcodes to your function as the following:
add_action( 'wpcf7_init', 'wpcf7_add_form_tag_mycustomfield' );
function wpcf7_add_form_tag_mycustomfield() {
wpcf7_add_form_tag( array( 'myCustomField', 'myCustomField*'),
'wpcf7_mycustomfield_form_tag_handler', array( 'name-attr' => true ) );
}
function wpcf7_mycustomfield_form_tag_handler( $tag ) {
$tag = new WPCF7_FormTag( $tag );
if ( empty( $tag->name ) ) {
return '';
}
$atts = array();
$class = wpcf7_form_controls_class( $tag->type );
$atts['class'] = $tag->get_class_option( $class );
$atts['id'] = $tag->get_id_option();
$atts['name'] = $tag->name;
$atts = wpcf7_format_atts( $atts );
$html = sprintf( '<your-tag %s></your-tag>', $atts );
return $html;
}
Then, you can use it:
[myCustomField course-name class:custom-field]
or
[myCustomField* course-name class:custom-field]
References:
https://contactform7.com/2015/01/10/adding-a-custom-form-tag
https://contactform7.com/2015/02/27/using-values-from-a-form-tag/

Resources