Add Custom Cart Item Data in WooCommerce

Add custom field in WooCommerce product.

 

Add a Custom Field to Your Product

/**
 * Output engraving field.
 */
function iconic_output_engraving_field() {
	global $product;

	if ( $product->get_id() !== 1741 ) {
		return;
	}

	?>
	

<div class="iconic-engraving-field">
		<label for="iconic-engraving"><?php _e( 'Engraving (10 characters)', 'iconic' ); ?></label>
		<input type="text" id="iconic-engraving" name="iconic-engraving" placeholder="<?php _e( 'Enter engraving text', 'iconic' ); ?>" maxlength="10">
	</div>


	<?php
}

add_action( 'woocommerce_before_add_to_cart_button', 'iconic_output_engraving_field', 10 );

Add Engraving Data to the Cart Item

/**
 * Add engraving text to cart item.
 *
 * @param array $cart_item_data
 * @param int   $product_id
 * @param int   $variation_id
 *
 * @return array
 */
function iconic_add_engraving_text_to_cart_item( $cart_item_data, $product_id, $variation_id ) {
	$engraving_text = filter_input( INPUT_POST, 'iconic-engraving' );

	if ( empty( $engraving_text ) ) {
		return $cart_item_data;
	}

	$cart_item_data['iconic-engraving'] = $engraving_text;

	return $cart_item_data;
}

add_filter( 'woocommerce_add_cart_item_data', 'iconic_add_engraving_text_to_cart_item', 10, 3 );

Display Engraving Data in the Cart

/**
 * Display engraving text in the cart.
 *
 * @param array $item_data
 * @param array $cart_item
 *
 * @return array
 */
function iconic_display_engraving_text_cart( $item_data, $cart_item ) {
	if ( empty( $cart_item['iconic-engraving'] ) ) {
		return $item_data;
	}

	$item_data[] = array(
		'key'     => __( 'Engraving', 'iconic' ),
		'value'   => wc_clean( $cart_item['iconic-engraving'] ),
		'display' => '',
	);

	return $item_data;
}

add_filter( 'woocommerce_get_item_data', 'iconic_display_engraving_text_cart', 10, 2 );

Add engraving text to order.


/**
 * Add engraving text to order.
 *
 * @param WC_Order_Item_Product $item
 * @param string                $cart_item_key
 * @param array                 $values
 * @param WC_Order              $order
 */
function iconic_add_engraving_text_to_order_items( $item, $cart_item_key, $values, $order ) {
	if ( empty( $values['iconic-engraving'] ) ) {
		return;
	}

	$item->add_meta_data( __( 'Engraving', 'iconic' ), $values['iconic-engraving'] );
}

add_action( 'woocommerce_checkout_create_order_line_item', 'iconic_add_engraving_text_to_order_items', 10, 4 );

Reference

Advertisements

Play Pause Vimeo or YouTube multiple video JavaScript

have found a solution to starting/pausing multiple Vimeo and YouTube videos from separate buttons

YouTube


<a href="javascript:void callPlayer(&quot;whateverID&quot;,&quot;playVideo&quot;)">Start</a> &bull; <a href="javascript:void callPlayer(&quot;whateverID&quot;,&quot;pauseVideo&quot;)">Pause</a> &bull; <a href="javascript:void callPlayer(&quot;whateverID&quot;,&quot;stopVideo&quot;)">Stop</a> - Hover over the links to see the called function




<div id="whateverID"><iframe width="640" height="390" frameborder="0" title="YouTube video player" type="text/html" src="http://www.youtube.com/embed/u1zgFlCw8Aw?enablejsapi=1"></iframe></div>




<a href="javascript:void callPlayer(&quot;whateverID1&quot;,&quot;playVideo&quot;)">Start</a> &bull; <a href="javascript:void callPlayer(&quot;whateverID1&quot;,&quot;pauseVideo&quot;)">Pause</a> &bull; <a href="javascript:void callPlayer(&quot;whateverID1&quot;,&quot;stopVideo&quot;)">Stop</a> - Hover over the links to see the called function




<div id="whateverID1"><iframe width="640" height="390" frameborder="0" title="YouTube video player" type="text/html" src="http://www.youtube.com/embed/AkwVg9viC-g?enablejsapi=1"></iframe></div>




