I'm using a Wordpress plugin called EventOn Tickets which offers ticket purchases. Woocommerce Addon Fields display on regular products but not on the EventOn tickets. I'm looking for help to have the Woocommerce Addon Fields added to the Eventon Tickets checkout and be functional.
Here is the problem code that only displays the "Add to Cart" button with a quantity. Using standard Woocommerce Variable Products it works but that doesn't allow me to display the options as I would like and I like the data entry with Woocommerce Product Addons.
<p itemprop="price" class="price tx_price_line"><?php echo eventon_get_custom_language($opt, 'evoTX_002ff','Price').': '. $product->get_price_html(); ?></p>
<form class='tx_orderonline_single' data-producttype='single' method="post" enctype='multipart/form-data'>
<div class='tx_orderonline_add_cart'>
<?php
// calculate correct max capacity
$max_quantity = ($capacity_of_this_repeat!='none') ? $capacity_of_this_repeat:
($product->backorders_allowed() ? '' : $product->get_stock_quantity());
if ( ! $product->is_sold_individually() )
woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', 1, $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $max_quantity, $product )
), $product );
?>
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
<button data-product_id='<?php echo $woo_product_id;?>' id='cart_btn' class="evoAddToCart evcal_btn single_add_to_cart_button button alt"><?php echo apply_filters('single_add_to_cart_text', eventon_get_custom_language($opt, 'evoTX_002','Add to Cart'), $product->product_type); ?></button>
<div class="clear"></div>
</div>
</form>
Product addons are displayed on the woocommerce_before_add_to_cart_button hook (see the constructor of the Product_Addon_Display class). So as long as you have a do_action( 'woocommerce_before_add_to_cart_button' ); action hook then the addons should display.
Making sure that your form has the standard WooCommerce hooks will help it support more WooCommerce extensions.
<p itemprop="price" class="price tx_price_line"><?php echo eventon_get_custom_language($opt, 'evoTX_002ff','Price').': '. $product->get_price_html(); ?></p>
<?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<form class='tx_orderonline_single' data-producttype='single' method="post" enctype='multipart/form-data'>
<div class='tx_orderonline_add_cart'>
<?php
// calculate correct max capacity
$max_quantity = ($capacity_of_this_repeat!='none') ? $capacity_of_this_repeat:
($product->backorders_allowed() ? '' : $product->get_stock_quantity());
if ( ! $product->is_sold_individually() )
woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', 1, $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $max_quantity, $product )
), $product );
?>
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<button data-product_id='<?php echo $woo_product_id;?>' id='cart_btn' class="evoAddToCart evcal_btn single_add_to_cart_button button alt"><?php echo apply_filters('single_add_to_cart_text', eventon_get_custom_language($opt, 'evoTX_002','Add to Cart'), $product->product_type); ?></button>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
<div class="clear"></div>
</div>
</form>
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
Related
I have found this piece of code for functions.php it's getting me partway to where I want to be.
Code I am using found here Adding affiliate links to Woocommerce variations
Website with attached code in place
However
It is removing my dropdown variation selection & the variable product description and placing all variable product data in a table.
I also want to create a second input box in the variation set up to output custom button text for each 'add to basket' - so that I can put the affiliate retailer name.
I want to be able to add multiple affiliate retailer buttons (with custom text) per variation, not just one.
What I would like the added multiple affiliate retailer buttons to display per variation dropdown selection, showing below the variable product description and below the variable price.
All help hugely appreciated. I'm not proficient at writing code so will need any advice spelling out for me I am afraid. Thanks.
// Display Fields
add_action( 'woocommerce_product_after_variable_attributes', 'variable_fields', 10, 2 );
//JS to add fields for new variations
add_action( 'woocommerce_product_after_variable_attributes_js', 'variable_fields_js' );
// Save Fields
add_action( 'woocommerce_process_product_meta_variable', 'variable_fields_process', 10, 2 );
function variable_fields( $loop, $variation_data ) {
?>
<tr>
<td>
<div>
<label><?php _e( 'Affiliate URL', 'woocommerce' ); ?></label>
<input type="text" size="5" name="my_affiliate_url[<?php echo $loop; ?>]" value="<?php echo $variation_data['_my_affiliate_url'][0]; ?>"/>
</div>
</td>
</tr>
<?php
}
function variable_fields_js() {
?>
<tr>
<td>
<div>
<label><?php _e( 'My Custom Field', 'woocommerce' ); ?></label>
<input type="text" size="5" name="my_affiliate_url[' + loop + ']" />
</div>
</td>
</tr>
<?php
}
function variable_fields_process( $post_id ) {
if (isset( $_POST['variable_sku'] ) ) :
$variable_sku = $_POST['variable_sku'];
$variable_post_id = $_POST['variable_post_id'];
$variable_custom_field = $_POST['my_affiliate_url'];
for ( $i = 0; $i < sizeof( $variable_sku ); $i++ ) :
$variation_id = (int) $variable_post_id[$i];
if ( isset( $variable_custom_field[$i] ) ) {
update_post_meta( $variation_id, '_my_affiliate_url', stripslashes( $variable_custom_field[$i] ) );
}
endfor;
endif;
}
//front-end variations
function woocommerce_variable_add_to_cart() {
global $product, $post;
$variations = $product->get_available_variations();
foreach ($variations as $key => $value) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>"method="post" enctype='multipart/form-data'>
<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
<?php
if(!empty($value['attributes'])){
foreach ($value['attributes'] as $attr_key => $attr_value) {
?>
<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">
<?php
}
}
?>
<table>
<tbody>
<tr>
<td>
<b><?php echo implode('/', $value['attributes']);?></b>
</td>
<td>
<?php echo $value['price_html'];?>
</td>
<td>
<a class="single_add_to_cart_button button alt" target="_blank" href="<?php echo get_post_meta($value['variation_id'], '_my_affiliate_url', true); ?>" ><?php echo apply_filters('single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $product->product_type); ?></a>
</td>
</tr>
</tbody>
</table>
</form>
<?php
}
}
The above code seems to be overriding this script in variation.php
defined( 'ABSPATH' ) || exit;
?>
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
<div class="woocommerce-variation-price">{{{ data.variation.price_html }}}</div>
<div class="woocommerce-variation-custom_field">{{{ data.variation.custom_field}}}</div>
<div class="woocommerce-variation-availability">{{{ data.variation.availability_html }}}</div>
</script>
<script type="text/template" id="tmpl-unavailable-variation-template">
<p><?php esc_html_e( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ); ?></p>
</script>
I need to alter the default Woocommerce checkout a little bit. I need to move the payment options ABOVE the order review table, while keeping the "Place Order" button at the bottom below the order review table. I currently have
remove_action('woocommerce_checkout_order_review','woocommerce_checkout_payment', 20 );
add_action( 'woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 5 );
This moves the payment box above the table, but it also moves the button. How can I keep the button at the bottom?
Here below, you will find the necessary code to reorder checkout order review section. This code will put the payment methods and gateways before the checkout review order table and will keep the "Place Order" button at the end.
The code:
add_action( 'woocommerce_checkout_order_review', 'reordering_checkout_order_review', 1 );
function reordering_checkout_order_review(){
remove_action('woocommerce_checkout_order_review','woocommerce_checkout_payment', 20 );
add_action( 'woocommerce_checkout_order_review', 'custom_checkout_payment', 8 );
add_action( 'woocommerce_checkout_order_review', 'custom_checkout_place_order', 20 );
}
function custom_checkout_payment() {
$checkout = WC()->checkout();
if ( WC()->cart->needs_payment() ) {
$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();
WC()->payment_gateways()->set_current_gateway( $available_gateways );
} else {
$available_gateways = array();
}
if ( ! is_ajax() ) {
// do_action( 'woocommerce_review_order_before_payment' );
}
?>
<div id="payment" class="woocommerce-checkout-payment-gateways">
<?php if ( WC()->cart->needs_payment() ) : ?>
<ul class="wc_payment_methods payment_methods methods">
<?php
if ( ! empty( $available_gateways ) ) {
foreach ( $available_gateways as $gateway ) {
wc_get_template( 'checkout/payment-method.php', array( 'gateway' => $gateway ) );
}
} else {
echo '<li class="woocommerce-notice woocommerce-notice--info woocommerce-info">';
echo apply_filters( 'woocommerce_no_available_payment_methods_message', WC()->customer->get_billing_country() ? esc_html__( 'Sorry, it seems that there are no available payment methods for your state. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ) : esc_html__( 'Please fill in your details above to see available payment methods.', 'woocommerce' ) ) . '</li>'; // #codingStandardsIgnoreLine
}
?>
</ul>
<?php endif; ?>
</div>
<?php
}
function custom_checkout_place_order() {
$checkout = WC()->checkout();
$order_button_text = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) );
?>
<div id="payment-place-order" class="woocommerce-checkout-place-order">
<div class="form-row place-order">
<noscript>
<?php esc_html_e( 'Since your browser does not support JavaScript, or it is disabled, please ensure you click the <em>Update Totals</em> button before placing your order. You may be charged more than the amount stated above if you fail to do so.', 'woocommerce' ); ?>
<br/><button type="submit" class="button alt" name="woocommerce_checkout_update_totals" value="<?php esc_attr_e( 'Update totals', 'woocommerce' ); ?>"><?php esc_html_e( 'Update totals', 'woocommerce' ); ?></button>
</noscript>
<?php wc_get_template( 'checkout/terms.php' ); ?>
<?php do_action( 'woocommerce_review_order_before_submit' ); ?>
<?php echo apply_filters( 'woocommerce_order_button_html', '<button type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="' . esc_attr( $order_button_text ) . '" data-value="' . esc_attr( $order_button_text ) . '">' . esc_html( $order_button_text ) . '</button>' ); // #codingStandardsIgnoreLine ?>
<?php do_action( 'woocommerce_review_order_after_submit' ); ?>
<?php wp_nonce_field( 'woocommerce-process_checkout', 'woocommerce-process-checkout-nonce' ); ?>
</div>
</div>
<?php
if ( ! is_ajax() ) {
do_action( 'woocommerce_review_order_after_payment' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
I have some problems displaying the SKU for variations, I modified the Single Product Page to display the Variations as a List, this is the Code I used (functions of the the Theme, tried with a Standard Theme, no change)
function woocommerce_variable_add_to_cart() {
global $product, $post;
$variations = $product->get_available_variations();
foreach ($variations as $key => $value) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>"method="post" enctype='multipart/form-data'>
<input type="hidden" name="variation_id" value="<?php echo $value['variation_id']?>" />
<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
<?php
if(!empty($value['attributes'])){
foreach ($value['attributes'] as $attr_key => $attr_value) {
?>
<input type="hidden" name="<?php echo $attr_key?>" value="<?php echo $attr_value?>">
<?php
}
}
?>
<table>
<tbody>
<tr>
<td>
<b><?php echo implode('/', $value['attributes']);?></b>
</td>
<td>
<?php echo $value['price_html'];?>
</td>
<td>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php
do_action( 'woocommerce_before_add_to_cart_quantity' );
woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : $product->get_min_purchase_quantity(),
) );
do_action( 'woocommerce_after_add_to_cart_quantity' );
?>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></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="0" /></div>
<?php
global $product;
?>
<div class>
<?php if ( wc_product_sku_enabled() && ( $product->get_sku() || $product->is_type( 'variation' ) ) ) : ?>
<span class="sku_wrapper"><?php esc_html_e( 'Artikelnummer: ', 'woocommerce' ); ?> <span class="sku"><?php echo ( $sku = $product->get_sku() ) ? $sku : esc_html__( 'N/A', 'woocommerce' ); ?></span></span>
<?php endif;?>
</div>
</td>
</tr>
</tbody>
</table>
</form>
<?php
}
}
The only thing not working is getting the SKU of the Variation, instead it gets the SKU of the Product itself or nothing at all (this is the case with the code below, any hint/help would be appreciated. I also tried implent this Variable Product Sku not Working
but it didn't work either
Thanks in Advance (I hade trouble with getting all the coe to display in the code window so I have to use the snippet function, appologies for that)
Your code was a bit hard to read but try using get_post_meta with the variation post id.
$variation_sku = get_post_meta( $value['variation_id'] , '_sku', TRUE );
See if that works.
In WooCommerce 3.0+, I have created some tabs using js and in each tab contains products from different categories. I have managed to modify add-to-cart link for simple products where ones the addtocart button is clicked it goes to the next tab without refreshing and the product is being added successfully to the cart.
if ( has_term( 'jeans-discount', 'product_cat', $post ) ) {
echo apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '<a rel="nofollow" data-target="2" href="javascript:void(0); %s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="custom %s">%s</a>',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->get_id() ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() )
),
$product );
}
However I am not able to modify the addtocart button for variable products in variation-add-to-cart.php template file:
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
For simple product the addtocart link shows as href="javascript:void(0); /wordpress/woo-slider/?add-to-cart=73".
Is there a way i can do this for variable products addtocart link as well?
For WooCommerce version 3.0+ you will override variation-add-to-cart.php template this way:
<?php
/**
* Single variation cart button
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product;
?>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php
/**
* #since 3.0.0.
*/
do_action( 'woocommerce_before_add_to_cart_quantity' );
woocommerce_quantity_input( array(
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : $product->get_min_purchase_quantity(),
) );
/**
* #since 3.0.0.
*/
do_action( 'woocommerce_after_add_to_cart_quantity' );
// Set HERE your targeted product category
if ( has_term( 'jeans-discount', 'product_cat', $product->get_id() ) ) {
?>
<button type="submit" data-target="2" class="single_add_to_cart_button button alt" onclick="javascript:void(0);"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php } else { // Other product categories
?>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php } ?>
<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="0" />
</div>
I can't test it for real (as I don't have a system of tabs enabled), but this is successful working on my test server without error problems.
For WooCommerce 2.6.x you will override variation-add-to-cart.php template this way:
<?php
/**
* Single variation cart button
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product;
// Set HERE your targeted product category
if ( has_term( 'jeans-discount', 'product_cat', $product->id ) ) {
?>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php if ( ! $product->is_sold_individually() ) : ?>
<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
<?php endif; ?>
<button type="submit" data-target="2" class="single_add_to_cart_button button alt" onclick="javascript:void(0);"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php } else { // Other product categories
?>
<div class="woocommerce-variation-add-to-cart variations_button">
<?php if ( ! $product->is_sold_individually() ) : ?>
<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
<?php endif; ?>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php } ?>
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="product_id" value="<?php echo absint( $product->id ); ?>" />
<input type="hidden" name="variation_id" class="variation_id" value="0" />
</div>
By default, Woocommerce has two types of addresses which are Billing and Delivery address, and these informations can be edited from My Account page, you click the "edit" link, form opens in a new window.
But this is what, I want the account page to look like:
When the user visits the My Account page, I would like to have both [the billing (facturacion) and shipping address (datos envio)] edit forms there on the same page. How can I achieve this?
I want to have both forms in the same page instead in two different ones.
I have been trying to "separate" both forms and have them one next to the other in the same page instead of having them in two different page/instances.
The file form-edit-address contains the forms.
This is what I have tried:
in the begining of the code it reads
$page_title = ( $load_address === 'billing' ) ? __( 'Billing Address', 'woocommerce' );
I removed the shipping bit. but breaks all.
clearly here is where i have to chop a bit to render billing or shipping forms, my experience is limited with php so I have been trying all sorts of combinations like walking blind. Can somebody help me understand this code to customize it?
This is the untouched code:
<?php
/**
* Edit address form
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $woocommerce, $current_user;
$page_title = ( $load_address === 'billing' ) ? __( 'Billing Address', 'woocommerce' ) : __( 'Shipping Address', 'woocommerce' );
get_currentuserinfo();
?>
<?php wc_print_notices(); ?>
<?php if ( ! $load_address ) : ?>
<?php wc_get_template( 'myaccount/my-address.php' ); ?>
<?php else : ?>
<form method="post">
<h3><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h3>
<?php foreach ( $address as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, ! empty( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : $field['value'] ); ?>
<?php endforeach; ?>
<p>
<input type="submit" class="button big" name="save_address" value="<?php _e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
</form>
<?php endif; ?>
Here is how you can do it.
<?php
// get the user meta
$userMeta = get_user_meta(get_current_user_id());
// get the form fields
$countries = new WC_Countries();
$billing_fields = $countries->get_address_fields( '', 'billing_' );
$shipping_fields = $countries->get_address_fields( '', 'shipping_' );
?>
<!-- billing form -->
<?php
$load_address = 'billing';
$page_title = __( 'Billing Address', 'woocommerce' );
?>
<form action="/my-account/edit-address/billing/" class="edit-account" method="post">
<h2><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h2>
<?php do_action( "woocommerce_before_edit_address_form_{$load_address}" ); ?>
<?php foreach ( $billing_fields as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, $userMeta[$key][0] ); ?>
<?php endforeach; ?>
<?php do_action( "woocommerce_after_edit_address_form_{$load_address}" ); ?>
<p>
<input type="submit" class="button" name="save_address" value="<?php esc_attr_e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
</form>
<!-- shipping form -->
<?php
$load_address = 'shipping';
$page_title = __( 'Shipping Address', 'woocommerce' );
?>
<form action="/my-account/edit-address/shipping/" class="edit-account" method="post">
<h2><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h2>
<?php do_action( "woocommerce_before_edit_address_form_{$load_address}" ); ?>
<?php foreach ( $shipping_fields as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, $userMeta[$key][0] ); ?>
<?php endforeach; ?>
<?php do_action( "woocommerce_after_edit_address_form_{$load_address}" ); ?>
<p>
<input type="submit" class="button" name="save_address" value="<?php esc_attr_e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
</form>