I am adding a shortcode from wordpress to woocommerce email template.
do_shortcode('[sample_test name="additional_gift_msg"]);
Then i am using this to display the value in email. I am able to display value.
function th_email_shortcode_handler( $atts ) {
if ( ! empty( $atts['name'] ) ) {
$field = $atts['name'];
echo 'Found me';
}
}
add_shortcode('sample_test','th_email_shortcode_handler');
But i need $order or $order_id inside this handler function to take some value from post meta. How can i use those variables? The shortcode handler function is in functions.php
Also i tried the following but still $order_id is empty.
do_shortcode('[sample_test name="additional_gift_msg" order_id=' . $order->get_id() . ']');
Below code will do the trick.
function th_email_shortcode_handler( $atts ) {
if ( ! empty( $atts['name'] ) ) {
$field = $atts['name'];
echo 'Found me';
}
global $wp;
$order_id = absint( $wp->query_vars['order_id'] );
if ( empty($order_id) || $order_id == 0 )
return; // Exit;
return $order_id;
}
add_shortcode('sample_test','th_email_shortcode_handler');
Related
There are many threads which deal with the topic "custom fields in WooCommerce emails" but I couldn't find the exact case I am struggling with.
I could achieve 50% of this project to display the field as a meta in the order table.
add_action( 'woocommerce_order_item_meta_end', 'custom_product_info', 20, 4 );
function custom_product_info ( $item_id, $item, $order, $plain_text ) {
$id = $item->get_product_id();
$erlebnisidgc = get_field('erlebnis_id',$id);
if($erlebnisidgc){
echo "<p>Here's your Link</p><a href=https://b-ceed.de/?eventid='.$erlebnisidgc'>Testlink</a>";
}
}
So this code works perfectly with the custom field. Problem is that this output isn't shown only in the customer_completed_order email but also in all other emails.
Therefore, I tried this code snippet:
add_action( 'woocommerce_order_item_meta_end', 'custom_product_info', 20, 4 );
function custom_product_info ( $item_id, $item, $order, $plain_text ) {
if ( $email->id == 'customer_completed_order' ) {
$id = $item->get_product_id();
$erlebnisidgc = get_field('erlebnis_id',$id);
if($erlebnisidgc){
echo "<p>Here's your Link</p><a href=https://b-ceed.de/?eventid='.$erlebnisidgc'>Testlink</a>";
}
}
}
But now the output won't be displayed in any email anymore and it triggers a internal server error. Any advice?
$email ($email->id) is not passed as argument to the woocommerce_order_item_meta_end hook, therefore it is undefined
So to target specific email notifications a workaround will be needed, this can be done by creating a global variable via the woocommerce_email_before_order_table hook
So you get:
// Setting global variable
function action_woocommerce_email_before_order_table( $order, $sent_to_admin, $plain_text, $email ) {
$GLOBALS['email_data'] = array(
'email_id' => $email->id, // The email ID (to target specific email notification)
'is_email' => true // When it concerns a WooCommerce email notification
);
}
add_action( 'woocommerce_email_before_order_table', 'action_woocommerce_email_before_order_table', 1, 4 );
function action_woocommerce_order_item_meta_end( $item_id, $item, $order, $plain_text ) {
// Getting the custom 'email_data' global variable
$ref_name_globals_var = $GLOBALS;
// Isset & NOT empty
if ( isset ( $ref_name_globals_var ) && ! empty( $ref_name_globals_var ) ) {
// Isset
$email_data = isset( $ref_name_globals_var['email_data'] ) ? $ref_name_globals_var['email_data'] : '';
// NOT empty
if ( ! empty( $email_data ) ) {
// Target specific emails, several can be added in the array, separated by a comma
$target_emails = array( 'customer_completed_order' );
// Target specific WooCommerce email notifications
if ( in_array( $email_data['email_id'], $target_emails ) ) {
// Get product ID
$product_id = $item->get_product_id();
// Get field
$erlebnisidgc = get_field( 'erlebnis_id', $product_id );
// Has some value
if ( $erlebnisidgc ) {
echo '<p>Here is your Link</p>';
echo 'Testlink';
}
}
}
}
}
add_action( 'woocommerce_order_item_meta_end', 'action_woocommerce_order_item_meta_end', 10, 4 );
Used in this answer:
Determine only for WooCommerce admin email notification
How to target other WooCommerce order emails
I have a woocommerce store.
Its an affiliate store.
I want that when clicked on the featured image on the shop page it goes to an external website
I have added below code to my function.php its working fine just need to know what code and where is to be added to open it in a new tab
**<?php // Do not include this if already open!
/**
* Code goes in theme functions.php.
*/
add_action( 'template_redirect', 'redirect_external_products' );
function redirect_external_products() {
global $post;
if ( is_singular( 'product' ) && ! empty( $post ) && ( $product = wc_get_product( $post ) ) && $product->is_type( 'external' ) ) {
wp_redirect( $product->get_product_url() );
exit;
}
}**
There is no way to redirect in a new tab, I will suggest adding "target='_blank'" to the tag where you display the featured image with probably the same condition as in the function above. The hacky way maybe
add_action( 'template_redirect', 'redirect_external_products' );
function redirect_external_products() {
global $post;
if ( is_singular( 'product' ) && ! empty( $post ) && ( $product = wc_get_product( $post ) ) && $product->is_type( 'external' ) ) {
echo "<script> window.open(" . $product->get_product_url() . ", '_blank') </script>";
}
}
But I strongly suggest you not to go this way!!
I have a metabox (one checkbox) , in posts, to check if a post will be featured..
My code:
function add_featured_post_checkbox() {
add_meta_box(
'custom_featured_meta',
'Featured post for Sidebar',
'featured_post_checkbox_callback',
'Post',
'side',
'high'
);
} add_action( 'add_meta_boxes', 'add_featured_post_checkbox' );
Callback function:
function featured_post_checkbox_callback( $post ) {
wp_nonce_field( 'custom_save_data' , 'custom_featured_nonce' );
$featured = get_post_meta($post->ID, '_featured_post', true);
echo "<label for='_featured_post'>".__('Is Featured? ', 'foobar')."</label>";
echo "<input type='checkbox' name='_featured_post' id='featured_post' value='1' " . checked(1, $featured) . " />";
}
Save function:
function custom_save_data( $post_id ) {
if( ! isset( $_POST['custom_featured_nonce'] ) ){
return;
}
if( ! wp_verify_nonce( $_POST['custom_featured_nonce'], 'custom_save_data') ) {
return;
}
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
return;
}
if( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if( ! isset( $_POST['_featured_post'] ) ) {
return;
}
$my_data_featured = sanitize_text_field( $_POST['_featured_post'] );
update_post_meta( $post_id, '_featured_post', $my_data_featured );
} add_action( 'save_post', 'custom_save_data' );
This code works well only when I want to make a post featured..
For example if a post is not checked as featured and I select the choice then database updated perfect (with value 1 in post_meta) and the ckeckbox has the tick on box
But after, If I try to uncheck and save the post then the ckeckbox is again with the tick and nothing changed in database..
I try to find a solution for days on stackoverflow and general in web but I can't find.
Please help me
Thank you
When a checkbox is unchecked, $_POST will not contain the key _featured_post. Therefore, in your save callback, you need to change your strategy. You do not want to bail out if the key is not set. Rather, you either want to save a 0 or delete the post meta. Let's go with the later option.
function custom_save_data( $post_id ) {
if( ! isset( $_POST['custom_featured_nonce'] ) ){
return;
}
if( ! wp_verify_nonce( $_POST['custom_featured_nonce'], 'custom_save_data') ) {
return;
}
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
return;
}
if( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( isset( $_POST['_featured_post'] ) ) {
update_post_meta( $post_id, '_featured_post', 1 );
} else {
delete_post_meta( $post_id, '_featured_post' );
}
}
Notice that you do not need to use sanitize_text_field(). Why? Because the value will only be a 1. That's it. Here we can hardcode that value.
Another Problem I Saw
Running your code I saw that upon being checked, the HTML for checked=checked is being rendered as text. Why? Because running the function checked() will echo it out to the browser unless you tell it not to. You'd have to check your code to:
checked(1, $featured, false);
That's happening because of return after the check if _featured_post is set in $_POST array. It's not set when you do not check the checkbox. Your approach here should be next
if (isset($_POST['_featured_post']))
{
update_post_meta($object_id, '_featured_post', 1); // can only be 1 when checked anyway
}
else
{
delete_post_meta($object_id, '_featured_post');
}
Using the shortcode [add_to_cart_url sku="#"] will generate a link that will take the shopper to the single product page ONLY IF the product has variations.
What if I want a simple product (a product without variations) to link to its single product page instead of adding it to the cart?
IMO, this seems overlooked by the WooCommerce team.
All I want is a generated link to an item's single product page based on its SKU. Something as simple as implementing [product_url sku="#"] would be great.
Otherwise, searching Google has revealed no success.
Is this what you want ?
Below code is for the shortcode of Product URL only and you can use it with like :
[product_url sku="SKUofProduct"] or with ID [product_url id="productID"]
add_shortcode( 'product_url', 'rohils_product_url_function' );
function rohils_product_url_function($atts){
global $wpdb;
if ( empty( $atts ) ) {
return '';
}
if ( isset( $atts['id'] ) ) {
$product_data = get_post( $atts['id'] );
} elseif ( isset( $atts['sku'] ) ) {
$product_id = wc_get_product_id_by_sku( $atts['sku'] );
$product_data = get_post( $product_id );
} else {
return '';
}
if ( 'product' !== $product_data->post_type ) {
return '';
}
$_product = wc_get_product( $product_data );
return esc_url( get_post_permalink($_product->id) );
}
hi all here is my function
function save_urun_meta_price( $post_id ) {
$slug = 'urun';
if ( $slug != $_POST['post_type'] ) {
return;
}
// - Update the post's metadata.
if ( isset( $_REQUEST['urun_indirimli_fiyat'] ) ) {
$product_price = get_post_meta( $post_id, 'urun_fiyat', true );
$product_discount = of_get_option('urun_discount');
$yuzde = ($product_discount / 100)*$product_price;
$discounted = $product_price-$yuzde;
update_post_meta( $post_id, 'urun_indirimli_fiyat', $discounted );
}
}
add_action( 'save_post', 'save_urun_meta_price' );
add_action( 'edit_post', 'save_urun_meta_price' );
When user write some price into the urun_fiyat meta field i want to calculate this price with % discount field from the options framework panel.
Than i want to put new price another meta field urun_indirimli_fiyat..
What is wrong with my function ?
Thanks.
Try using the below code. I think the problem was with the product price variable. You were trying to get the value from post meta ( which does not exist )
Getting the value from $_POST variable will do the trick I guess.
function save_urun_meta_price( $post_id ) {
$slug = 'urun';
if ( $slug != $_POST['post_type'] ) {
return;
}
// - Update the post's metadata.
if ( isset( $_REQUEST['urun_indirimli_fiyat'] ) ) {
$product_price = $_POST['urun_fiyat'];
$product_discount = of_get_option('urun_discount');
$yuzde = ($product_discount / 100)*$product_price;
$discounted = $product_price-$yuzde;
update_post_meta( $post_id, 'urun_indirimli_fiyat', $discounted );
}
}
add_action( 'save_post', 'save_urun_meta_price' );
add_action( 'edit_post', 'save_urun_meta_price' );