function callPlayer(frame_id, func, args) {
if (window.jQuery && frame_id instanceof jQuery) frame_id = frame_id.get(0).id;
var iframe = document.getElementById(frame_id);
if (iframe && iframe.tagName.toUpperCase() != 'IFRAME') {
iframe = iframe.getElementsByTagName('iframe')[0];
}
if (iframe) {
// Frame exists,
iframe.contentWindow.postMessage(JSON.stringify({
"event": "command",
"func": func,
"args": args || [],
"id": frame_id
}), "*");
}
}

Vimeo

Single video (simpler) version here: <a href="https://codepen.io/filipbech/pen/cbaxq">https://codepen.io/filipbech/pen/cbaxq</a>


<iframe width="560" height="315" src="//player.vimeo.com/video/5705212?api=1&player_id=video1" id="video1"></iframe>
<button class="play" data-id="video1">Play</button>
<button class="pause" data-id="video1">Pause</button>



<iframe width="560" height="315" src="//player.vimeo.com/video/5705212?api=1&player_id=video2" id="video2"></iframe>
<button class="play" data-id="video2">Play</button>
<button class="pause" data-id="video2">Pause</button>




Red background means "playing"... 
<i>(try clicking either "native" or "custom" controls, to see that both work as expected)</i>

/* Grabbing objects to play with */
var playButtons = $('.play'),
    pauseButtons = $('.pause');

/* Helper function to send a message to Vimeo-iframe */
function vimeoPost(action, value, target) {
	var data = { method: action };
	if (value) {
		data.value = value;
	}
	target.contentWindow.postMessage(JSON.stringify(data), '*');
};

/* When clicking the playButton, send a "play"-message to given iframe*/
playButtons.click(function() {
  var iframe = document.getElementById(this.dataset.id);
  vimeoPost('play',null,iframe);
});

/* When clicking the pauseButton, send a "pause"-message to given iframe */
pauseButtons.click(function() {
  var iframe = document.getElementById(this.dataset.id);
  vimeoPost('pause',null,iframe);
});

/* When a message is received, deal with it */
window.addEventListener('message', function(event) {
  /* Get message and sender from the event */
  var message = JSON.parse(event.data);
  var sender = document.getElementById(message.player_id);
 
  /* If the message.event is "ready", then send a message to add eventlisteners for play and pause also */
  if(message.event == "ready") {
 	vimeoPost('addEventListener','play',sender);
   vimeoPost('addEventListener','pause',sender);
  }
  
  /* Because of the above, we will start receiving events when video is played or paused - we will toggle a class, just to show it visually */ 
  if(message.event == 'play') {
		sender.classList.add('playing');    
  }
  if(message.event == 'pause') {
    sender.classList.remove('playing');
  }
  
}, false);

YouTube Vimeo

Best way to filter featured image text

add_filter( 'admin_post_thumbnail_html', 'add_featured_image_instruction');
function add_featured_image_instruction( $content ) {
	global $post;
	if($post->post_type == 'stores' || $post->post_type == 'dining'){
    	return $content .= '<p>Recommended Size: <b>365px * 246px</b></p>';
	}
	if($post->post_type == 'whats'){
    	return $content .= '<p>Recommended Size: <b>340px * 280px</b></p>';
	}
	return $content;
}

Onscroll animations jquery

Below code to we can set animation son scroll nested time

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.1/animate.min.css">
<style>
.revealOnScroll{opacity:0;}
</style>

For jQuery used below function


<script src="//ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.js"></script>

<script>
//Update this function call with your own element ID, animate.css animation, and timeout in milliseconds. Each animated element requires its on function call.
//Supported animations are 'fadeInUp' 'flipInX' 'lightSpeedIn' 'bounceIn' 'slideInLeft' 'slideInRight' 'fadeInLeft' 'fadeInRight'. Other animations must be added on line 41 if used.
addAnimationData('#lp-pom-image-126','bounceIn','1000');
//addAnimationData('#your-next-element','bounceIn','2000');

