• i have been looking through the web for a while and i’ve got no where more than where i already am.

    i have a ‘directory’ post type with a custom archive page setup to display my directories posts.

    each post has a latitude and longitude meta data.

    in the custom archive, i have included a search form where you can search within a location.

    i would like to display the posts that are within 5 miles radius from the searched location.

    1- right now, i have an incomplete hack in place where it calculates the distance of each post as it loops, and then checks if distance is lower or equal to radius before it prints on screen:

    <?php $radius = 5;?>
    <?php $address = get_geocode(urlencode($_GET['address'])); ?>
    
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
        <?php $latLng = explode(',',str_replace(array('(',')'),'',get_geocode_latlng($post->ID)));?>
        <?php $distance = distance($address['lat'],$address['lng'],trim($latLng[0]), trim($latLng[1]));?>
        <?php if(($distance <= $radius) || count($address) == 0 ){?>
            <?php $thumbnail = wp_get_attachment_url( get_post_thumbnail_id(get_the_ID()));?>
            <div class="large-12 medium-12 small-12">
                <div class="directory" data-latitude="<?php echo trim($latLng[0]);?>" data-longitude="<?php echo trim($latLng[1]);?>">
                    <div class="row">
                        <div class="large-2 medium-2 small-12 columns">
                            <div class="image" href="<?php the_permalink();?>">
                                <img src="<?php echo $thumbnail;?>" alt="<?php the_title(); ?>"/>
                            </div>
                        </div>
                        <div class="large-10 medium-10 small-12 columns">
                            <h4><?php the_title(); ?></h4>
                            <p><?php echo get_the_excerpt();?> <a href="<?php the_permalink();?>">read more</a></p>
                        </div>
                    </div>
                </div>
            </div>
        <?php }?>
    <?php endwhile;?>
    
    <?php if (function_exists('joints_page_navi')) { ?>
        <?php joints_page_navi(); ?>
    <?php } ?>
    
    <?php else: ?>
        <p>There are currently no directories.</p>
    <?php endif; ?>

    the problem with this hack is that obviously it will have no effect to the WordPress global variables and therefore the pagination will not be correct. is there a way we can alter this.

    2- another hack would be same as above but instead of printing results straight to page, i would push all posts that meet the condition to an array which then i can loop through separately but i ideally i would want to replace the global variable array with this new array. is there away to do this.

    3- i know there is away for this to work as i have seen plugins like store finder that does a similar thing however i didn’t want to go the plugin route as i wanted to learn to build my own as i will be adding a lot more search by custom taxonomies after and also i couldn’t understand their implementation.
    i assumed that i may need to use an action like ‘pre_get_posts’ or similar to hook my array to it or alter the whole MySQL query.

    all my custom post types have their custom archive page and rely on wordpress default functionality to display things correctly. i am trying to get my problem fixed while keeping to this framework.

    any thoughts and advise is much appreciated.

Viewing 1 replies (of 1 total)
  • You can do this by using some filters to alter the WP query. Add these to your functions.php;

    // Filter functions to modify a query.
    function mam_posts_fields ($fields) {
       global $mam_global_fields;
       // Make sure there is a leading comma
       if ($mam_global_fields) $fields .= (preg_match('/^(\s+)?,/',$mam_global_fields)) ? $mam_global_fields : ", $mam_global_fields";
       return $fields;
    }
    function mam_posts_join ($join) {
       global $mam_global_join;
       if ($mam_global_join) $join .= " $mam_global_join";
       return $join;
    }
    function mam_posts_where ($where) {
       global $mam_global_where;
       if ($mam_global_where) $where .= " $mam_global_where";
       return $where;
    }
    function mam_posts_orderby ($orderby) {
       global $mam_global_orderby;
       if ($mam_global_orderby) $orderby = $mam_global_orderby;
       return $orderby;
    }
    add_filter('posts_fields','mam_posts_fields');
    add_filter('posts_join','mam_posts_join');
    add_filter('posts_where','mam_posts_where');
    add_filter('posts_orderby','mam_posts_orderby');

    In the code below, I am assuming that your Custom Field is stored in the format ‘(35.2500234,-85.31345789)’. If this is not correct, the code will need to be changed.

    I also assume that your $address is an array keyed on ‘lat’ and ‘lon’.

    Here is the code using the filters:

    <?php $address = get_geocode(urlencode($_GET['address'])); ?>
    
    <?php
    $post_type = 'post';    // Use your post type
    $meta_key = 'latlng';   // Use your meta_key
    $distance = 5;
    $address_lat = $address['lat'];
    $address_lon = $address['lon'];
    
    $mam_global_fields = ", (((acos(sin(($address_lat * pi()/180)) *
          sin((SUBSTRING(pm.meta_value,2,INSTR(pm.meta_value,',')-2) * pi()/180)) +
          cos(( $address_lat * pi()/180)) *
          cos((SUBSTRING(pm.meta_value,2,INSTR(pm.meta_value,',')-2) * pi()/180)) *
          cos((( $address_lon -
          SUBSTRING(pm.meta_value, INSTR(pm.meta_value,',')+1,
          LENGTH(pm.meta_value) - INSTR(pm.meta_value,',') - 1)) * pi()/180)))) *
          180/pi())*60*1.1515
            ) as distance";
    $mam_global_join = "JOIN $wpdb->postmeta pm ON ( $wpdb->posts.ID = pm.post_id AND pm.meta_key = '$meta_key' )";
    $mam_global_where = " HAVING distance > $distance";
    $args = array(
       'posts_per_page' => 5,
       'ignore_sticky_posts' => 1,
       'post_type' => $post_type,
    );
    $my_query = new WP_Query($args);
    $mam_global_fields = $mam_global_join = $mam_global_where = ''; // Clear filters
    
    if ( $my_query->have_posts() ) {
       while ( $my_query->have_posts() ) {
          $my_query->the_post();
          the_title();
          echo " - $post->distance <br />";
       }
    }
    ?>
Viewing 1 replies (of 1 total)
  • The topic ‘replace wp query results with custom result array’ is closed to new replies.