Related
child Theme, functions.php, I am creating a metabox. I have two text fields in a custom metabox. I need to save the fields anytime user clicks "update" or "publish" from the admin Add post. This meta box is allowed to appear in ally types of posts, including custom posts.
I am running PHP7.3, running wordpress 5.3
I have tried to:
1) use others hooks like save_edit_post, admin_init, publish_post, etc.
2) to provide priority value to the add_Action
3) Reviewed HTTP post request to confirm the meta key-value pairs are getting passed - yes it is.
4) used get_post_meta() and $POST global variable to test if values are coming through - but couldn't verify.
function add_taddressbox_address_meta_box() {
add_meta_box(
'taddressbox_address_meta_box', // $id
'taddressbox Address', // $title
'show_taddressbox_address_meta_box', // $callback
get_current_screen(), // $screen
'normal', // $context
'high' // $priority
);
}
function taddressbox_address_save_postdata($post_id, $post, $update)
{
//if this is post revision, then bail
if (wp_is_post_revision( $post_id))
{
return;
}
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
$lat_val = sanitize_text_field(get_post_meta($post_id, '_taddressbox_lng', true));
//get_post_meta($post->ID, 'taddressbox_lat', true);
$lng_val = sanitize_text_field(get_post_meta($post_id, '_taddressbox_lng', true));
update_post_meta($post_id, '_taddressbox_lat', $lat_val);
update_post_meta($post_id, '_taddressbox_lng', $lng_val);
}
function show_taddressbox_address_meta_box() {
global $post;
// $values = get_post_custom( $post->ID );
$lat = isset( $values['taddressbox_lat'] ) ? trim(esc_attr( $values['taddressbox_lat'][0] )) : '30';
$lng = isset( $values['taddressbox_lng'] ) ? trim(esc_attr( $values['taddressbox_lng'][0] )) : '69';
//$lat = '30';
//$lng ='69';
// $meta = get_post_meta( $post->ID, 'taddressbox_address', true );
?>
<input type="hidden" name="taddressbox_address_box_nonce" value="<?php echo wp_create_nonce( basename(__FILE__) ); ?>">
<!-- All fields will go here -->
<div id="map" tabindex="0" style="position: relative;height:400px;margin:0; padding:0; display: block;"></div>
<div id="taddressbox_latlng">
<label for"latitude">Latitude</label> <input type="text" id="taddressbox_lat" name="taddressbox_lat" value="<?php echo $lat; ?>">
<label for"longitude">Longitude</label> <input type="text" id="taddressbox_lng" name ="taddressbox_lng" value="<?php echo $lng; ?>">
</div>
<script>
<?php if ( trim($lat) == '' || trim($lng) =='' ) { ?> InitializetaddressboxMap();
<?php } else { ?>
InitializetaddressboxMap(<?php echo $lat; ?>,<?php echo $lng; ?>);
<?php } ?>
</script>
<?php }
You have to use $_POST[] to catch and save the form submitted code. I've fixed your code, feel free to use it.
add_action( 'add_meta_boxes', 'add_taddressbox_address_meta_box' );
function add_taddressbox_address_meta_box() {
add_meta_box(
'taddressbox_address_meta_box', // $id
'taddressbox Address', // $title
'show_taddressbox_address_meta_box', // $callback
get_current_screen(), // $screen
'normal', // $context
'high' // $priority
);
}
add_action( 'save_post', 'taddressbox_address_save_postdata' );
function taddressbox_address_save_postdata( $post_id )
{
//if this is post revision, then bail
if (wp_is_post_revision( $post_id))
{
return;
}
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
if ( ! isset( $_POST['my_lat_lang_box_nonce'] ) ) {
return $post_id;
}
$nonce = $_POST['my_lat_lang_box_nonce'];
// Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce, 'my_lat_lang_box' ) ) {
return $post_id;
}
$lat_val = sanitize_text_field($_POST['taddressbox_lat']);
$lng_val = sanitize_text_field($_POST['taddressbox_lng']);
update_post_meta($post_id, '_taddressbox_lat', $lat_val);
update_post_meta($post_id, '_taddressbox_lng', $lng_val);
}
function show_taddressbox_address_meta_box( $post ) {
$lat = get_post_meta( $post->ID, '_taddressbox_lat', true );
$lng = get_post_meta( $post->ID, '_taddressbox_lng', true );
wp_nonce_field( 'my_lat_lang_box', 'my_lat_lang_box_nonce' );
?>
<!-- All fields will go here -->
<div id="map" tabindex="0" style="position: relative;height:400px;margin:0; padding:0; display: block;"></div>
<div id="taddressbox_latlng">
<label for"latitude">Latitude</label> <input type="text" id="taddressbox_lat" name="taddressbox_lat" value="<?php echo $lat; ?>">
<label for"longitude">Longitude</label> <input type="text" id="taddressbox_lng" name ="taddressbox_lng" value="<?php echo $lng; ?>">
</div>
<script>
<?php if ( trim($lat) == '' || trim($lng) =='' ) { ?> InitializetaddressboxMap();
<?php } else { ?>
InitializetaddressboxMap(<?php echo $lat; ?>,<?php echo $lng; ?>);
<?php } ?>
</script>
<?php }
Here is a picture of desktop and mobile, you can see there is a : in mobile that shouldn't be there. Any idea what the cause of it could be?
Here is the template from the images - it uses code that falls outside of the scope of Wordpress because my client specifically requested I fix a problem this way, not because I think that it is a good idea to work outside of the scope of Wordpress :)
<?php
/**
* Payment methods
*
* Shows customer payment methods on the account page.
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/payment-methods.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
$customer_id = get_user_meta( $current_user_id, '_stripe_customer_id', true );
\Stripe\Stripe::setApiKey("xxx");
$customer = \Stripe\Customer::retrieve((string)$customer_id);
$card_list = $customer->sources->all(["object" => "card"]);
$show_table = true;
if(isset($_POST['create_new_method'])) {
$show_table = false;
}
$saved_methods = wc_get_customer_saved_methods_list( get_current_user_id() );
$has_methods = (bool) $saved_methods;
$types = wc_get_account_payment_methods_types();
/*echo " **saved_methods: ";
print_r($saved_methods);
echo " **saved_methods length: ";
count($saved_methods->cc);
echo " **card list: ";
print_r($card_list);
echo " **card list length: ".count($card_list->data);*/
$just_added_method = false;
if((empty($saved_methods) && count($card_list->data) > 0) || isset($_GET['added_card']) ) {
$just_added_method = true;
}
do_action( 'woocommerce_before_account_payment_methods', $has_methods ); ?>
<?php if ( ( ($has_methods || $just_added_method) && $show_table ) ) : ?>
<?php if ( $has_methods && $show_table ) : ?>
<table class="woocommerce-MyAccount-paymentMethods shop_table shop_table_responsive account-payment-methods-table">
<thead>
<tr>
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<th class="woocommerce-PaymentMethod woocommerce-PaymentMethod--<?php echo esc_attr( $column_id ); ?> payment-method-<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<?php foreach ( $saved_methods as $type => $methods ) : ?>
<?php foreach ( $methods as $method ) : ?>
<tr class="payment-method<?php echo ! empty( $method['is_default'] ) ? ' default-payment-method' : '' ?>">
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<td class="woocommerce-PaymentMethod woocommerce-PaymentMethod--<?php echo esc_attr( $column_id ); ?> payment-method-<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php
if ( has_action( 'woocommerce_account_payment_methods_column_' . $column_id ) ) {
do_action( 'woocommerce_account_payment_methods_column_' . $column_id, $method );
} elseif ( 'method' === $column_id ) {
if ( ! empty( $method['method']['last4'] ) ) {
/* translators: 1: credit card type 2: last 4 digits */
echo sprintf( __( '%1$s ending in %2$s', 'woocommerce' ), esc_html( wc_get_credit_card_type_label( $method['method']['brand'] ) ), esc_html( $method['method']['last4'] ) );
} else {
echo esc_html( wc_get_credit_card_type_label( $method['method']['brand'] ) );
}
} elseif ( 'expires' === $column_id ) {
echo esc_html( $method['expires'] );
} elseif ( 'actions' === $column_id ) {
foreach ( $method['actions'] as $key => $action ) {
echo '' . esc_html( $action['name'] ) . ' ';
}
}
?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php if ($just_added_method && $show_table && empty($saved_methods)) : ?>
<?php foreach ( $card_list->data as $added_card ) : ?>
<tr class="payment-method">
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<td class="woocommerce-PaymentMethod woocommerce-PaymentMethod--<?php echo esc_attr( $column_id ); ?> payment-method-<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php
if ( has_action( 'woocommerce_account_payment_methods_column_' . $column_id ) ) {
do_action( 'woocommerce_account_payment_methods_column_' . $column_id, $method );
} elseif ( 'method' === $column_id ) {
$last4 = $added_card->last4;
$brand = $added_card->brand;
if ( ! empty( $last4 ) ) {
/* translators: 1: credit card type 2: last 4 digits */
echo sprintf( __( '%1$s ending in %2$s', 'woocommerce' ), esc_html( wc_get_credit_card_type_label( $brand ) ), esc_html( $last4 ) );
} else {
echo esc_html( wc_get_credit_card_type_label( $brand ) );
}
} elseif ( 'expires' === $column_id ) {
echo esc_html( $added_card['exp_month']."/".substr($added_card['exp_year'], 2) );
} elseif ( 'actions' === $column_id ) { ?>
<button class="woocommerce-Button woocommerce-Button--alt button alt" id="delete_card" style="color: white!important" name="delete_card" onClick="location.href='https://www.grahmlux.com/wp-content/themes/betheme/includes/delete_payment_method.php?id=<?php echo $added_card->id; ?>&user_id=<?php echo $current_user_id; ?>'">Delete</button>
<?php if($customer->default_source != $added_card->id) { ?>
<button class="woocommerce-Button woocommerce-Button--alt button alt" id="make_default" style="color: white!important" name="make_default" onClick="location.href='https://www.grahmlux.com/wp-content/themes/betheme/includes/make_default.php?id=<?php echo $added_card->id; ?>&user_id=<?php echo $current_user_id; ?>'">Make default</button>
<?php } ?>
<?php } ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($just_added_method && $show_table && !empty($saved_methods)) {
$added_card = $card_list->data[count($card_list) - 1] ?>
<tr class="payment-method">
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<td class="woocommerce-PaymentMethod woocommerce-PaymentMethod--<?php echo esc_attr( $column_id ); ?> payment-method-<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php
if ( has_action( 'woocommerce_account_payment_methods_column_' . $column_id ) ) {
do_action( 'woocommerce_account_payment_methods_column_' . $column_id, $method );
} elseif ( 'method' === $column_id ) {
$last4 = $added_card->last4;
$brand = $added_card->brand;
if ( ! empty( $last4 ) ) {
/* translators: 1: credit card type 2: last 4 digits */
echo sprintf( __( '%1$s ending in %2$s', 'woocommerce' ), esc_html( wc_get_credit_card_type_label( $brand ) ), esc_html( $last4 ) );
} else {
echo esc_html( wc_get_credit_card_type_label( $brand ) );
}
} elseif ( 'expires' === $column_id ) {
echo esc_html( $added_card['exp_month']."/".substr($added_card['exp_year'], 2) );
} elseif ( 'actions' === $column_id ) { ?>
<button class="woocommerce-Button woocommerce-Button--alt button alt" id="delete_card" style="color: white!important" name="delete_card" onClick="location.href='https://www.grahmlux.com/wp-content/themes/betheme/includes/delete_payment_method.php?id=<?php echo $added_card->id; ?>&user_id=<?php echo $current_user_id; ?>'">Delete</button>
<?php if($customer->default_source != $added_card->id) { ?>
<button class="woocommerce-Button woocommerce-Button--alt button alt" id="make_default" style="color: white!important" name="make_default" onClick="location.href='https://www.grahmlux.com/wp-content/themes/betheme/includes/make_default.php?id=<?php echo $added_card->id; ?>&user_id=<?php echo $current_user_id; ?>'">Make default</button>
<?php } ?>
<?php } ?>
</td>
<?php endforeach; ?>
</tr>
<?php } ?>
</table>
<form action="" method="post">
<input class="woocommerce-Button woocommerce-Button--alt button alt" style="background-color: #88d651!important;" name="create_new_method" type="submit" value="Add payment method" />
</form>
<?php endif; ?>
<?php else :
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
$customer_id = get_user_meta( $current_user_id, '_stripe_customer_id', true );
\Stripe\Stripe::setApiKey("xxx");
if($customer_id == NULL) {
echo 'Make your first purchase to activate this feature - Shop Now';
//die();
}
else {
$customer = \Stripe\Customer::retrieve((string)$customer_id);
} ?>
<?php if(count($card_list->data) == 0) { ?>
<p class="woocommerce-Message woocommerce-Message--info woocommerce-info"><?php esc_html_e( 'No saved methods found.', 'woocommerce' ); ?></p>
<?php } ?>
<!--<form action="https://www.grahmlux.com/wp-content/themes/betheme/includes/add_payment_method.php" method="post" id="add_payment_method">-->
<form action="https://www.grahmlux.com/wp-content/themes/betheme/includes/add_payment_method.php" method="post" id="add_payment_method">
<div class="form-row">
<label for="card-element">
Credit or Debit Card (Secured By Stripe)
</label>
<div id="card-number" style="display: inline-block; width: 180px"></div>
<div id="card-expiry" style="display: inline-block; width: 60px"></div>
<div id="card-cvc" style="display: inline-block; width: 50px"></div>
<!-- Used to display Element errors. -->
<div id="card-errors" role="alert"></div>
<button type="submit" class="woocommerce-Button woocommerce-Button--alt button alt" id="place_order" style="color: white!important" value="<?php esc_attr_e( 'Add payment method', 'woocommerce' ); ?>"><?php esc_html_e( 'Add payment method', 'woocommerce' ); ?></button>
</div>
</form>
<script>
var style = {
base: {
color: '#ffffff',
fontSize: '14px',
fontSmoothing: 'antialiased',
'::placeholder': {
color: '#ccc',
},
iconColor: "#fff"
},
invalid: {
color: '#e5424d',
':focus': {
color: '#303238',
},
},
};
var stripe = Stripe('pk_test_TpmyYk1TnhrxPqNpImYwjyap');
var elements = stripe.elements();
var cardNumber = elements.create('cardNumber', {
placeholder: 'Add Card Number Here',
style: style
});
var cardExpiry = elements.create('cardExpiry', {
style: style
});
var cardCvc = elements.create('cardCvc', {
style: style
});
window.mobilecheck = function() {
var check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
};
if(mobilecheck()) {
cardNumber.mount('#Content > div > div > div > div.section.mcb-section.hide-desktop > div > div > div > div > div > div > div > form > div.form-row >div#card-number');
cardExpiry.mount('#Content > div > div > div > div.section.mcb-section.hide-desktop > div > div > div > div > div > div > div > form > div.form-row >div#card-expiry');
cardCvc.mount('#Content > div > div > div > div.section.mcb-section.hide-desktop > div > div > div > div > div > div > div > form > div.form-row >div#card-cvc');
}
else {
cardNumber.mount('#Content > div > div > div > div.section.mcb-section.hide-tablet.hide-mobile > div > div > div > div > div > div > div > form > div.form-row > div#card-number');
cardExpiry.mount('#Content > div > div > div > div.section.mcb-section.hide-tablet.hide-mobile > div > div > div > div > div > div > div > form > div.form-row > div#card-expiry');
cardCvc.mount('#Content > div > div > div > div.section.mcb-section.hide-tablet.hide-mobile > div > div > div > div > div > div > div > form > div.form-row > div#card-cvc');
}
cardNumber.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
var stop = 0;
// Create a token or display an error when the form is submitted.
var form = document.getElementById('add_payment_method');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(cardNumber).then(function(result) {
if (result.error) {
// Inform the customer that there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
if(stop == 0) {
console.log("inside stop token from being stored");
// Send the token to your server.
stripeTokenHandler(result.token);
stop = 1;
}
else {
stop = 0
}
}
});
});
function delete_cookie( name ) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
function createCookie(name,value) {
delete_cookie("stripe_token");
var date = new Date();
date.setTime(date.getTime()+1000);
var expires = "; expires="+date.toGMTString();
document.cookie = name+"="+value+expires+"; path=/; domain=.grahmlux.com";
//document.cookie = name+"="+value+expires+"; path=/";
}
function createUserIDCookie(name,value) {
document.cookie = name+"="+value+""+"; path=/; domain=.grahmlux.com";
//document.cookie = name+"="+value+""+"; path=/";
}
function stripeTokenHandler(token) {
var current_user_id = <?php echo $current_user_id; ?>
console.log("current_user_id:", current_user_id);
//MUST BE THIS ORDER BECAUSE OF DELETE_COOKIE
createUserIDCookie("user_id", current_user_id);
createCookie("stripe_token", token);
var form = document.getElementById('add_payment_method');
form.submit();
}
</script>
<?php endif; ?>
<?php do_action( 'woocommerce_after_account_payment_methods', $has_methods ); ?>
Anyone see any typos/anything that could be causing this to happen on mobile and not on desktop?
I needed to edit the css, the : was in a ::before tag.
I am trying to add a file upload along with radio inputs in a custom woocommerce page; where all the products are showing in a list view.
The Custom Page CODE:
<?php /*
Template Name: Custom Woo Product List Page
*/ ?>
<?php get_header();?>
<div class="inn_page">
<table id="wh_table" class="table table-hover" width="100%" cellspacing="0">
<thead>
<tr>
<th></th>
<th>PRODUCT</th>
<th>Monogram letter or Message Box</th>
<th>PRICE</th>
<th>Product Total Quantity</th>
<th></th>
</tr>
</thead>
<tbody>
<?php
$args = array(
'post_type' => array('product', 'product_variation'),
'post_status' => array('publish'),
'posts_per_page' => -1,
'product_cat' => '',
'post__in' => array( 178, 39, 180, 101, 182, 108, 184, 171, 872, 877, 206, 197, 1028, 330, 216, 451, 481, 478, 589 ),
'orderby' => 'post__in',
//'order' => 'DESC',
'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1 );
$wp_query = new WP_Query( $args );
while ( $wp_query->have_posts() ) : $wp_query->the_post();
global $product;
?>
<?php if ( $product->is_type( 'variable' ) )
{
show_variable_products_list();
}
else
{
?>
<tr class="product-<?php echo esc_attr( $product->id ); ?> variations_form" data-role="product">
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" name="upload_form" id="upload_form" method="post" enctype='multipart/form-data'>
<a href="<?php echo get_permalink( $wp_query->post->ID ) ?>" title="<?php echo esc_attr($wp_query->post->post_title ? $wp_query->post->post_title : $wp_query->post->ID); ?>">
<td class="image">
<?php woocommerce_show_product_sale_flash( $post, $product ); ?>
<?php if (has_post_thumbnail( $wp_query->post->ID )) echo get_the_post_thumbnail($wp_query->post->ID, 'wh_catalog'); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="150px" height="150px" />'; ?>
</td>
<td class="title">
<h3><?php the_title(); ?></h3>
<?php if ( ($product->get_id() == 178) || ($product->get_id() == 589) ) { ?>
<b>Sterling Silver</b>
<?php } ?>
</td>
<td class="note">
<?php letter_note(); ?>
<?php msg_note(); ?>
<?php upload_logo(); ?>
</td>
<td class="wh-price">
<span class="hiddenPrice"><?php echo $product->get_price_html() ?></span>
<span class="woocommerce-Price-amount ajaxPrice"><?php echo $product->get_price_html() ?></span>
</td>
</a>
<td class="quantity-field">
<?php woocommerce_quantity_input(); ?>
</td>
<td class="button-row">
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
<input type="hidden" name="product_id" value="<?php echo esc_attr( $product->id ); ?>" />
<div class="wh-button">
<button type="submit" class="single_add_to_cart_button btn btn-primary button wh-btn"><span class="glyphicon glyphicon-tag"></span> ADD TO CART</button>
</div>
</td>
</form>
</tr>
<?php } ?>
<?php endwhile; ?>
</tbody>
</table><!--/.products-->
<?php wp_reset_query(); ?>
</div>
<?php get_footer();?>
For variations to show in list view as different items/products in funtions.php
<?php
//----------------------------- START PRODUCT LIST VIEW PAGE CODE ----------------------------------
//-------------------------------------- Variations in Table List ---------------------------
function show_variable_products_list(){
global $product, $post;
$variations = find_valid_variations();
asort($variations);
foreach ($variations as $key => $value) {
if( !$value['variation_is_visible'] ) continue; ?>
<?php
$id_variation = $value['variation_id']
?>
<tr class="product-<?php echo esc_attr( $product->id ); ?> variation-<?php echo $value['variation_id']?> variations_form" data-role="product">
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo htmlspecialchars( json_encode( $available_variations ) ) ?>">
<td class="image">
<?php echo '<img src="'.$value['image_src'].'" alt="'.$product->get_title().'-'.$value['variation_id'].'" width="150px" height="150px" />'; ?>
</td>
<td class="title">
<h3><?php the_title(); ?></h3><br />
<b class="var-name"><?php
foreach($value['attributes'] as $attr_name => $attr_value ) {
$attr_name = 'pa_setting';
$attr = get_term_by('slug', $attr_value, $attr_name);
$attr_value = $attr->name;
echo $attr_value, ' ';
}
?></b>
<?php echo $id_variation ?>
</td>
<td class="note">
<?php letter_note(); ?>
<?php msg_note(); ?>
<?php upload_logo(); ?>
</td>
<td class="wh-price">
<span class="hiddenPrice"><?php echo $value['price_html'];?></span>
<span class="woocommerce-Price-amount ajaxPrice"><?php echo $value['price_html'];?></span>
</td>
<?php if( $value['is_in_stock'] ) { ?>
<td class="quantity-field">
<?php woocommerce_quantity_input(); ?>
</td>
<td class="button-row">
<?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
}
}
?>
<div class="wh-button">
<button type="submit" class="single_add_to_cart_button btn btn-primary button wh-btn"><span class="glyphicon glyphicon-tag"></span> ADD TO CART</button>
</div>
<input type="hidden" name="variation_id" class="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 } else { ?>
<p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
<?php } ?>
</td>
</form>
</tr>
<?php
}
}
?>
<?php
function find_valid_variations() {
global $product;
if ( $product->get_id() == 330 ) {
$variations = $product->get_available_variations();
//$attributes = $product->get_attributes();
$new_variants = array();
/* Show only the variations listed below */
foreach( $variations as $variation ) {
if ( $variation["variation_id"] == 971 || $variation["variation_id"] == 958 || $variation["variation_id"] == 945 || $variation["variation_id"] == 422 || $variation["variation_id"] == 412 || $variation["variation_id"] == 386 || $variation["variation_id"] == 358 ) {
$valid = true;
if( $valid )
$new_variants[] = $variation;
}
}
}
elseif ( $product->get_id() == 216 ) {
$variations = $product->get_available_variations();
$new_variants = array();
foreach( $variations as $variation ) {
if ( $variation["variation_id"] == 1010 || $variation["variation_id"] == 997 || $variation["variation_id"] == 984 || $variation["variation_id"] == 321 || $variation["variation_id"] == 295 || $variation["variation_id"] == 267 || $variation["variation_id"] == 237 ) {
$valid = true;
if( $valid )
$new_variants[] = $variation;
}
}
}
else {
$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"]) ) {
// Exists
} 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;
}
add_filter( 'woocommerce_variable_add_to_cart', 'show_variable_products_list', 10, 2 );
?>
I am able to add the radio values to cart & order but not able to do anything with file upload.
Please take a look:
add_action("woocommerce_before_add_to_cart_button", "upload_logo", 9);
function upload_logo(){
?>
<div>
<p>Want to add Logo? <input type="checkbox" id="showHide" onclick="myFunction()"><b>Tick</b></p>
<p id="hiddenInputs" style="display:none">
<label for="radio_field">
Where you want the logo?
<input type="radio" name="radio_field" checked="checked" value="Front Side"> Front Side
<input type="radio" name="radio_field" value="Back Side"> Back Side
<input type="radio" name="radio_field" value="Both Side"> Both Side
</label> <br />
<label for="file_field">
Upload logo: <input type="file" name="file_field" value="">
</label> <br />
</p>
</div>
<script>
function myFunction() {
var checkboxToShowInputs = document.getElementById("showHide");
var showInputs = document.getElementById("hiddenInputs");
if (checkboxToShowInputs.checked == true){
showInputs.style.display = "block";
} else {
showInputs.style.display = "none";
}
}
</script>
<?php
}
/* Add File custom data to the cart item */
function file_upload_add_cart_item_data( $cart_item, $product_id ){
if( isset( $_POST['file_field'] ) ) {
$cart_item['logo_upload'] = $_POST['file_field'];
}
return $cart_item;
}
add_filter( 'woocommerce_add_cart_item_data', 'file_upload_add_cart_item_data', 10, 2 );
/* Add Radio custom data to the cart item */
// Stores the custom field value in Cart object
add_action( 'woocommerce_add_cart_item_data', 'save_custom_product_field_data', 10, 2 );
function save_custom_product_field_data( $cart_item, $product_id ) {
if( isset( $_REQUEST['radio_field'] ) ) {
$cart_item[ 'side_radio' ] = $_REQUEST['radio_field'];
// below statement make sure every add to cart action as unique line item
$cart_item['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'my_order_data', $_REQUEST['radio_field'] );
}
return $cart_item;
}
/* Load File cart data from session */
function file_upload_get_cart_item_from_session( $cart_item, $values ) {
if ( isset( $values['logo_upload'] ) ){
$cart_item['logo_upload'] = $values['logo_upload'];
}
return $cart_item;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'file_upload_get_cart_item_from_session', 20, 2 );
/* Load Radio cart data from session */
function radio_get_cart_item_from_session( $cart_item, $values ) {
if ( isset( $values['side_radio'] ) ){
$cart_item['side_radio'] = $values['side_radio'];
}
return $cart_item;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'radio_get_cart_item_from_session', 20, 2 );
/* Add File meta to order item */
function file_upload_add_order_item_meta( $item_id, $values ) {
if ( ! empty( $values['logo_upload'] ) ) {
woocommerce_add_order_item_meta( $item_id, 'logo_upload', $values['logo_upload'] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'file_upload_add_order_item_meta', 10, 2 );
/* Add Radio meta to order item */
function radio_add_order_item_meta( $item_id, $values ) {
if ( ! empty( $values['side_radio'] ) ) {
woocommerce_add_order_item_meta( $item_id, 'side_radio', $values['side_radio'] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'radio_add_order_item_meta', 10, 2 );
/* Get File item data to display in cart */
function file_upload_get_item_data( $other_data, $cart_item ) {
if ( ! empty ( $cart_item['logo_upload'] ) ){
$other_data[] = array(
'name' => __( 'Logo ', 'woocommerce' ),
'value' => $cart_item['logo_upload']
);
}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'file_upload_get_item_data', 10, 2 );
/* Get Radio item data to display in cart */
function radio_get_item_data( $other_data, $cart_item ) {
if ( ! empty ( $cart_item['side_radio'] ) ){
$other_data[] = array(
'name' => __( 'Side ', 'woocommerce' ),
'value' => $cart_item['side_radio']
);
}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'radio_get_item_data', 10, 2 );
/* Show File field in order overview */
function file_upload_order_item_product( $cart_item, $order_item ){
if( isset( $order_item['logo_upload'] ) ){
$cart_item_meta['logo_upload'] = $order_item['logo_upload'];
}
return $cart_item;
}
add_filter( 'woocommerce_order_item_product', 'file_upload_order_item_product', 10, 2 );
/* Show Radio field in order overview */
function radio_order_item_product( $cart_item, $order_item ){
if( isset( $order_item['side_radio'] ) ){
$cart_item_meta['side_radio'] = $order_item['side_radio'];
}
return $cart_item;
}
add_filter( 'woocommerce_order_item_product', 'radio_order_item_product', 10, 2 );
/* Add the File Upload field to order emails */
function file_upload_email_order_meta_fields( $fields ) {
$fields['custom_field'] = __( 'Logo ', 'woocommerce' );
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'file_upload_email_order_meta_fields');
/* Add the Radio field to order emails */
function radio_email_order_meta_fields( $fields ) {
$fields['custom_field'] = __( 'Side ', 'woocommerce' );
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'radio_email_order_meta_fields');
Here's the AJAX PHP
function ajax_add_to_cart_script() {
wp_enqueue_script( 'add-to-cart-wh_ajax', plugins_url() . '/wh-page-ajax-add-to-cart/js/add-to-cart-wh.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'ajax_add_to_cart_script',99 );
add_action( 'wp_ajax_woocommerce_add_to_cart_wh_sh', 'woocommerce_add_to_cart_wh_sh_callback' );
add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart_wh_sh', 'woocommerce_add_to_cart_wh_sh_callback' );
function woocommerce_add_to_cart_wh_sh_callback() {
ob_start();
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
$quantity = empty( $_POST['quantity'] ) ? 1 : apply_filters( 'woocommerce_stock_amount', $_POST['quantity'] );
$variation_id = $_POST['variation_id'];
$variation = $_POST['variation'];
$letter = $_POST['_letter'];
$message = $_POST['_message'];
$radio = $_POST['radio_field'];
//$file = $_POST['file_field'];
$file = $_FILES['id_proof'];;
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $quantity, $cart_item_data, $letter, $message, $radio, $file );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $letter, $message, $radio, $file ) ) {
do_action( 'woocommerce_ajax_added_to_cart', $product_id );
if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
wc_add_to_cart_message( $product_id );
}
// Return fragments
WC_AJAX::get_refreshed_fragments();
} else {
$this->json_headers();
// If there was an error adding to the cart, redirect to the product page to show any errors
$data = array(
'error' => true,
'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
);
echo json_encode( $data );
}
die();
}
And here's the edited js
/* AJAX Add to Cart Button */
jQuery(function($) {
// wc_add_to_cart_params is required to continue, ensure the object exists
if (typeof wc_add_to_cart_params === 'undefined')
return false;
// Ajax add to cart
$(document).on('click', '.variations_form .wh-btn', function(e) {
e.preventDefault();
$variation_form = $(this).closest('.variations_form');
var var_id = $variation_form.find('input[name=variation_id]').val();
var product_id = $variation_form.find('input[name=product_id]').val();
var quantity = $variation_form.find('input[name=quantity]').val();
var letter = $variation_form.find('input[name=_wholesale_letter]').val();
var message = $variation_form.find('input[name=_wholesale_message]').val();
var rad = $variation_form.find('input[name=radio_field]:checked').val();
var file = $variation_form.find('input[name=file_field]').val();
//var file = $variation_form.find('input[name=file_field]').files[0].path;
//attributes = [];
$('.ajaxerrors').remove();
var item = {},
check = true;
variations = $variation_form.find('select[name^=attribute]');
/* Updated code to work with radio button - mantish - WC Variations Radio Buttons - 8manos */
if (!variations.length) {
variations = $variation_form.find('[name^=attribute]:checked');
}
/* Backup Code for getting input variable */
if (!variations.length) {
variations = $variation_form.find('input[name^=attribute]');
}
variations.each(function() {
var $this = $(this),
attributeName = $this.attr('name'),
attributevalue = $this.val(),
index,
attributeTaxName;
$this.removeClass('has-error');
if (attributevalue.length === 0) {
index = attributeName.lastIndexOf('_');
attributeTaxName = attributeName.substring(index + 1);
$this
//.css( 'border', '1px solid red' )
.addClass('required has-error')
//.addClass( 'barizi-class' )
.before('<div class="ajaxerrors"><p>OH No Please select ' + attributeTaxName + '</p></div>')
//check = false;
} else {
item[attributeName] = attributevalue;
}
});
if (!check) {
return false;
}
/* Validate for All the input Message field */
var itemMessages = {},
checkmsg = true;
messages = $variation_form.find('input[name=_message');
messages.each(function() {
var $this = $(this),
attributeName = $this.attr('name'),
attributevalue = $this.val(),
index,
attributeTaxName;
$this.removeClass('required wh-error');
if (attributevalue.length === 0) {
index = attributeName.lastIndexOf('_');
attributeTaxName = attributeName.substring(index + 1);
$this
.removeClass('wh-input')
.addClass('required wh-error')
.before('<div class="ajaxerrors"><p><span style="font-weight: bold;">REQUIRED!</span> Please Type Some Text or Number.</p></div>')
//checkmsg = false;
} else {
itemMessages[attributeName] = attributevalue;
$this.addClass('wh-input');
}
});
if (!checkmsg) {
return false;
}
/* Validate One Letter Input Field */
var itemLetter = {},
checkltr = true;
letterOne = $variation_form.find('input[name=_letter]');
letterOne.each(function() {
var $this = $(this),
attributeName = $this.attr('name'),
attributevalue = $this.val(),
index,
attributeTaxName;
$this.removeClass('required wh-error');
if (attributevalue.length === 0) {
index = attributeName.lastIndexOf('_');
attributeTaxName = attributeName.substring(index + 1);
$this
/* .css({
'border': '2px solid #a94442',
'box-shadow': 'inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483'
})*/
.removeClass('wh-input')
.addClass('required wh-error')
.before('<div class="ajaxerrors"><p><span style="font-weight: bold;">REQUIRED!</span> Please Type 1 Letter or Number.</p></div>')
//checkmsg = false;
} else {
itemLetter[attributeName] = attributevalue;
$this.addClass('wh-input');
}
});
if (!checkltr) {
return false;
}
//item = JSON.stringify(item);
//alert(item);
//return false;
// AJAX add to cart request
var $thisbutton = $(this);
if ($thisbutton.is('.variations_form .wh-btn')) {
$thisbutton.removeClass('added');
$thisbutton.addClass('loading');
$thisbutton.attr("disabled", "disabled");
var data = {
action: 'woocommerce_add_to_cart_wh_sh',
product_id: product_id,
quantity: quantity,
variation_id: var_id,
variation: item,
_letter: letter,
_message: message,
radio_field: rad,
file_field: file
};
$.each($thisbutton.data(), function(key, value) {
data[key] = value;
});
// Trigger event
$('body').trigger('adding_to_cart', [$thisbutton, data]);
// Ajax action
$.post(wc_add_to_cart_params.ajax_url.toString().replace('%%endpoint%%', 'add_to_cart'), data, function(response) {
if (!response) {
return;
}
var this_page = window.location.toString();
this_page = this_page.replace('add-to-cart', 'added-to-cart');
if (response.error && response.product_url) {
window.location = response.product_url;
return;
}
if (wc_add_to_cart_params.cart_redirect_after_add === 'yes') {
window.location = wc_add_to_cart_params.cart_url;
return;
} else {
$thisbutton.removeClass('loading');
var fragments = response.fragments;
var cart_hash = response.cart_hash;
// Block fragments class
if (fragments) {
$.each(fragments, function(key) {
$(key).addClass('updating');
});
}
// Block widgets and fragments
$('.shop_table.cart, .updating, .cart_totals').fadeTo('400', '0.6').block({
message: null,
overlayCSS: {
opacity: 0.6
}
});
// Changes button classes
$thisbutton.addClass('added');
// View cart text
/* if ( ! wc_add_to_cart_params.is_cart && $thisbutton.parent().find( '.added_to_cart' ).size() === 0 ) {
$thisbutton.after( ' <a href="' + wc_add_to_cart_params.cart_url + '" class="added_to_cart wc-forward" title="' +
wc_add_to_cart_params.i18n_view_cart + '">' + wc_add_to_cart_params.i18n_view_cart + '</a>' );
}
// View cart text
if (!wc_add_to_cart_params.is_cart && $variation_form.find('.added_to_cart').length === 0) {
$thisbutton.after(' <a href="' + wc_add_to_cart_params.cart_url + '" class="added_to_cart wc-forward" title="' +
wc_add_to_cart_params.i18n_view_cart + '">' + wc_add_to_cart_params.i18n_view_cart + '</a>');
}
*/
// Replace fragments
if (fragments) {
$.each(fragments, function(key, value) {
$(key).replaceWith(value);
});
}
// Unblock
$('.widget_shopping_cart, .updating').stop(true).css('opacity', '1').unblock();
// Cart page elements
$('.shop_table.cart').load(this_page + ' .shop_table.cart:eq(0) > *', function() {
$('.shop_table.cart').stop(true).css('opacity', '1').unblock();
$(document.body).trigger('cart_page_refreshed');
});
$('.cart_totals').load(this_page + ' .cart_totals:eq(0) > *', function() {
$('.cart_totals').stop(true).css('opacity', '1').unblock();
});
// Trigger event so themes can refresh other areas
$(document.body).trigger('added_to_cart', [fragments, cart_hash, $thisbutton]);
}
})
.done(function(response) {
if ($variation_form.find('.added_to_cart').length === 0) {
$thisbutton.after(' <a href="' + wc_add_to_cart_params.cart_url + '" class="added_to_cart wc-forward" title="' +
wc_add_to_cart_params.i18n_view_cart + '">' + wc_add_to_cart_params.i18n_view_cart + '</a>');
}
$thisbutton.removeAttr("disabled", "disabled");
$thisbutton.removeClass('failed')
var quantity = $variation_form.find('input[name=quantity]').val("1");
var letter = $variation_form.find('input[name=_letter]').val("");
var message = $variation_form.find('input[name=_message]').val("");
var rad = $variation_form.find('input[name=radio_field]').val("Front Side");
})
.fail(function(response) {
setTimeout(function() {
$thisbutton.removeClass('loading');
$thisbutton.removeAttr("disabled", "disabled");
}, 2000);
$thisbutton.addClass('failed');
})
return false;
} else {
return true;
}
});
});
This page is only accessible to certain users, so it has different input fields, price than the single product page counterpart. Client don't like this page to be refreshed so I had to add AJAX, with the little knowledge I have. Now it's getting more complicated so please help me out.
Update 2021 - Still works perfectly on last WooCommerce version (5.1.x).
In your actual code, there is many mistakes as:
Repetitive hooked functions using the same hook, that need to be merged instead.
Deprecated hooked functions.
Not useful or not needed hooked functions.
Wrong or missing code related to file upload
Here is your revisited code (much more lighter, compact and complete):
// Display additional product fields (+ jQuery code)
add_action( 'woocommerce_before_add_to_cart_button', 'display_additional_product_fields', 9 );
function display_additional_product_fields(){
// Array of radio button options
$options = array( __("Front Side"), __("Back Side"), __("Both Sides") );
// Temporary styles
?>
<style>
.upload-logo a.button { padding: .3em .75em !important; }
.upload-logo a.button.on { background-color: #CC0000 !important; color: #FFFFFF !important; }
.upload-logo p span { display:inline-block; padding:0 8px 0 4px; }
</style><?php
// Html output ?>
<div class="upload-logo">
<p><strong><?php _e( "Add a Logo option"); ?>: </strong>
<?php _e( "Yes" ); ?>
<input type="hidden" name="upload_active" value="">
</p>
<div id="hidden-inputs" style="display:none">
<p><label for="radio_field"><?php
echo __( "Where you want the logo?" ) . ' <br>';
// Loop though each $options array
foreach( $options as $key => $option ) {
$atts = $key == 0 ? 'name="side_field" checked="checked"' : 'name="side_field"'; ?>
<input type="radio" <?php echo $atts; ?> value="<?php echo $option; ?>"><span> <?php echo $option . '</span> ';
}
?>
</label></p>
<p><label for="file_field"><?php echo __("Upload logo") . ': '; ?>
<input type='file' name='image' accept='image/*'>
</label></p>
</div>
</div><?php
// Javascript (jQuery) ?>
<script type="text/javascript">
jQuery( function($){
var a = '.upload-logo', b = a+' a.button',
c = a+' #hidden-inputs', d = a+' input[type=hidden]';
$(b).click(function(e){
e.preventDefault();
if( ! $(this).hasClass('on') ) {
$(this).addClass('on');
$(c).show();
$(d).val('1');
} else {
$(this).removeClass('on');
$(c).hide('fast');
$(d).val('');
}
});
});
</script>
<?php
}
// # ===> Manage the file upload <=== #
// Add custom fields data as the cart item custom data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_fields_data_as_custom_cart_item_data', 10, 2 );
function add_custom_fields_data_as_custom_cart_item_data( $cart_item, $product_id ){
if( isset($_POST['upload_active']) && $_POST['upload_active'] && isset($_FILES['image']) ) {
$upload = wp_upload_bits( $_FILES['image']['name'], null, file_get_contents( $_FILES['image']['tmp_name'] ) );
$filetype = wp_check_filetype( basename( $upload['file'] ), null );
$upload_dir = wp_upload_dir();
$upl_base_url = is_ssl() ? str_replace('http://', 'https://', $upload_dir['baseurl']) : $upload_dir['baseurl'];
$base_name = basename( $upload['file'] );
$cart_item['custom_file'] = array(
'guid' => $upl_base_url .'/'. _wp_relative_upload_path( $upload['file'] ),
'file_type' => $filetype['type'],
'file_name' => $base_name,
'title' => preg_replace('/\.[^.]+$/', '', $base_name ),
'side' => isset( $_POST['side_field'] ) ? sanitize_text_field( $_POST['side_field'] ) : '',
'key' => md5( microtime().rand() ),
);
}
return $cart_item;
}
// Display custom cart item data in cart
add_filter( 'woocommerce_get_item_data', 'display_custom_item_data', 10, 2 );
function display_custom_item_data( $cart_item_data, $cart_item ) {
if ( isset( $cart_item['custom_file']['title'] ) ){
$cart_item_data[] = array(
'name' => __( 'Logo', 'woocommerce' ),
'value' => $cart_item['custom_file']['title']
);
}
if ( isset( $cart_item['custom_file']['side'] ) ){
$cart_item_data[] = array(
'name' => __( 'Side', 'woocommerce' ),
'value' => $cart_item['custom_file']['side']
);
}
return $cart_item_data;
}
// Save and display Logo data in orders and email notifications (everywhere)
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_field_update_order_item_meta', 20, 4 );
function custom_field_update_order_item_meta( $item, $cart_item_key, $values, $order ) {
if ( isset( $values['custom_file'] ) ){
$item->update_meta_data( __('Logo'), $values['custom_file']['title'] );
$item->update_meta_data( __('Side'), $values['custom_file']['side'] );
$item->update_meta_data( '_logo_file_data', $values['custom_file'] );
}
}
// Display a linked button + the link of the logo file in backend
add_action( 'woocommerce_after_order_itemmeta', 'backend_logo_link_after_order_itemmeta', 20, 3 );
function backend_logo_link_after_order_itemmeta( $item_id, $item, $product ) {
// Only in backend for order line items (avoiding errors)
if( is_admin() && $item->is_type('line_item') && $item->get_meta('_logo_file_data') ){
$file_data = $item->get_meta( '_logo_file_data' );
echo '<p>'.__("Open Logo") . '</p>';
echo '<p>Link: <textarea type="text" class="input-text" readonly>'.$file_data['guid'].'</textarea></p>';
}
}
This code goes in functions.php file of your active child theme (or active theme).
Tested in Woocommerce version 3.4.x and working with normal products (from all types)
Frontend: orders display (and email notifications):
Backend (Admin): Display on orders edit pages:
I am developing a wordpress plugin to allow users to submit a post from the frontend.
I have added a validation method and it works. How do I implement ajax validation in my code?
<?php
function exclutips_fep($content = null) {
global $post;
ob_start();
?>
<style>
#fep-new-post label{display:inline-block;width:15%;}
#fep-post-title input{width:60%;}
#fep-new-post input[type="submit"]{margin-left:15%;width:30%;padding:7px;}
#fep-new-post textarea{ display:inline-block;width:80%;vertical-align:top;}
</style>
<div id="exclutips-fep-postbox" class="<?php if(is_user_logged_in()) echo 'closed'; else echo 'loggedout'?>">
<?php do_action( 'exclutips-fep-notice' ); ?>
<div class="exclutips-fep-inputarea">
<?php if(is_user_logged_in()) { ?>
<form id="fep-new-post" name="new_post" method="post" action="<?php the_permalink(); ?>">
<p><label>Post Title *</label><input type="text" id ="fep-post-title" name="post-title" /></p>
<p>
<?php
$settings = array(
'textarea_rows' => 14,
'teeny' => true,
'quicktags' => false,
'textarea_name' => 'post-content',
'media_buttons' => true,
'editor_class' => 'front-end-post',
'tinymce' => array(
'theme_advanced_buttons1' => 'formatselect,|,bold,italic,underline,|,' .
'bullist,blockquote,|,justifyleft,justifycenter' .
',justifyright,justifyfull,|,link,unlink,|' .
',spellchecker,wp_fullscreen,wp_adv'
)
);
wp_editor( '', 'content', $settings);
?>
</p>
<p><label>Category</label>
<select name="post-category">
<option value=""><?php echo esc_attr_e( 'Select Category', 'exclutips-fep' ); ?></option>
<?php
$args = array(
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
printf( '<option value="%1$s">%2$s</option>',
esc_attr( '/category/archives/' . $category->category_nicename ),
esc_html( $category->cat_name )
);
}
?>
</select>
</p>
<p><label>Tags</label><input id="fep-tags" name="tags" type="text" tabindex="2" autocomplete="off" value="<?php esc_attr_e( 'Add tags', 'exclutips-fep' ); ?>" onfocus="this.value=(this.value=='<?php echo esc_js( __( 'Add tags', 'exclutips-fep' ) ); ?>') ? '' : this.value;" onblur="this.value=(this.value=='') ? '<?php echo esc_js( __( 'Add tags', 'exclutips-fep' ) ); ?>' : this.value;" /></p>
<input id="submit" type="submit" tabindex="3" value="<?php esc_attr_e( 'Post', 'exclutips-fep' ); ?>" />
<input type="hidden" name="action" value="post" />
<input type="hidden" name="empty-description" id="empty-description" value="1"/>
<?php wp_nonce_field( 'new-post' ); ?>
</form>
<?php } else { ?>
<h4 class="exclutips-fep-error">Please Log-in To Post</h4>
<?php } ?>
</div>
</div> <!-- #exclutips-fep-postbox -->
<?php
// Output the content.
$output = ob_get_contents();
ob_end_clean();
// return only if we're inside a page. This won't list anything on a post or archive page.
if (is_page()) return $output;
}
// Add the shortcode to WordPress. [exclutips-fep]
add_shortcode('exclutips-fep', 'exclutips_fep');
function exclutips_fep_errors(){
?>
<style>
.exclutips-fep-error{border:1px solid #CC0000;border-radius:5px;background-color: #FFEBE8;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
global $error_array;
foreach($error_array as $error){
echo '<p class="exclutips-fep-error">' . $error . '</p>';
}
}
function exclutips_fep_notices(){
?>
<style>
.exclutips-fep-notice{ border:1px solid #E6DB55;border-radius:5px;background-color: #FFFBCC;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
global $notice_array;
foreach($notice_array as $notice){
echo '<p class="exclutips-fep-notice">' . $notice . '</p>';
}
}
function exclutips_fep_add_post(){
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'post' ){
if ( !is_user_logged_in() )
return;
global $current_user;
$user_id = $current_user->ID;
$post_title = $_POST['post-title'];
$post_content = $_POST['post-content'];
$post_category = $_POST['post-category'];
$tags = $_POST['tags'];
global $error_array;
$error_array = array();
if (empty($post_title)) $error_array[]='Please add a post title.';
if (empty($post_content)) $error_array[]='Please add some content.';
if (empty($post_category)) $error_array[]='Please select category.';
if (count($error_array) == 0){
$post_id = wp_insert_post( array(
'post_author' => $user_id,
'post_title' => $post_title,
'post_type' => 'post',
'post_content' => $post_content,
'post_category' => $post_category,
'tags_input' => $tags,
'post_status' => 'publish'
) );
global $notice_array;
$notice_array = array();
$notice_array[] = "Thank you for posting. Your post is now live. ";
add_action('exclutips-fep-notice', 'exclutips_fep_notices');
} else {
add_action('exclutips-fep-notice', 'exclutips_fep_errors');
}
}
}
add_action('init','exclutips_fep_add_post');
Please try it.. it is works for me.
1) call this on click of your button.. (it is the code of your lending page)
var pathname = window.location.pathname;
var firstName = $('#firstName').val();
var lastName = $('#lastName').val();
var email = $('#email').val();
var phoneNumber = $('#phoneNumber').val();
var data = new Array (firstName,lastName,email,phoneNumber);
$.get( ajax_request_url,
{
'action' : 'get_myusers',
'data' : data,
'pathname' : pathname
},
function( response )
{
$('.displayUsers').html(response);
$('#myForm')[0].reset();
$('.addForm').hide();
$('.displayAddForm').show();
$('.hideAddForm').hide();
}, "html" );
2) this is functions.php code
/* custom function for display user
* using ajax user add update delete
*/
add_action('wp_footer', 'eps_footer');
function eps_footer() {
echo "<script>var ajax_request_url = '".admin_url( 'admin-ajax.php' )."'</script>";
}
//Get user Ajax
add_action( 'wp_ajax_nopriv_get_myusers', 'get_myusers' );
add_action( 'wp_ajax_get_myusers', 'get_myusers' );
function get_myusers()
{
$userArray = $_REQUEST['data'];
$table = "my_table";
$data = array(firstName=>$userArray[0],lastName=>$userArray[1],email=>$userArray[2],foneNumber=>$userArray[3]);
global $wpdb;
$wpdb->insert( $table, $data );
?>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Phone Number</th>
<th>Action</th>
</tr>
<?php
$users = $wpdb->get_results( "SELECT * FROM my_table" );
foreach($users as $user)
{
?>
<tr id="displayTr<?php echo $user->my_table_id;?>">
<td><?php echo $user->firstName; ?></td>
<td><?php echo $user->lastName; ?></td>
<td><?php echo $user->email; ?></td>
<td><?php echo $user->foneNumber; ?></td>
<td>
Delete
Edit
</td>
</tr>
<tr style="display:none;" class="editTr" id="editTr<?php echo $user->my_table_id;?>">
<td><input type="text" id="firstName<?php echo $user->my_table_id;?>" value="<?php echo $user->firstName; ?>"></td>
<td><input type="text" id="lastName<?php echo $user->my_table_id;?>" value="<?php echo $user->lastName; ?>"></td>
<td><input type="text" id="email<?php echo $user->my_table_id;?>" value="<?php echo $user->email; ?>"></td>
<td><input type="text" id="phoneNumber<?php echo $user->my_table_id;?>" value="<?php echo $user->foneNumber; ?>"></td>
<td>
Update
Cancle
</td>
</tr>
<?php
}
?>
</table>
<?php
}
die();
You can do like some steps below:
Step 1: Localize WP Ajax URL
<?php
add_action('wp_head','pluginname_ajaxurl');
function pluginname_ajaxurl() { ?>
<script type="text/javascript">
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
</script>
<?php
}
Step 2: Send your post information by using ajax
$.ajax({
type: 'post',
url: ajaxurl ,
data: {
action: 'validation',
data: [yourdata]
},
beforeSend: function() {},
success: function(resp) {
}
});
Step 3: Receive data on PHP server by using WP Hook
<?php
// this action will run for loged in user
add_action('wp_ajax_validation', 'exclutips_fep_add_post');
// This action will run for visitor
add_action('wp_ajax_wp_ajax_nopriv_validation', 'exclutips_fep_add_post');?>
Hope Those can help you solve your problem.
Your question is a bit open ended. But one important piece of security validation is implementing nonces. This checks the ajax request is coming from your site as intended, which prevents a variety of attacks.
In your php you create a nonce and pass it into the javascript as a variable.
wp_register_script( 'your-script', /*file url here*/ , /*dependencies here*/, false, false);
$params = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('name-the-nonce'),
);
wp_localize_script( 'your-script', 'jsParameters', $params );
wp_enqueue_script( 'your-script' );
In your javascript you pass the nonce to the php like so:
var ajaxRequest = $.post(
jsParameters.ajaxurl,
{
action: 'your_action',
// send the nonce along with the request
nonce: jsParameters.nonce
},
function (response) {
//some reponse code
}
);
Within the AJAX php function you perform this validation:
$nonce = $_POST['nonce'];
if (!wp_verify_nonce($nonce, 'name-the-nonce'))
die('Busted');
//continue executing ajax php code
Some external material on the matter:
https://codex.wordpress.org/WordPress_Nonces
http://www.barrykooij.com/check-nonces-wordpress-ajax-calls/
I just created a simple theme option page that is working fine and also saved after when press save options.
But when I go somewhere else from theme options page and come back to theme options page that settings what I saved just disappear and I have to change that again whenever I come to theme options page.
Here is my code
add_action( 'admin_menu', 'theme_options_add_page' );
if ( get_option('new_theme_options')) {
$theme_options = get_option('new_theme_options');
} else {
add_option('new_theme_options', array (
'sidebar2_on' => true,
'footer_text' => ''
));
$theme_options = get_option('new_theme_options');
}
function theme_options_add_page() {
add_submenu_page( 'themes.php', 'My Theme Options', 'Theme Options', 8, 'themeoptions', 'theme_options_do_page' );
}
function theme_options_do_page() {
global $theme_options;
$new_values = array (
'footer_text' => htmlentities($_POST['footer_text'], ENT_QUOTES),
);
update_option('new_theme_options', $new_values);
$theme_options = $new_values;
?>
<div class="wrap">
<?php screen_icon(); echo "<h2>" . get_current_theme() . __( ' Theme Options', 'responsivetheme' ) . "</h2>"; ?>
<form method="post" action="themes.php?page=themeoptions">
<label for="footer_text">Footer Text:</label>
<input id="footer_text" type="text" name="footer_text" value="<?php echo $theme_options['footer_text']; ?>" />
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e( 'Save Options', 'responsivetheme' ); ?>" />
</p>
</form>
</div>
<?php
}
#Praveen answer is correct, but for completeness I'll post the full code I tested. Please, note that you should always develop with WP_DEBUG enabled. It shows three issues with your code:
using $_POST['footer_text'] without it being defined (Praveen's answer)
using the deprecated function get_current_theme()
using Level instead of Capability in add_submenu_page()
I dropped the following code into my theme's functions.php and it works ok:
if ( get_option('new_theme_options')) {
$theme_options = get_option('new_theme_options');
} else {
$theme_options = array (
'sidebar2_on' => true,
'footer_text' => ''
);
add_option( 'new_theme_options', $theme_options );
}
add_action( 'admin_menu', 'theme_options_add_page' );
function theme_options_add_page() {
add_submenu_page(
'themes.php',
'My Theme Options',
'Theme Options',
'add_users',
'themeoptions',
'theme_options_do_page'
);
}
function theme_options_do_page() {
global $theme_options;
if( isset( $_POST['footer_text'] ) ) {
$new_values = array (
'footer_text' => htmlentities( $_POST['footer_text'], ENT_QUOTES),
);
update_option('new_theme_options', $new_values);
$theme_options = $new_values;
}
?>
<div class="wrap">
<?php screen_icon(); echo "<h2>" . wp_get_theme() . __( ' Theme Options', 'responsivetheme' ) . "</h2>"; ?>
<form method="post" action="themes.php?page=themeoptions">
<label for="footer_text">Footer Text:</label>
<input id="footer_text" type="text" name="footer_text" value="<?php echo $theme_options['footer_text']; ?>" />
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e( 'Save Options', 'responsivetheme' ); ?>" />
</p>
</form>
</div>
<?php
}
The only issue I can see is the option value sidebar2_on that's being overwritten in theme_options_do_page(), but your sample code does not show it being used elsewhere.
Please change this code:
if($_POST['footer_text']) {
$new_values = array (
'footer_text' => htmlentities($_POST['footer_text'], ENT_QUOTES),
);
update_option('new_theme_options', $new_values);
$theme_options = $new_values;
}
hope this will work fine :)