function addAnimationData(elem, elemData, elemTimeout) {
$(elem).addClass("revealOnScroll").attr("data-animation",elemData).attr("data-timeout",elemTimeout);
}
$(function() {
var $window = $(window),
win_height_padded = $window.height() * 1.1,
isTouch = Modernizr.touch;
if (isTouch) { $('.revealOnScroll').addClass('animated'); }
$window.on('scroll', revealOnScroll);
function revealOnScroll() {
var scrolled = $window.scrollTop(),
win_height_padded = $window.height() * 1.1;
// Showed...
$(".revealOnScroll:not(.animated)").each(function () {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded > offsetTop) {
if ($this.data('timeout')) {
window.setTimeout(function(){
$this.addClass('animated ' + $this.data('animation'));
}, parseInt($this.data('timeout'),10));
} else {
$this.addClass('animated ' + $this.data('animation'));
}
}
});
// Hidden...
$(".revealOnScroll.animated").each(function (index) {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded < offsetTop) {
//add additional animate.css animations to the removeClass function
$(this).removeClass('animated fadeInUp flipInX lightSpeedIn bounceIn slideInLeft slideInRight fadeInLeft fadeInRight')
}
});
}
revealOnScroll();
});
//Original script created by Benoît Boucart: http://blog.webbb.be/
/**
* Do not remove this section; it allows our team to troubleshoot and track feature adoption.
* TS:0002-03-037
*/
</script>

Refrence

WordPress custom taxonomy custom hierarchical

Custom taxonomy hierarchical with ul li list and checkbox and radio button.


