I've driven myself crazy looking for this all over the internet on how I would go around sorting this.
So I need to add a new form below the variations on WooCommerce, and get this to post through to the checkout and then into the order notes once payment has been processed. I have got the select fields added to the product view page (front end) using the code below, but now I need to somehow get this to post to the basket and checkout and then into the order in the backend, but not sure where to start with a function doing this.
add_action( 'woocommerce_before_add_to_cart_button', 'espresso_add_flavour_field', 0 );
function espresso_add_flavour_field() {
global $post;
global $product;
// Show this only on the subscription boxes
$product_type = $product->get_type();
if( $product_type == 'variable-subscription' ){
echo "<div class='pick-flavor'>";
//echo get_post_meta( $post->ID, 'Product Code', true );
echo "Please select your favorite flavors we can include in your subscription box*<br>";
$flavors = ( get_terms('pa_do-not-use-sub-flav', array('hide_empty' => false) ) );
echo '<select name="_redeem_in_stores[]" class="chosen-select" multiple="multiple">';
foreach($flavors as $flavor){
echo '<option>' . $flavor->name . '</option>';
}
echo "</select>";
echo "</div>";
}
return true;
}
I have finally found what I've been looking for on this guide:
https://wisdmlabs.com/blog/add-custom-data-woocommerce-order/
Related
I have products with two variations (Color & Country). I needed an enquery form for the out of stock products which this thread completely cover it but since my contact form is being surrounded with an Accordion element I need to display all the selected variations name inside the accordion title once the user select variations.
/** Quote form for out of stock variation products */
add_action( 'woocommerce_single_product_summary', 'add_product_outofstock_contact_form', 30, 2 );
function add_product_outofstock_contact_form() {
global $product;
$product_title = $product->get_name();
$selected_variations = // ---> I need help about it
$cf7form_title = sprintf(__( 'Request a quote for %s - %s', 'pro-child' ), $product_title, $selected_variations );
$cf7form = do_shortcode('[contact-form-7 id="2485" title="make order en"]'); // Here the contact form shortcode
$contact_form = do_shortcode('[accordion id="get-quote"] [accordion_item title="'.$cf7form_title.'" parent_id="get-quote"] '.$cf7form.' [/accordion_item][/accordion]'); // Here the accordion shortcode which involves the contact form
if( $product->is_type('variable') ) {
echo '<div class="outofstock-form" style="display:none">' . $contact_form . '</div>';
} elseif( ! $product->is_in_stock() ) {
echo $contact_form;
?>
<script type="text/javascript">
jQuery(function($) {
var id = <?php echo $product->get_id(); ?>,
name = '<?php echo $product->get_name(); ?>';
$('input[name="your-product"]').val(name+' ('+id+')');
});
</script>
<?php
}
}
How get all selected variations and return them inside the $selected_variations variable?
I am using the following code to show custom product meta in the order items table on the WooCommerce admin order details page:
add_action('woocommerce_admin_order_item_headers', 'tempiconsegna_admin_order_item_headers');
function tempiconsegna_admin_order_item_headers() {
$column_name = 'Tempi Consegna';
echo '<th>' . $column_name . '</th>';
}
add_action('woocommerce_admin_order_item_values', 'tempiconsegna_admin_order_item_values', 10, 3);
function tempiconsegna_admin_order_item_values($_product, $item, $item_id = null) {
$value = get_post_meta($_product->post->ID, 'prefix-tempiconsegna', 1);
echo '<td>' . $value . '</td>';
}
It displays "prefix-tempiconsegna" which are custom metas like:
Available in 3 days
Available now
etc..
My problem is that if I change the availability in the product, it changes also in previous orders.
How do i make this displaying the value at the moment of the order without changing when I update the availability of the product?
Your current code contains 2 errors:
Attempt to read property "post" on null
Attempt to read property "ID" on null
To answer your question: that's because you're using get_post_meta() and the productID, so if you adjust the data for the product it will also change the data where it is displayed, in your case the current and previous orders.
To prevent this, you have to add the data per order line item, this can be done via:
function action_woocommerce_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
// The WC_Product instance Object
$product = $item->get_product();
// Get value
$value = $product->get_meta( 'prefix-tempiconsegna' );
// NOT empty
if ( ! empty ( $value ) ) {
$item->update_meta_data( 'prefix-tempiconsegna', $value );
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'action_woocommerce_checkout_create_order_line_item', 10, 4 );
Then to display this in WooCommerce admin order details page, use:
// Add header
function action_woocommerce_admin_order_item_headers( $order ) {
// Set the column name
$column_name = __( 'Tempi Consegna', 'woocommerce' );
// Display the column name
echo '<th class="my-class">' . $column_name . '</th>';
}
add_action( 'woocommerce_admin_order_item_headers', 'action_woocommerce_admin_order_item_headers', 10, 1 );
//Add content
function action_woocommerce_admin_order_item_values( $product, $item, $item_id ) {
// Only for "line_item" items type, to avoid errors
if ( ! $item->is_type('line_item') ) return;
// Get value
$value = $item->get_meta( 'prefix-tempiconsegna' );
// NOT empty
if ( ! empty ( $value ) ) {
echo '<td>' . $value . '</td>';
} else {
echo '<td>Meta not found!</td>';
}
}
add_action( 'woocommerce_admin_order_item_values', 'action_woocommerce_admin_order_item_values', 10, 3 );
We use this code to display the used coupons on a order. This is working fine! But now we want to show this information also in the order quick view.
I found this hook here: woocommerce_admin_order_preview_end
So i tried to change the hook from the code below with this hook. But then the quick view function does not work at all. When we click on the "eye" to open the quick view - nothing happend. Do we have to adjust the code more or what is here the problem?
add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
/**
* Add used coupons to the order edit page
*
*/
function custom_checkout_field_display_admin_order_meta($order){
if( $order->get_used_coupons() ) {
$coupons_count = count( $order->get_used_coupons() );
echo '<h4>' . __('Coupons used') . ' (' . $coupons_count . ')</h4>';
echo '<p><strong>' . __('Coupons used') . ':</strong> ';
$i = 1;
foreach( $order->get_used_coupons() as $coupon) {
echo $coupon;
if( $i < $coupons_count )
echo ', ';
$i++;
}
echo '</p>';
}
}
Try to use the following to display coupon used in admin order quick view (preview):
// Add custom order data to make it accessible in Order preview template
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'admin_order_preview_add_custom_data', 10, 2 );
function admin_order_preview_add_custom_data( $data, $order ) {
// Replace '_custom_meta_key' by the correct postmeta key
if( $coupons = $order->get_used_coupons() ) {
$data['coupons_count'] = count($coupons); // <= Store the count in the data array.
$data['coupons_codes'] = implode(', ', $coupons); // <= Store the count in the data array.
}
return $data;
}
// Display The data in Order preview
add_action( 'woocommerce_admin_order_preview_end', 'custom_display_order_data_in_admin' );
function custom_display_order_data_in_admin(){
// Call the stored value and display it
echo '<div><strong>' . __('Coupons used') . ' ({{data.coupons_count}})<strong>: {{data.coupons_codes}}</div><br>';
}
Code goes in functions.php file of the active child theme (or active theme). Untested it should works.
Based on: Display custom data on Woocommerce admin order preview
In woocommerce, I'm building a website which sells vintage maps. I need to find a way to pass the product id and variation id from the woocommerce shop to the single product page for two separate variations using buttons without adding the product to the cart.
There are two product types, the original map (of which there is obviously only one) and digital prints which are infinite.
I've separated these by creating a variable product with attributes 'original' and 'digital prints'. there is one variation per attribute so that much is pretty simple.
The company want these two options ('original' and 'digital prints') to appear in the woocommerce shop front page as buttons.
The idea is that the 'original' button will only appear if the original is in stock (again, simple to achieve).
The problems start here:
The idea is that when either of these buttons are pressed it won't add the product to the cart but will go to the appropriate single product page and there, based on the variation type, there will be a range of options to select whether the map is framed and mounted, if it's digital how large the print should be etc. etc. Once selected, the product can then be added to the cart using the add to cart button on the single product page.
What I can't seem to do at the moment is send the information to the single product page without adding it to the cart(!)
The code I'm currently using uses woocommerce_after_shop_loop_item and woocommerce_single_variation to overwrite default add to cart button and replace it with the following but obviously this is still adding the product to the cart. Looking at the code, it's verbose and obviously over complicating things but I'm stumped. the add to cart button needs to be replaced with something that simply moves to the single product page and takes the product id and variation id with it but I don;t know what. In theory you can serialise it into an array and send as $_GET attached to an anchor but apart from the potential security issues this could give rise to, it looks shoddy in the toolbar.
So, in summary. I need to find a way to pass the product id and variation id from the woocommerce shop to the single product page for two separate variations using buttons without adding the product to the cart. Any ideas?
Code below:
function mc_loop_variation_add_to_cart_button() {
global $product;
$product_obj = new WC_Product_Factory();
$product = $product_obj->get_product($product);
if ($product->product_type == 'variable'):
$children = $product->get_children( $args = '', $output = OBJECT );
foreach ($children as $key=>$value) {
$product_variatons = new WC_Product_Variation($value);
if ( $product_variatons->exists() && $product_variatons->variation_is_visible() ) {
$variations[$value] = $product_variatons->get_variation_attributes();
foreach ($variations[$value] as $key=>$value) {
$stock = $product_variatons->get_stock_quantity();
$product_price = $product_variatons->regular_price;
if($value=="original") {
if($stock > 0) {
echo "Price: £" . $product_price;
?>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php
?>
<button type="submit" class="single_add_to_cart_button button">Buy <?php //echo $value; ?></button>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="<?php echo $value; ?>" />
</div>
<?php
} else {
echo "";
}
} else {
echo "Price: £" . $product_price;
?>
<div class="woocommerce-variation-add-to-cart variations_button">
<button type="submit" class="single_add_to_cart_button button">Buy <?php echo $value; ?></button>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->get_id() ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="<?php echo $value; ?>" />
</div>
<?php
}
?>
<?php
}
}
}
endif;
}
For variable products with a specific attribute for variations in archives pages as shop, the following code will:
Remove the default price range
Remove add to cart
Add 2 buttons with prices linked to product variations
The buttons links will take the customer to the right preselected variation in the variable product.
You will need to define in the first function the product attribute that has 'original' and 'digital-prints' term values. You need to define in the 2nd function the product attribute term slugs.
For the prints, we display the min price with something like Price from: $123.00.
The code:
add_action( 'woocommerce_after_shop_loop_item_title', 'loop_custom_variable_products', 2 );
function loop_custom_variable_products() {
global $product;
// HERE define the product attribute (for 'original' and 'digital-prints' term values
$attribute = 'type'; // <==== <==== <==== <==== <==== <==== <==== <==== <====
// Only variable products
if ( $product->get_type() === 'variable' && $product->get_attribute($attribute) ) :
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 ); // Remove price
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 ); // remove add to cart
add_action( 'woocommerce_after_shop_loop_item', 'loop_variations_custom_buttons_and_prices', 10 ); // Add prices with custom buttons
endif;
}
function loop_variations_custom_buttons_and_prices() {
global $product;
if ( $product->get_type() === 'variable' ) :
// HERE define your targeted slugs for the defined product attribute
$targeted_slugs = array('original', 'digital-prints'); // <==== <==== <==== <====
$found_original = $found_a_print = false;
$data = $url_var = [];
$min_price_html = __("Price from: ") . strip_tags( wc_price( $product->get_variation_price( 'min', true ) ) );
// Loop through product variations ids
foreach ($product->get_children() as $variation_id ){
// Get the WC_Product_Variation Object
$variation = wc_get_product( $variation_id );
if ( $variation->is_type('variation') && $variation->variation_is_visible() && $variation->variation_is_active() ) {
$stock_qty = $variation->get_stock_quantity();
$price_html = __("Price: "); strip_tags( wc_price( wc_get_price_to_display( $variation ) ) );
$attributes = $variation->get_variation_attributes();
// Loop through variation attributes
foreach ( $attributes as $attribute => $term_slug ) {
if( $term_slug === $targeted_slugs[0] ) {
$data[$term_slug]['price'] = $price_html . strip_tags( wc_price( wc_get_price_to_display( $variation ) ) );
$data[$term_slug]['stock'] = $stock_qty > 0 ? true : false;
$found_original = true;
}
if( $term_slug === $targeted_slugs[1] ) {
$data[$term_slug]['price'] = $min_price_html;
$data[$term_slug]['stock'] = true;
$targeted_attribute = $attribute;
$found_a_print = true;
}
}
}
if( $found_original && $found_a_print) {
// If both are found we stop the main loop
break;
}
}
// Output prices and buttons
foreach( $targeted_slugs as $slug ) {
if( isset($data[$slug]) && $data[$slug]['stock'] ) {
echo '<div class="variation-' . $slug . '">
<div class="price" style="margin-bottom:14px;">' . $data[$slug]['price'] . '</div>';
foreach( $attributes as $key => $value ){
if( isset($targeted_attribute) && $targeted_attribute === $key ) {
$url_var[] = $key . '=' . $slug;
} else {
$url_var[] = $key . '=null';
}
}
$href = $product->get_permalink() . '?' . implode('&', $url_var);
echo '' . __ ("Buy") . ' ' . str_replace('-', ' ', $slug) . '
</div>';
}
}
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
You will get something like:
i am using advanced custom filed and i made custom author field (it could be Publisher Or Brand etc) now this author's name is not printing on product (Book) page . in custom field its for author's name slug is 'names'
add_action( 'woocommerce_after_single_product_summary', "ACF_product_content", 10 );
function ACF_product_content(){
echo '<h2> ACF Content </h2>';
if (function_exists('the_field')){
echo '<p>Woohoo, the_field function exists! </p>';
//the_field('authors');
echo '<pre>';
print_r(get_the_ID());
echo '</pre>';
echo '<pre>';
print_r(get_field('authors'));
echo '</pre>';
die;
}
}
for this i got the result
Check this report screenshot
. now problem is to show the Authors name which is ['post_title'] in this array.
i tried so many solutions but not working its not showing the result.
i used to show this result by this code
echo the_field('names');
'names' is the field name in 'Authors' custom field.
try this code for ACF
<?php
echo get_field('your custom filed slug name',get_the_ID());
?>
fetch the post title
<?php echo get_the_title(); ?>
for display author name for below function
<?php echo get_the_author(); ?>
You may use one of the methods below . You have to strictly set $post otherwise get_the_ID() funtion return false.
global = $post;
$custom_key = 'author';
$post_id = get_the_ID();
echo $customer_key_value = get_post_meta( $post_id, $custom_key , true );
OR
global = $post;
$custom_key = 'author';
$post_id = get_the_ID();
$custom_values = get_post_custom_values( $custom_key , $post_id );
foreach ( $custom_values as $key => $value ) {
echo "$key => $value <br />";
}