In my WooCommerce shop customers can only buy one product.
They can add this single product multiple times to the cart, but with different custom meta values.
Customers are able to edit their products from the cart (WooCommerce default functionality) and change the meta they initially filled in.
In my functions.php I have the following code:
function add_names_on_tshirt_field() {
global $post;
$name_one_on_tshirt = "";
$name_two_on_tshirt = "";
$name_three_on_tshirt = "";
foreach ( WC()->cart->cart_contents as $key => $value ) {
if( $value["product_id"] == $post->ID && isset( $value["name_one_on_tshirt"] ) ) {
$name_one_on_tshirt = $value["name_one_on_tshirt"];
}
if( $value["product_id"] == $post->ID && isset( $value["name_two_on_tshirt"] ) ) {
$name_two_on_tshirt = $value["name_two_on_tshirt"];
}
if( $value["product_id"] == $post->ID && isset( $value["name_three_on_tshirt"] ) ) {
$name_three_on_tshirt = $value["name_three_on_tshirt"];
}
}
echo '<table class="variations" cellspacing="0">
<tbody>
<tr>
<td class="label"><label for="color">Name 1 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-one-on-tshirt" value="'. esc_attr( $name_one_on_tshirt ) .'" />
</td>
</tr>
<tr>
<td class="label"><label for="color">Name 2 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-two-on-tshirt" value="'. esc_attr( $name_two_on_tshirt ) .'" />
</td>
</tr>
<tr>
<td class="label"><label for="color">Name 3 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-three-on-tshirt" value="'. esc_attr( $name_three_on_tshirt ) .'" />
</td>
</tr>
</tbody>
</table>';
}
add_action( 'woocommerce_before_add_to_cart_button', 'add_names_on_tshirt_field' );
The problem lies in when my customers try to edit a product from the cart. Because all products have the same ID (I only have one product), the meta from the last product added to the cart is loaded into the text fields. I currently retrieve the meta in my foreach using the product id, but the ID is the same as all other products in my cart. Is there another way to retrieve the meta without using the product_id/$post->ID, like the cart_item_key or using sessions?
Here is the idea how you can achieve that
you will have to edit your your-theme/woocommerce/cart.php ( especially product-thumbnail TD and product-name TD )
<?php
$query_str = "";
if( isset( $cart_item["name_one_on_tshirt"] ) ) {
$query_str .= "?name_one_on_tshirt=" . $cart_item["name_one_on_tshirt"];
}
if( isset( $cart_item["name_two_on_tshirt"] ) ) {
if( $query_str == "" ) {
$query_str .= "?name_two_on_tshirt=" . $cart_item["name_two_on_tshirt"];
} else {
$query_str .= "&name_two_on_tshirt=" . $cart_item["name_two_on_tshirt"];
}
}
if( isset( $cart_item["name_three_on_tshirt"] ) ) {
if( $query_str == "" ) {
$query_str .= "?name_three_on_tshirt=" . $cart_item["name_three_on_tshirt"];
} else {
$query_str .= "&name_three_on_tshirt=" . $cart_item["name_three_on_tshirt"];
}
}
?>
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $_product->is_visible() ) {
echo $thumbnail;
} else {
printf( '%s', esc_url( $_product->get_permalink( $cart_item ) . $query_str ), $thumbnail );
}
?>
</td>
<td class="product-name" data-title="<?php _e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $_product->is_visible() ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $_product->get_permalink( $cart_item ) . $query_str ), $_product->get_title() ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?>
</td>
and then update your add_name_on_tshirt_field function like this
function add_names_on_tshirt_field() {
global $post;
$name_one_on_tshirt = "";
$name_two_on_tshirt = "";
$name_three_on_tshirt = "";
if( isset( $_GET["name_one_on_tshirt"] ) ) {
$name_one_on_tshirt = $_GET["name_one_on_tshirt"];
}
if( isset( $_GET["name_two_on_tshirt"] ) ) {
$name_two_on_tshirt = $_GET["name_two_on_tshirt"];
}
if( isset( $_GET["name_three_on_tshirt"] ) ) {
$name_three_on_tshirt = $_GET["name_three_on_tshirt"];
}
echo '<table class="variations" cellspacing="0">
<tbody>
<tr>
<td class="label"><label for="color">Name 1 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-one-on-tshirt" value="'. esc_attr( $name_one_on_tshirt ) .'" />
</td>
</tr>
<tr>
<td class="label"><label for="color">Name 2 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-two-on-tshirt" value="'. esc_attr( $name_two_on_tshirt ) .'" />
</td>
</tr>
<tr>
<td class="label"><label for="color">Name 3 on T-Shirt</label></td>
<td class="value">
<input type="text" name="name-three-on-tshirt" value="'. esc_attr( $name_three_on_tshirt ) .'" />
</td>
</tr>
</tbody>
</table>';
}
add_action( 'woocommerce_before_add_to_cart_button', 'add_names_on_tshirt_field' );
So basically what I did is, I added them as query variable at cart.php and in add_name_on_tshirt_field I am check for the corresponding query var, if I find one then we can fill that fields value attribute.
Related
I've a Woocommerce variation table. It shows each variation in table with respective info, it's working almost properly but I don't know why, it's replacing period with hyphen and even front slash with hyphen.
6.5 becomes 6-5. N/A becomes n-a. Image is attached be low
Here's my code
global $product, $post;
$variations = $product->get_available_variations();
$gcounter = 1; ?>
<table>
<thead>
<tr>
<th scope="col" class="model-class"><b>Model</b></th>
<?php foreach($product->get_available_variations() as $variation ){
$variation_id = $variation['variation_id'];
foreach( $variation['attributes'] as $key => $value ){
$taxonomy = str_replace('attribute_', '', $key );
$taxonomy_label = get_taxonomy( $taxonomy )->labels->singular_name;
$term_name = get_term_by( 'slug', $value, $taxonomy )->name;
?>
<th>
<b><?php echo $taxonomy_label;?></b>
</th>
<?php
} ?>
<th scope="col"><b>Price</b></th>
<th scope="col" width="250"><b>Qty</b></th>
</tr>
<?php if ($gcounter == 1) {
break;
} ?>
<?php } ?>
</thead>
<?php
foreach ($variations as $key => $value) {
?>
<tbody>
<tr>
<td class="model-class">
<?php $variation_sku = get_post_meta( $value['variation_id'] , '_sku', TRUE ); ?>
<?php echo $variation_sku ;?>
</td>
<?php
if(!empty($value['attributes'])){
foreach ($value['attributes'] as $attr_key => $attr_value) {
$taxonomy = str_replace('attribute_', '', $attr_key );
$taxonomy_label = get_taxonomy( $taxonomy )->labels->singular_name;
$term_name = get_term_by( 'slug', $value, $taxonomy )->name;
?>
<td class="<?php echo $taxonomy;?>">
<b><?php echo $attr_value;?></b>
</td>
<?php
}
}
?>
<td class="price">
<?php if ( is_user_logged_in() ) {
if ($value['price_html']){
echo $value['price_html'];
} else {
echo '£'.number_format((float)$value['display_regular_price'], 2, '.', '');
}
} else {
echo 'Call/Enquire for prices';
}
?>
</td>
<td class="quantity">
<form id="addtocart" name="addtocart" class="variations_form cart"
action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" method="post"
enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>"
data-product_variations="<?php echo htmlspecialchars( json_encode( $product->get_available_variations() ) ) ?>">
<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 ); ?>" />
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $post->ID ); ?>">
<?php
if(!empty($value['attributes'])){
foreach ($value['attributes'] as $attr_key => $attr_value) {
$taxonomy = str_replace('attribute_', '', $attr_key );
$taxonomy_label = get_taxonomy( $taxonomy )->labels->singular_name;
$term_name = get_term_by( 'slug', $value, $taxonomy )->name;
?>
<input type="hidden" id="<?php echo $taxonomy; ?>" data-attribute_name="<?php echo $attr_key?>"
name="<?php echo $attr_key?>" value="<?php echo $attr_value;?>">
<?php
}
}
?>
<?php
if ( $product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input( array(
'input_name' => "quantity",
'max_value' => $product->get_max_purchase_quantity(),
'min_value' => '1',
'product_name' => $product->get_name(),
'input_value' => '1',
), $product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); // PHPCS: XSS ok.
?>
</form>
<div class="yith-ywraq-add-to-quote add-to-quote-addons-<?php echo $product_id ?>"
<?php echo $data_variations ?>>
<a href="#" class="add-request-quote-button button alt"
data-product_id="<?php echo $value['variation_id']?>"
data-wp_nonce="<?php echo wp_create_nonce(); ?>">Add to quote</a>
</div>
<?php if ( is_user_logged_in() ) { ?>
<button type="submit" onclick="document.addtocart.submit()" class="single_add_to_cart_button button alt"
form="addtocart"><?php echo apply_filters('single_add_to_cart_text', __( 'Add to cart', 'woocommerce' ), $product->product_type); ?></button><?php } ?>
</td>
</tr>
<?php
} ?>
</tbody>
</table>
This is how it looks on backend
On Woocommerce, I have changed $show_image variable to true in email order details php template file, but I am still unable to get the image displayed in email notifications:
<div style="margin-bottom: 40px;">
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
<thead>
<tr>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
echo wc_get_email_order_items( $order, array( // WPCS: XSS ok.
'show_sku' => $sent_to_admin,
'show_image' => true,
'image_size' => array( 100, 100 ),
'plain_text' => $plain_text,
'sent_to_admin' => $sent_to_admin,
) );
?>
</tbody>
<tfoot>
<?php
$totals = $order->get_order_item_totals();
if ( $totals ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['label'] ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['value'] ); ?></td>
</tr>
<?php
}
}
if ( $order->get_customer_note() ) {
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Personal Message:', 'woocommerce' ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php echo wp_kses_post( wptexturize( $order->get_customer_note() ) ); ?></td>
</tr>
<?php
}
?>
</tfoot>
</table>
I need to add link as well to the product image.Once the user click on the image it should redirect to the particular page.
Changed the message from false to true still the image is not displayed in the site.
To display the image in Email notifications, revert back your changes to original template and use instead:
add_filter( 'woocommerce_email_order_items_args', 'custom_email_order_items_args', 10, 1 );
function custom_email_order_items_args( $args ) {
$args['show_image'] = true;
return $args;
}
To add the product link to the image and to the item name (optionally) you will use:
add_filter( 'woocommerce_order_item_thumbnail', 'add_email_order_item_permalink', 10, 2 ); // Product image
add_filter( 'woocommerce_order_item_name', 'add_email_order_item_permalink', 10, 2 ); // Product name
function add_email_order_item_permalink( $output_html, $item, $bool = false ) {
// Only email notifications
if( is_wc_endpoint_url() )
return $output_html;
$product = $item->get_product();
return '' . $output_html . '';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Thumbnail size change:
You can also manipulate the thumbnail size in this hook which is by default 32 x 32 pixels using under $args['show_image'] = true; adding this line:
$args['image_size'] = array( 48, 48 );
Tested and works too.
I made a table for single product variations and I trying to do pagination.
I'm using variable products with few custom attributes. So the issue is that pagination is not working and showing too many pages.
For example, for one product I have 15 variations on the first page and total but pagination shows 14 total page. Also if I set posts_per_page for example 2, then all variations are multiplied by 2 (duplicated) and so on.
This is my table
Full Code in functions.php
function woocommerce_variable_add_to_cart(){
global $product, $post, $woocommerce;
$attributes = $product->get_attributes();
$variations = find_valid_variations();
if ( get_post_meta($post->ID, 'price_grid', true) ) {
wp_enqueue_script( 'wc-add-to-cart-variation' );
wc_get_template( 'single-product/add-to-cart/variable.php', array(
'available_variations' => $product->get_available_variations(),
'attributes' => $product->get_variation_attributes(),
'selected_attributes' => $product->get_variation_default_attributes()
) );
return;
}
?>
<table class="variations variations-grid" cellspacing="0">
<thead>
<tr>
<td> Date</td>
<td> Location </td>
<td> Price </td>
<td> Quantity </td>
<td> Availability </td>
<td> </td>
</tr>
</thead>
<tbody>
<?php
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = ( array(
'post_type' => array('product_variation'),
'posts_per_page'=> 1,
'post_status' => array('private', 'publish'),
//'post_in' => array('product'),
'product_cat' => '',
'paged' => $paged,
'post_parent' => get_the_ID()
) );
$wp_query = new WP_Query($args);
while( $wp_query->have_posts() ) : $wp_query->the_post();
?>
<?php
foreach ($variations as $key => $value) {
if( !$value['variation_is_visible'] ) continue;
?>
<tr>
<td class="date">
<?php
$i = 0;
foreach($value['attributes'] as $key => $val ) {
if($i == 0 ) {
echo $val;
}
$i++;
}
?>
</td>
<td class="location">
<?php
$i = 0;
foreach($value['attributes'] as $key => $val ) {
if($i !== 0) {
echo $val;
}
$i++;
}
?>
</td>
<td class="price">
<?php echo '<span>£</span>' . $product->get_price(); ?>
</td>
<td class="quantity">
<?php woocommerce_quantity_input(); ?>
</td>
<td class="stock">
<?php if (!$value['is_in_stock'] ) { ?>
<p class="stock out-of-stock"><?php _e( 'Places Not Available', 'woocommerce' ); ?></p>
<?php } else { ?>
<p class="stock in-stock"><?php _e( 'Places Available', 'woocommerce' ); ?></p>
</td>
<td class="add-to-cart">
<form class="cart" action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" method="post" enctype='multipart/form-data'>
<?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
}
}
?>
<button type="submit" class="single_add_to_cart_button button alt"><span class="glyphicon glyphicon-tag"></span> Add to cart</button>
<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 ); ?>" />
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $post->ID ); ?>" />
</form>
<?php } ?>
</td>
</tr>
<?php } ?>
</tbody>
<?php endwhile; ?>
</table>
<?php
if ( function_exists( 'wp_pagenavi' ) ) {
?>
<div id="pagination">
<?php wp_pagenavi( array( 'query' => $wp_query ) ); ?>
</div>
<?php } ?>
<?php wp_reset_query(); ?>
<?php
}
function find_valid_variations() {
global $product;
$variations = $product->get_available_variations();
$attributes = $product->get_attributes();
$new_variants = array();
foreach( $variations as $variation ) {
$valid = true;
foreach( $attributes as $slug => $args ) {
if( array_key_exists("attribute_$slug", $variation['attributes']) && !empty($variation['attributes']["attribute_$slug"]) ) {
} else {
$valid = false;
foreach( explode( '|', $attributes[$slug]['value']) as $attribute ) {
$attribute = trim( $attribute );
$new_variant = $variation;
$new_variant['attributes']["attribute_$slug"] = $attribute;
$new_variants[] = $new_variant;
}
}
}
if( $valid )
$new_variants[] = $variation;
}
return $new_variants;
}
I had a similar issue with one of my projects. I solved it using jQuery DataTables plugin. Try to see if it solves yours.
I have a big issue right now on my Wordpress site. Simple products do work just fine, but when I add product variations in attribute, and add that product, cart page just bugs out. After the description nothing is loaded, don't have the price, quantity, even footer doesn't load, as it stops loading there.
I tried overriding Woocommerce files with theme woocommerce files, but with no luck. I searched everything and everywhere for solution, but there is none. I tried everything with Product variations, but with no luck also.
The website is: https://ticketshoprd.com
Also, mini-cart in the menu is working just fine with product variations.
The event which is with variations is the Boat Party one.
Code from cart.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
wc_print_notices();
do_action( 'woocommerce_before_cart' ); ?>
<form action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">
<?php do_action( 'woocommerce_before_cart_table' ); ?>
<table class="shop_table shop_table_responsive cart" cellspacing="0">
<thead>
<tr>
<th class="product-remove"> </th>
<th class="product-thumbnail"> </th>
<th class="product-name"><?php esc_html_e( 'Evento', 'startit' ); ?></th>
<th class="product-price"><?php esc_html_e( 'Precio', 'startit' ); ?></th>
<th class="product-quantity"><?php esc_html_e( 'Cantidad', 'startit' ); ?></th>
<th class="product-subtotal"><?php esc_html_e( 'Total', 'startit' ); ?></th>
</tr>
</thead>
<tbody>
<?php do_action( 'woocommerce_before_cart_contents' ); ?>
<?php
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<td class="product-remove">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( WC()->cart->get_remove_url( $cart_item_key ) ),
esc_html__( 'Remove this item', 'startit' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</td>
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo qode_startit_kses_img($thumbnail);
} else {
printf( '%s', esc_url( $product_permalink ), $thumbnail );
}
?>
</td>
<td class="product-name" data-title="<?php _e( 'Product', 'startit' ); ?>">
<?php
if ( ! $product_permalink ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_title() ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'startit' ) . '</p>';
}
?>
</td>
<td class="product-price" data-title="<?php _e( 'Price', 'startit' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-quantity" data-title="<?php _e( 'Quantity', 'startit' ); ?>">
<?php
if ( $_product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input( array(
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(),
'min_value' => '0'
), $_product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item );
?>
</td>
<td class="product-subtotal" data-title="<?php _e( 'Total', 'startit' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key );
?>
</td>
</tr>
<?php
}
}
do_action( 'woocommerce_cart_contents' );
?>
<tr>
<td colspan="6" class="actions">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon">
<label for="coupon_code"><?php esc_html_e( 'Coupon', 'startit' ); ?>:</label>
<input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Código del cupón', 'startit' ); ?>" />
<?php
//Override Apply Coupon Button
do_action('qode_startit_woocommerce_apply_coupon_button');
?>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
</div>
<?php } ?>
<div class="qodef-cart-proceed-update">
<?php do_action( 'woocommerce_proceed_to_checkout' ); ?>
<input type="submit" class="qodef-btn qodef-btn-medium qodef-btn-default checkout-button alt wc-forward" name="update_cart" value="<?php esc_attr_e( 'Actualizar Carrito', 'woocommerce' ); ?>" />
<?php
//Override Apply Coupon Button
do_action('qode_startit_woocommerce_update_cart_button');
?>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
</div>
</td>
</tr>
<?php do_action( 'woocommerce_after_cart_contents' ); ?>
</tbody>
</table>
<?php do_action( 'woocommerce_after_cart_table' ); ?>
</form>
<div class="cart-collaterals">
<?php if ( is_cart() ) : ?>
<div class="qodef-shipping-calculator">
<?php woocommerce_shipping_calculator(); ?>
</div>
<?php endif; ?>
<div class="qodef-cart-totals">
<?php do_action( 'woocommerce_cart_collaterals' ); ?>
</div>
</div>
<?php do_action( 'woocommerce_after_cart' ); ?>
I have found the code how to do repeatable fields in metabox in WordPress but have problem because i have error like below
Parse error: syntax error, unexpected '}' in of this code line 124.
Below I put the code, please help me if someone now what is wrong? I will be grateful
<?
function hhs_get_sample_options() {
$options = array (
'Option 1' => 'option1',
'Option 2' => 'option2',
'Option 3' => 'option3',
'Option 4' => 'option4',
);
return $options;
}
add_action('admin_init', 'hhs_add_meta_boxes', 1);
function hhs_add_meta_boxes() {
add_meta_box( 'repeatable-fields', 'Repeatable Fields',
'hhs_repeatable_meta_box_display', 'price_table', 'normal', 'default');
}
function hhs_repeatable_meta_box_display() {
global $post;
$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
$options = hhs_get_sample_options();
wp_nonce_field( 'hhs_repeatable_meta_box_nonce', 'hhs_repeatable_meta_box_nonce' );
?>
<script type="text/javascript">
jQuery(document).ready(function( $ ){
$( '#add-row' ).on('click', function() {
var row = $( '.empty-row.screen-reader-text' ).clone(true);
row.removeClass( 'empty-row screen-reader-text' );
row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
return false;
});
$( '.remove-row' ).on('click', function() {
$(this).parents('tr').remove();
return false;
});
});
</script>
<table id="repeatable-fieldset-one" width="100%">
<thead>
<tr>
<th width="40%">Name</th>
<th width="12%">Select</th>
<th width="40%">URL</th>
<th width="8%"></th>
</tr>
</thead>
<tbody>
<?php
if ( $repeatable_fields ) :
foreach ( $repeatable_fields as $field ) {
?>
<tr>
<td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['select'], $value ); ?>><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
<?php
}
else :
// show a blank one
?>
<tr>
<td><input type="text" class="widefat" name="name[]" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
<?php endif; ?>
<!-- empty hidden one for jQuery -->
<tr class="empty-row screen-reader-text">
<td><input type="text" class="widefat" name="name[]" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Add another</a></p>
<?php
} //this is something wrong but I don't now why?
add_action('save_post', 'hhs_repeatable_meta_box_save');
function hhs_repeatable_meta_box_save($post_id) {
if ( ! isset( $_POST['hhs_repeatable_meta_box_nonce'] ) ||
! wp_verify_nonce( $_POST['hhs_repeatable_meta_box_nonce'],
'hhs_repeatable_meta_box_nonce' ) )
return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if (!current_user_can('edit_post', $post_id))
return;
$old = get_post_meta($post_id, 'repeatable_fields', true);
$new = array();
$options = hhs_get_sample_options();
$names = $_POST['name'];
$selects = $_POST['select'];
$urls = $_POST['url'];
$count = count( $names );
for ( $i = 0; $i < $count; $i++ ) {
if ( $names[$i] != '' ) :
$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
if ( in_array( $selects[$i], $options ) )
$new[$i]['select'] = $selects[$i];
else
$new[$i]['select'] = '';
if ( $urls[$i] == 'http://' )
$new[$i]['url'] = '';
else
$new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
endif;
}
if ( !empty( $new ) && $new != $old )
update_post_meta( $post_id, 'repeatable_fields', $new );
elseif ( empty($new) && $old )
delete_post_meta( $post_id, 'repeatable_fields', $old );
}
?>