I added some custom fields (dates) in my admin columns. I try to make them sortable but in order to do that I need to convert them from string to date. My naive and simple code obviously doesn't work... Can someone point out my error(s) ?
add_action( 'pre_get_posts', 'orderby_date' );
function orderby_date( $query ) {
$orderby = $query->get( 'orderby');
if( 'start' == $orderby ) {
$query->set('meta_key','class_start');
$query->set('orderby',"STR_TO_DATE(meta_value,'%m/%d/%Y')");
}
}
This is what you are looking for:
add_filter( 'posts_clauses', 'manage_wp_posts_be_qe_posts_clauses', 1, 2 );
function manage_wp_posts_be_qe_posts_clauses( $pieces, $query ) {
global $wpdb;
if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) {
$order = strtoupper( $query->get( 'order' ) );
if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) )
$order = 'ASC';
switch( $orderby ) {
case 'class_start':
$pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'class_start'";
$pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%m/%d/%Y' ) $order, " . $pieces[ 'orderby' ];
break;
}
}
return $pieces;
}
You can read more about it here: http://wpdreamer.com/2014/04/how-to-make-your-wordpress-admin-columns-sortable/
Related
Using "Reorder and customize product dimensions formatted output in WooCommerce" answer code il would like to make the output display as:
Size: D40 x W45 x H60 (cm)
Any help is appreciated.
Just add the follows code snippet in your active theme's functions.php to achieve the above -
function woocommerce_display_product_attributes( $product_attributes, $product ){
if( !isset( $product_attributes['dimensions'] ) ) return $product_attributes;
$modified_dimensions = array();
foreach ( $product->get_dimensions( false ) as $key => $value ) {
if( $key == 'length' )
$modified_dimensions[$key] = 'D'.$value;
if( $key == 'width' )
$modified_dimensions[$key] = 'W'.$value;
if( $key == 'height' )
$modified_dimensions[$key] = 'H'.$value;
}
$dimension_string = implode( ' × ', array_filter( array_map( 'wc_format_localized_decimal', $modified_dimensions ) ) );
if ( ! empty( $dimension_string ) ) {
$dimension_string .= ' (' . get_option( 'woocommerce_dimension_unit' ) . ')';
} else {
$dimension_string = __( 'N/A', 'woocommerce' );
}
// change dimensions label & value.
$product_attributes['dimensions']['label'] = __( 'Size', 'text-domain' );
$product_attributes['dimensions']['value'] = $dimension_string;
return $product_attributes;
}
add_filter( 'woocommerce_display_product_attributes', 'woocommerce_display_product_attributes', 99, 2 );
Welcome to StackOverflow!
Try a simpler code (tested):
add_filter( 'woocommerce_format_dimensions', 'custom_formated_product_dimentions', 10, 2 );
function custom_formated_product_dimentions( $dimension_string, $dimensions ){
if ( empty( $dimension_string ) )
return __( 'N/A', 'woocommerce' );
$dimensions = array_filter( array_map( 'wc_format_localized_decimal', $dimensions ) );
return 'D'.$dimensions['length'].' x W'.$dimensions['width'].' x H'.$dimensions['height'].' ('.get_option( 'woocommerce_dimension_unit' ).')';
}
I'm trying to fetch bookings based on time availability in wocommerce bookings by passing the time selection in below format:
2019-08-26 08:00 - 2019-08-26 11:00
$available_blocks = $booking_form->product->get_available_blocks( array(
'blocks' => $blocks_in_range,
'from' => $from,
'to' => $to));
foreach ( $available_blocks as $check ) {
if ( true === $booking_form->product->check_availability_rules_against_date( $check, '' )){
//Custom Added to fetch only blocks in selected range
if( $from >= reset($available_blocks) && $to <= end($available_blocks)){
$matches[] = $post_id;
break; // check passed
}
}
}
But, it's only working when I pass time in Hour only format(10:00 AM), When I add minute(10:30 AM) it is not returning any available bookings.
Full function for reference.
/**
* Get all available booking products
*
* #param string $start_date_raw YYYY-MM-DD format
* #param string $end_date_raw YYYY-MM-DD format
* #param int $quantity Number of people to book
* #param string $behavior Whether to return exact matches
* #return array Available post IDs
*/
function get_available_bookings( $start_date_raw, $end_date_raw, $quantity = 1, $behavior = 'default' ) {
$matches = array();
// Separate dates from times
$start_date = explode( ' ', $start_date_raw );
$end_date = explode( ' ', $end_date_raw );
// If time wasn't passed, define defaults.
if ( ! isset( $start_date[1] ) ) {
$start_date[1] = '00:00';
}
$start = explode( '-', $start_date[0] );
$args = array(
'wc_bookings_field_resource' => 0,
'wc_bookings_field_persons' => $quantity,
'wc_bookings_field_duration' => 1,
'wc_bookings_field_start_date_year' => $start[0],
'wc_bookings_field_start_date_month' => $start[1],
'wc_bookings_field_start_date_day' => $start[2],
);
// Loop through all posts
foreach ( $this->product_ids as $post_id ) {
if ( 'product' == get_post_type( $post_id ) ) {
$product = wc_get_product( $post_id );
if ( is_wc_booking_product( $product ) ) {
// Grab the duration unit
$unit = $product->is_type( 'accommodation-booking' ) ? 'night' : $product->get_duration_unit();
// Support time
if ( in_array( $unit, array( 'minute', 'hour' ) ) ) {
if ( ! empty( $start_date[1] ) ) {
$args['wc_bookings_field_start_date_time'] = $start_date[1];
}
}
if ( 'exact' === $behavior ) {
$duration = $this->calculate_duration( $start_date_raw, $end_date_raw, $product->get_duration(), $unit );
$args['wc_bookings_field_duration'] = $duration;
}
$booking_form = new WC_Booking_Form( $product );
$posted_data = $booking_form->get_posted_data( $args );
// All slots are available (exact match)
if ( true === $booking_form->is_bookable( $posted_data ) ) {
$matches[] = $post_id;
}
// Any slot between the given dates are available
elseif ( 'exact' !== $behavior ) {
$from = strtotime( $start_date_raw );
$to = strtotime( $end_date_raw );
$blocks_in_range = $booking_form->product->get_blocks_in_range( $from, $to );
// Arguments changed in WC Bookings 1.11.1
$available_blocks = $booking_form->product->get_available_blocks( array(
'blocks' => $blocks_in_range,
'from' => $from,
'to' => $to
) );
foreach ( $available_blocks as $check ) {
if ( true === $booking_form->product->check_availability_rules_against_date( $check, '' )){
$matches[] = $post_id;
break; // check passed
}
}
}
}
}
}
return $matches;
}
Im tryng to mod this function to make an update more powerful.
What im tryng to do is to mod this function:
add_action( 'wp_loaded', 'cron_revise_changed_listings' );
function cron_revise_changed_listings() {
global $wpdb;
if ( !isset( $_REQUEST['wplister_revise_all'] ) ) {
return;
}
$limit = isset( $_REQUEST['revise_limit'] ) ? intval( $_REQUEST['revise_limit'] ) : 10;
$listings = $wpdb->get_results("
SELECT id, account_id
FROM {$wpdb->prefix}ebay_auctions
WHERE status = 'changed'
ORDER BY id DESC
LIMIT {$limit}", ARRAY_A );
if ( empty( $listings ) ) {
die( json_encode( array( 'revised' => 0 ) ) );
}
$lm = new ListingsModel();
$revised = 0;
$last_account_id = false;
foreach ( $listings as $listing ) {
if ( $last_account_id != $listing['account_id'] ) {
$last_account_id = $listing['account_id'];
WPLE()->initEC( $listing['account_id'] );
}
$lm->reviseItem( $listing['id'], WPLE()->EC->session );
$revised++;
}
WPLE()->EC->closeEbay();
die( json_encode( array( 'revised' => $revised ) ) );
}
What i need to obtain is to repeat cycle for each, but with a step of 10 items per time so for revise 100 items it need only to do 10 cicles and not 100...someone have any ideas?
How to limit query to 6 in woocommerce product price filter short-code [products_by_price min="100" max="300"]? The code below is based on woocommerce product short-code which unfortunately does not support per_page. In this case I need to limit query to 6 to avoid showing all products.
add_shortcode( 'wc_products_price_range', 'wc_products_price_range' );
function wc_products_price_range( $atts, $content, $shortcode ) {
if ( class_exists( 'WooCommerce' ) ) {
$shortcodes = new WC_Shortcodes();
if ( is_array( $atts ) ) {
$min = (int) $atts['min'];
$max = (int) $atts['max'];
if ( $min && $max ) {
$and = "meta_value BETWEEN $min AND $max";
} else {
if ( $min ) {
$and = "meta_value >= $min";
} elseif ( $max ) {
$and = "meta_value <= $max";
}
}
if ( $and ) {
global $wpdb;
$query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_price' AND $and";
$ids = $wpdb->get_col( $query );
if ( ! empty( $ids ) ) {
$atts['ids'] = implode( ",", $ids );
}
}
}
return $shortcodes->products( $atts );
}
}
After a quick scan of WC shortcode class I have came across this :
public static function products( $atts ) {
$atts = shortcode_atts( array(
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'ids' => '',
'skus' => ''
), $atts );
it means you can pass 'column' attribute along with ids where you can limit posts per page.
and in this query :
$query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_price' AND $and";
you can use limit 0,6 with order by clause.
Hope this helps.
OR
random rows:
SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;
or you can pass 'rand' to attributes in shortcode.
Can someone tell me what wrong with this query.
if ( isset( $_GET['lokacija'] ) && !empty( $_GET['lokacija'] ) ) {
$lokacija = $_GET['lokacija'];
} else { $lokacija = ''; }
if ( isset( $_GET['tip'] ) && !empty( $_GET['tip'] ) ) {
$tip = $_GET['tip'];
} else { $tip = ''; }
if ( isset( $_GET['sobe'] ) && !empty( $_GET['sobe'] ) ) {
$sobe = $_GET['sobe'];
} else { $sobe = ''; }
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args2 = array(
'posts_per_page' => 10,
'post_type' => 'nekretnine',
'paged' => $paged,
if ($lokacija != '') {
'meta_query' => array(
array (
'key' => 'lokacija',
'value' => $lokacija.''
),
)
}
);
$wp_query = new WP_Query( $args2 );
This code gives me error
Parse error: syntax error, unexpected T_IF, expecting ')' in
*/wp-content/themes/gs/page-nek-pretraga.php on line 23;
Line 23 is line that starts with if ($lokacija)...
What i want to do is to use multiple meta_query that i can get from php get (www.blabla./com/page1/?lokacija=foo&tip=foo&sobe=3)
But, i want it only if lets say $lokacija is not empty. Same for other two (possible 5-6 later) fields.
You can not include if condition in array. Whatever you are trying to achieve with above code is you can achieve with this following code.
$args2 = array(
'posts_per_page' => 10,
'post_type' => 'nekretnine',
'paged' => $paged,
);
if ($lokacija != '') {
$args2['meta_query'] = array(
array (
'key' => 'lokacija',
'value' => $lokacija.''
),
);
}
To check for multiple custom fields we have to join the meta table twice.
So the copy of the table is joined with a different temporary table name.
global $wpdb; $query = " SELECT * FROM {$wpdb--->prefix}posts
INNER JOIN {$wpdb->prefix}postmeta m1
ON ( {$wpdb->prefix}posts.ID = m1.post_id )
INNER JOIN {$wpdb->prefix}postmeta m2
ON ( {$wpdb->prefix}posts.ID = m2.post_id )
WHERE
{$wpdb->prefix}posts.post_type = 'post'
AND {$wpdb->prefix}posts.post_status = 'publish'
AND ( m1.meta_key = 'date' AND m1.meta_value > '2010-12-05 00:00:00' )
AND ( m1.meta_key = 'date' AND m1.meta_value < '2010-12-12 00:00:00' ) AND ( m2.meta_key = 'some_other_meta_value' AND m2.meta_value != '' ) GROUP BY {$wpdb->prefix}posts.ID
ORDER BY {$wpdb->prefix}posts.post_date
DESC;
For More Details Visit : http://realtuts.com/write-custom-wordpress-sql-query-multiple-meta-values/
";