Php 按最近的地点订购产品

Php 按最近的地点订购产品,php,sql,wordpress,woocommerce,advanced-custom-fields,Php,Sql,Wordpress,Woocommerce,Advanced Custom Fields,我想在搜索表单中输入位置后按最近的位置订购产品。我使用来自ACF的谷歌地图为产品分配位置,该字段称为“地址”。我也有谷歌地方自动完成我的表格和ACF谷歌地图半径搜索插件。我的表单重定向到包含lat和lng变量的URL: /?s=&post_type=product&lat=43.267680799999&lng=6.6407108999991 插件应该从这个url订购产品。lat和lng在URL中传递良好。不幸的是,它不会改变搜索产品的顺序 以下是该插件的一些关键功能: // Join for

我想在搜索表单中输入位置后按最近的位置订购产品。我使用来自ACF的谷歌地图为产品分配位置,该字段称为“地址”。我也有谷歌地方自动完成我的表格和ACF谷歌地图半径搜索插件。我的表单重定向到包含lat和lng变量的URL:

/?s=&post_type=product&lat=43.267680799999&lng=6.6407108999991

插件应该从这个url订购产品。lat和lng在URL中传递良好。不幸的是,它不会改变搜索产品的顺序

以下是该插件的一些关键功能:

// Join for searching metadata
function acf_google_maps_search_join_to_WPQuery($join) {

    global $wpdb;

    $acf_gms = new acf_gms; 
    $table_name = $acf_gms->table_name();

    if ( 
        isset($_GET['lat']) && !empty($_GET['lat']) 
        && isset( $_GET['lng']) && !empty($_GET['lng']) 
         ) {

        $join .= " LEFT JOIN {$table_name} AS acf_gms_geo ON {$wpdb->posts}.ID = acf_gms_geo.post_id ";

    }

    return $join;

}
add_filter('posts_join', 'acf_google_maps_search_join_to_WPQuery');



// ORDER BY DISTANCE
function acf_google_maps_search_orderby_WPQuery($orderby) {


     if ( 
        isset($_GET['lat']) && !empty($_GET['lat']) 
        && isset( $_GET['lng']) && !empty($_GET['lng']) 
         ) {

        $lat = sanitize_text_field( $_GET['lat'] );
        $lng = sanitize_text_field( $_GET['lng'] );

        $orderby = " (POW((acf_gms_geo.lng-{$lng}),2) + POW((acf_gms_geo.lat-{$lat}),2)) ASC";

    }

    return $orderby;

}
add_filter('posts_orderby', 'acf_google_maps_search_orderby_WPQuery');
下面是传递到结果页的sql查询:

SELECT wp_posts.* 
FROM wp_posts 
INNER JOIN wp_postmeta 
    ON ( wp_posts.ID = wp_postmeta.post_id ) 
INNER JOIN wp_postmeta AS mt1 
    ON ( wp_posts.ID = mt1.post_id ) 
INNER JOIN wp_postmeta AS mt2 
    ON ( wp_posts.ID = mt2.post_id ) 
LEFT JOIN wp_acf_google_map_search_geodata AS acf_gms_geo 
    ON wp_posts.ID = acf_gms_geo.post_id 
WHERE 1=1 
    AND (   
            ( wp_postmeta.meta_key = ‘flash_sale_start’ 
                AND CAST(wp_postmeta.meta_value AS DATE) > ‘20180122’ 
            )
            AND ( mt1.meta_key = ‘flash_sale_end’ 
                AND CAST(mt1.meta_value AS DATE) > ‘20180122’ 
            )
            AND ( mt2.meta_key = ‘flash_sale_start’ 
                AND CAST(mt2.meta_value AS DATE) <= ‘20180127’ 
            )
        ) 
    AND wp_posts.post_type = ‘product’ 
    AND ((wp_posts.post_status = ‘publish’)) 