function get_product_taxonomie($taxonomies = 'product_category', $input_type = 'radio', $input_class = 'categoryCheck') {function get_product_taxonomie($taxonomies = 'product_category', $input_type = 'radio', $input_class = 'categoryCheck') { $selected_term = ''; $selected_term_open = ''; if($taxonomies == 'product_category'){ $selected_term = get_query_var('cats'); $selected_term_open = get_query_var('cats'); if(empty($selected_term)){ $selected_term = get_queried_object()->term_id; $selected_term_open = get_queried_object()->term_id; } } else if($taxonomies == 'product_brand'){ $selected_term = get_query_var('brands'); $selected_term_open = get_query_var('brands'); if(empty($selected_term)){ $selected_term = get_queried_object()->term_id; $selected_term_open = get_queried_object()->term_id; } } $selected_term = explode(',', $selected_term); $args = array( 'orderby'           => 'name',  'order'             => 'ASC', 'hide_empty'        => false,  'fields'            => 'all', 'parent'            => 0, 'hierarchical'      => true, 'child_of'          => 0, 'pad_counts'        => false, 'cache_domain'      => 'core' ); $terms = get_terms($taxonomies, $args); $return .= '<ul class="'.$taxonomies.'">';    foreach ( $terms as $term ) { $subterms = get_terms($taxonomies, array( 'parent'   => $term->term_id, 'hide_empty' => false )); $has_sub = ""; if( is_array($subterms) && !empty($subterms) ){ $has_sub = " has-children"; if(in_array_r($subterms, 'term_id', $selected_term_open)){ $has_sub .= " open"; } } $checked = ''; if(in_array($term->term_id, $selected_term)){ $checked = 'checked'; } // return terms (working) $return .= sprintf( '<li id="category-%1$s" class="toggle%6$s"><label><input type="%3$s" value="%1$s" name="%4$s" class="%5$s" %7$s><span>%2$s</span></label>', $term->term_id, $term->name, $input_type, $term->taxonomy, $input_class, $has_sub, $checked #7 ); if( is_array($subterms) && !empty($subterms) )        $return .= '<ul class="children">';
foreach ( $subterms as $subterm ) { $checked = ''; if(in_array($subterm->term_id, $selected_term)){ $checked = 'checked'; } $return .= sprintf( '<li id="category-%1$s" class="toggle"><label><input type="%3$s" value="%1$s" name="%4$s" class="%5$s" %6$s><span>%2$s</span></label>', $subterm->term_id, $subterm->name, $input_type, $term->taxonomy, $input_class, $checked # 6 ); $return .= '</li>'; //end subterms li } if( is_array($subterms) && !empty($subterms) )        $return .= '</ul>'; //end subterms ul $return .= '</li>'; //end terms li } //end foreach term $return .= '</ul>'; return $return;}
/** add current page active class */function in_array_r($array, $key, $val) {    foreach ($array as $item){ if (isset($item->$key) && $item->$key == $val){ return true; } } return false;}

WordPress search Post(news) with ajax

js code


/* All filter news and pagination*/
jQuery('.news-filter .categoryCheck').on( 'change' , function() {
if(!jQuery(this).val()){
jQuery('.news-filter .categoryCheck').prop( "checked", false );
}
load_news_list(0,1);
});

jQuery('.search-btn').on( 'click' , function() {
load_news_list(0,1);
});
jQuery('#srch_keyword').on('keypress', function(e){
if(e.keyCode == '13'){
e.preventDefault();
load_news_list(0,1);
}
});
jQuery('.pagination').on( 'click', '.page-numbers', function( event ) {
event.preventDefault();
page = find_page_number(jQuery(this));
var post_length = jQuery( '.news-div' ).length;
load_news_list( post_length, page);
});

&nbsp;

/* load news list */
function load_news_list(post_length, page) {

var news_cats = jQuery('.categoryCheck:checked').map(function() {return this.value;}).get().join(',');
var year = ( jQuery( '#year' ).length > 0 ) ? jQuery( '#year' ).val() : '';
var monthnum = ( jQuery( '#monthnum' ).length > 0 ) ? jQuery( '#monthnum' ).val() : '';
var search_val = jQuery('#srch_keyword').val();
// jQuery( '.clear-all' ).css( 'display' , 'none' );
if( news_cats.length > 0 ) {
jQuery( '.clear-all' ).css( 'display' , 'inline-block' );
}

jQuery.ajax({
type: "POST",
url: adminurl,
data: { action : 'load_news', news_cats: news_cats, post_length : post_length, year: year, monthnum: monthnum ,search:search_val, page: page},
success: function (result){
var responseData = JSON.parse(result);
jQuery( '.load-more-news' ).remove();
jQuery( '.news-listing' ).empty();
jQuery( '.news-listing' ).append(responseData.news);
jQuery( '.pagination' ).empty()
jQuery( '.pagination' ).append(responseData.pagination);
},
error:function(){
alert("Error: There is some issue please try again.");
},
beforeSend:function(){
jQuery( '.load-result' ).css( 'display' , 'block' );
},
complete: function () {
jQuery( '.load-result' ).css( 'display' , 'none' );
}
});
}

&nbsp;

WordPress code


add_action( 'wp_ajax_nopriv_load_news', 'load_news' );
add_action( 'wp_ajax_load_news', 'load_news' );
function load_news() {
$per_page = 12;
$paged = ( isset($_POST['page']) ) ? $_POST['page'] : 1 ;
$offset = (( $paged - 1 ) * $per_page);
/* if( !empty( $_POST['post_length'] ) ) { */
$post_length = $_POST['post_length'];
//$offset = $post_length;
$nextOffset = $offset + $per_page;
/* } */
$result = '';

$pagination = '';
$newsList = getNewsArray( $offset , $per_page , $_POST );

$result = '<div class="col-sm-12"><header class="page-header">';
$result .= '<h2 class="page-title">Sorry, it seems that we didn&rsquo;t find any results</h2>';
$result .= '</header>';
$result .= '<div class="page-content">';
$result .= '<p>Please try the search function at the top of the page to see if you can find what you&rsquo;re looking for</p>';
$result .= '</div></div>';
if ( $newsList->have_posts() ) {
$result = '';
while ( $newsList->have_posts() ) { $newsList->the_post();
$result .= post_html( $post->ID );
}
}

if($newsList->max_num_pages > 0){
$big = 999999999;
$pagination = paginate_links( array(
'type' => 'plain',
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, $paged ),
'total' => $newsList->max_num_pages,
'prev_next' => true,
'prev_text' => 'Prev',
'next_text' => 'Next',
) );
//$pagination .= football_pagination($newsList->max_num_pages);

} else {
$result .= '<div class="no-more-news"></div>';
}

$data['news'] = $result;
$data['pagination'] = $pagination;
echo json_encode( $data );

die();
}

&nbsp;
function getNewsArray( $offset , $per_page , $newsFilter ) {

$argsNews = array('post_type' => 'post', 'post_status'=> 'publish' , 'posts_per_page' => $per_page , 'offset' => $offset, 'order' => 'desc', 'orderby' => 'date' );

if( !empty($newsFilter['news_cats']) ) {
$cats = explode( ',' , $newsFilter['news_cats'] );
$argsNews['category__in'] = $cats;
}
if(!empty($newsFilter['year'])){
$argsNews['year'] = $newsFilter['year'];
}
if(!empty($newsFilter['monthnum'])){
$argsNews['monthnum'] = $newsFilter['monthnum'];
}
if(!empty($newsFilter['search'])){
$argsNews['s'] = $newsFilter['search'];
}
$newsList = new WP_Query( $argsNews );

return $newsList;
}

 

 

WordPress pagination with custom MySQL query

Simple pagination with custom query


$per_page = 50; # Set per page
$paged = ( get_query_var('paged') != 0 ) ? get_query_var('paged') : 1 ; ## get paged number
$offset = (( $paged - 1 ) * $per_page); ## set offset

$trial_list = football_trial_list(null, $offset, $per_page);

$trial_total = football_trial_list(null,0,-1);
$total = count($trial_total);

$max_num_pages = ceil( $total / $per_page );

$pagination = football_pagination($max_num_pages);

function football_trial_list($post_id = null, $offset = 0, $per_page = 3, $request = null){
global $wpdb;
$user_id = get_current_user_id();
$table_team = $wpdb->prefix . 'trial';

$distance = "";
if(isset($request) && !empty($request)){
if(isset($request['post_code']) && !empty($request['post_code'])){

$address_data = football_get_latitude_longitude($request['post_code']);
$lat = $address_data['lat'];
$lng = $address_data['lng'];

$distance = ", ( 3959 * acos( cos( radians(".$lat.") ) * cos( radians( tr.lat ) ) * cos( radians( tr.lng ) - radians(".$lng.") ) + sin( radians(".$lat.") ) * sin( radians( tr.lat ) ) ) ) AS distance";
}
}

$query = "SELECT tr.*, p.post_title, p.post_content $distance FROM $table_team AS tr ";
$query .= " INNER JOIN ".$wpdb->prefix."posts AS p ON ( tr.post_id = p.ID ) ";
$query .= " WHERE p.post_type = 'trials' AND p.post_status = 'publish' ";

// if get single post data
if(!empty($post_id) && $post_id != null){
$query .= " AND p.ID = $post_id ";
}

if(isset($request) && !empty($request)){
// if(isset($request['post_code']) && !empty($request['post_code'])){
// $query .= " AND tr.postcode LIKE '%".$request['post_code']."%'";
// }

if(isset($request['trial_name']) && !empty($request['trial_name'])){
$query .= " AND p.post_title LIKE '%".$request['trial_name']."%'";
}
if(isset($request['trial_age']) && !empty($request['trial_age'])){
if($request['trial_age'] >= 35)
$query .= " AND tr.trial_age >= ".$request['trial_age']."";
else
$query .= " AND tr.trial_age <= ".$request['trial_age']."";
}

// if(!empty($request['post_code']) && !empty($request['distance_min']) && !empty($request['distance_max'])){
if(!empty($request['post_code'])){
$query .= " HAVING distance BETWEEN ".$request['distance_min']." AND ".$request['distance_max']." ";
}

// Upcoming Trials
if(isset($request['upcoming']) && $request['upcoming'] = true){
$query .= " AND tr.trial_date >= CURDATE()";
}
}
else{
$query .= " AND tr.user_id = $user_id ";
}

// Upcoming Trials
if(isset($request['upcoming']) && $request['upcoming'] = true)
$query .= " ORDER BY tr.trial_date ASC ";
else
$query .= " ORDER BY p.post_date DESC ";

if($per_page != -1){
$query .= " LIMIT $offset, $per_page";
}

// echo $query; #die;
return $wpdb->get_results( $query, OBJECT );
}
// =============================================
// Default pagination
// =============================================
function football_pagination($max_num_pages){

if($max_num_pages > 1){
$big = 999999999;
$pagination = "<div class='toolbar'>";
$pagination .= paginate_links( array(
'type' => 'list',
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $max_num_pages,
'prev_next' => true,
'prev_text' => 'Prev',
'next_text' => 'Next',
) );
$pagination .= "</div>";

return $pagination;
}
else{
return '';
}
}