GROUP BY wp_posts.ID 
ORDER BY (POW((acf_gms_geo.lng-6.640710899999931),2) + POW((acf_gms_geo.lat-43.26768079999999),2)) ASC
选择wp_帖子。*
来自wp_的职位
内部连接wp_Posteta
打开(wp_posts.ID=wp_postta.post_ID)
内部连接wp_Posteta为mt1
打开(wp_posts.ID=mt1.post_ID)
内部连接wp_Posteta为mt2
打开(wp_posts.ID=mt2.post_ID)
左键加入wp_acf_google_map_search_geodata作为acf_gms_geo
在wp_posts.ID=acf_gms_geo.post_ID上
其中1=1
及(
(wp_postmeta.meta_key='flash_sale_start'
和铸造(wp_Posteta.meta_值为日期)>“20180122”
)
和(mt1.meta_key='flash_sale_end'
和铸造(mt1.meta_值截至日期)>“20180122”
)
和(mt2.meta_key='flash_sale_start'

和CAST(mt2.meta_value AS DATE)我发现了这个问题。我在functions.php中有两个meta_查询,根据两种不同的规则在页面的两个不同位置显示产品

插件触发的ORDER BY location(按位置排序)只出现在一个sql查询中,而不出现在这个sql查询中(尽管左侧的连接部分出现):

//下面你可以看到left join插件的一部分出现了

LEFT JOIN wp_acf_google_map_search_geodata AS acf_gms_geo ON wp_posts.ID = acf_gms_geo.post_id WHERE 1=1 AND wp_posts.ID NOT IN (968) AND (
    wp_posts.ID NOT IN (
    SELECT object_id
    FROM wp_term_relationships
    WHERE term_taxonomy_id IN (10)
    )
    ) AND (
    wp_postmeta.meta_key = ‘total_sales’
    AND
    (
    (
    ( mt1.meta_key = ‘flash_sale_start’ AND CAST(mt1.meta_value AS DATE) <= ‘20180125’ )
    AND
    ( mt2.meta_key = ‘flash_sale_end’ AND CAST(mt2.meta_value AS DATE) >= ‘20180125’ )
    )
    )
    ) AND wp_posts.post_type = ‘product’ AND (wp_posts.post_status = ‘publish’ OR wp_posts.post_status = ‘complete’ OR wp_posts.post_status = ‘paid’ OR wp_posts.post_status = ‘confirmed’ OR wp_posts.post_status = ‘unpaid’ OR wp_posts.post_status = ‘pending-confirmation’ OR wp_posts.post_status = ‘cancelled’ OR wp_posts.post_status = ‘private’) 
GROUP BY wp_posts.ID 

你知道如何更正吗?

我有一个元查询:

$today = current_time('Ymd');
 $args = array (
    'numberposts' => -1,
    'post_status'       => 'publish',
    'post_type'         => 'product',
    'meta_query' => array(
    'relation' => 'AND',
    'start_clause' => array(
        'key'=>'flash_sale_start',
        'value' => $today,
        'compare'=> '<=',
     'type' => 'DATE'
    ),
         'end_clause' => array(
         'key' => 'flash_sale_end',
     'value' => $today,
         'compare' => '>=',
     'type' => 'DATE'
)

       )
);
return $args;
}

// The main shop and archives meta query
add_filter( 'woocommerce_product_query_meta_query', 'custom_product_query_meta_query', 10, 2 );
function custom_product_query_meta_query( $meta_query, $query ) {
    if( ! is_admin() ) 
        return custom_meta_query( $meta_query );
}
我还有一个元查询:

$products = new WP_Query( array (
            'post_type'         => 'product',
            'post_status'       => 'publish',
            'posts_per_page'    => $atts['limit'],
            'meta_query'        => array(
                'relation'      => 'AND',
                'start_clause'  => array(
                    'key'       =>'flash_sale_start',
                    'value'     => $today,
                    'compare'   => '>',
                    'type'      => 'DATE'
                ),
                'end_clause'    => array(
                    'key'       => 'flash_sale_end',
                    'value'     => $today,
                    'compare'   => '>',
                    'type'      => 'DATE'
                ),
        'limit_clause'    => array(
                    'key'       => 'flash_sale_start',
                    'value'     => $limitdate,
                    'compare'   => '<=',
                    'type'      => 'DATE'
                )
)

        ));
}

        ob_start();

        if ( $products->have_posts() ) { ?>

            <?php woocommerce_product_loop_start(); ?>

                <?php while ( $products->have_posts() ) : $products->the_post(); ?>

                    <?php wc_get_template_part( 'content', 'product' ); ?>

                <?php endwhile; // end of the loop. ?>

            <?php woocommerce_product_loop_end(); ?>

            <?php
        } else {
            do_action( "woocommerce_shortcode_products_loop_no_results", $atts );
            echo "<p>Aucune vente &#224; venir pour le moment.</p>";
        }

        woocommerce_reset_loop();
        wp_reset_postdata();

        return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
    }

    add_shortcode( 'upcoming_sales', 'upcoming_sales' );

你知道为什么插件不能在第一个sql查询中执行orderby吗?

我成功地让它工作了!!因为woocommerce有自己的东西来订购产品,所以只需要编写如下函数:

if(isset($_GET['lat']) and $_GET['lat'] != "" and isset($_GET['lng']) and $_GET['lng'] != "")
    {
    add_filter( 'woocommerce_default_catalog_orderby', 'custom_woocommerce_get_catalog_ordering_args' 

    );
    }
    function custom_woocommerce_get_catalog_ordering_args( $args ) {

    $lat = sanitize_text_field( $_GET['lat'] );
    $lng = sanitize_text_field( $_GET['lng'] );

            $args['orderby'] = ' (POW((acf_gms_geo.lng-{$lng}),2) + POW((acf_gms_geo.lat-

    {$lat}),2))';
            $args['order'] = 'ASC';
            $args['meta_key'] = '';

        return $args;
    }
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts 
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) 
INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) 
INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id )
LEFT JOIN wp_acf_google_map_search_geodata AS acf_gms_geo ON wp_posts.ID = acf_gms_geo.post_id WHERE 1=1 AND wp_posts.ID NOT IN (968) AND (
    wp_posts.ID NOT IN (
    SELECT object_id
    FROM wp_term_relationships
    WHERE term_taxonomy_id IN (10)
    )
    ) AND (
    wp_postmeta.meta_key = ‘total_sales’
    AND
    (
    (
    ( mt1.meta_key = ‘flash_sale_start’ AND CAST(mt1.meta_value AS DATE) &lt;= ‘20180125’ )
    AND
    ( mt2.meta_key = ‘flash_sale_end’ AND CAST(mt2.meta_value AS DATE) &gt;= ‘20180125’ )
    )
    )
    ) AND wp_posts.post_type = ‘product’ AND (wp_posts.post_status = ‘publish’ OR wp_posts.post_status = ‘complete’ OR wp_posts.post_status = ‘paid’ OR wp_posts.post_status = ‘confirmed’ OR wp_posts.post_status = ‘unpaid’ OR wp_posts.post_status = ‘pending-confirmation’ OR wp_posts.post_status = ‘cancelled’ OR wp_posts.post_status = ‘private’) 
GROUP BY wp_posts.ID 
ORDER BY wp_postmeta.meta_value+0 DESC, wp_posts.post_date DESC LIMIT 0, 100
$products = new WP_Query( array (
            'post_type'         => 'product',
            'post_status'       => 'publish',
            'posts_per_page'    => $atts['limit'],
            'meta_query'        => array(
                'relation'      => 'AND',
                'start_clause'  => array(
                    'key'       =>'flash_sale_start',
                    'value'     => $today,
                    'compare'   => '>',
                    'type'      => 'DATE'
                ),
                'end_clause'    => array(
                    'key'       => 'flash_sale_end',
                    'value'     => $today,
                    'compare'   => '>',
                    'type'      => 'DATE'
                ),
        'limit_clause'    => array(
                    'key'       => 'flash_sale_start',
                    'value'     => $limitdate,
                    'compare'   => '<=',
                    'type'      => 'DATE'
                )
)

        ));
}

        ob_start();

        if ( $products->have_posts() ) { ?>

            <?php woocommerce_product_loop_start(); ?>

                <?php while ( $products->have_posts() ) : $products->the_post(); ?>

                    <?php wc_get_template_part( 'content', 'product' ); ?>

                <?php endwhile; // end of the loop. ?>

            <?php woocommerce_product_loop_end(); ?>

            <?php
        } else {
            do_action( "woocommerce_shortcode_products_loop_no_results", $atts );
            echo "<p>Aucune vente &#224; venir pour le moment.</p>";
        }

        woocommerce_reset_loop();
        wp_reset_postdata();

        return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
    }

    add_shortcode( 'upcoming_sales', 'upcoming_sales' );
SELECT wp_posts.* 
FROM wp_posts 
INNER JOIN wp_postmeta 
    ON ( wp_posts.ID = wp_postmeta.post_id ) 
INNER JOIN wp_postmeta AS mt1 
    ON ( wp_posts.ID = mt1.post_id ) 
INNER JOIN wp_postmeta AS mt2 
    ON ( wp_posts.ID = mt2.post_id ) 
LEFT JOIN wp_acf_google_map_search_geodata AS acf_gms_geo 
    ON wp_posts.ID = acf_gms_geo.post_id 
WHERE 1=1 
    AND (   
            ( wp_postmeta.meta_key = ‘flash_sale_start’ 
                AND CAST(wp_postmeta.meta_value AS DATE) &gt; ‘20180122’ 
            )
            AND ( mt1.meta_key = ‘flash_sale_end’ 
                AND CAST(mt1.meta_value AS DATE) &gt; ‘20180122’ 
            )
            AND ( mt2.meta_key = ‘flash_sale_start’ 
                AND CAST(mt2.meta_value AS DATE) &lt;= ‘20180127’ 
            )
        ) 
    AND wp_posts.post_type = ‘product’ 
    AND ((wp_posts.post_status = ‘publish’)) 
GROUP BY wp_posts.ID 
ORDER BY (POW((acf_gms_geo.lng-6.640710899999931),2) + POW((acf_gms_geo.lat-43.26768079999999),2)) ASC
if(isset($_GET['lat']) and $_GET['lat'] != "" and isset($_GET['lng']) and $_GET['lng'] != "")
    {
    add_filter( 'woocommerce_default_catalog_orderby', 'custom_woocommerce_get_catalog_ordering_args' 

    );
    }
    function custom_woocommerce_get_catalog_ordering_args( $args ) {

    $lat = sanitize_text_field( $_GET['lat'] );
    $lng = sanitize_text_field( $_GET['lng'] );

            $args['orderby'] = ' (POW((acf_gms_geo.lng-{$lng}),2) + POW((acf_gms_geo.lat-

    {$lat}),2))';
            $args['order'] = 'ASC';
            $args['meta_key'] = '';

        return $args;
    }