I have a custom search form that ends up on a page-template.php which then performs two WP_Query's. This is for a real estate where each property CPT has a long / lat value set via ACF. The code is partially based on https://pagecrafter.com/radial-search-results-page-wordpress-tutorial/. The issue I am having is with pagination. I've not yet tried adding a reqrite rule so wordpress understands pagination on this page-template
The first query
Gets property IDs that are within a search radius and does some meta query filtering based on the passed search parameters. It outputs an array pf property IDs that are sorted by distance from the searched postcode.
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$proximity = (int)get_query_var( 'radius' );
$zip2 = normalise( htmlspecialchars( get_query_var( 'q' ) ) );
$bedrooms = (int)get_query_var( 'beds' );
$property_type = get_query_var( 'property_type' );
$price_min = get_query_var( 'min' );
$price_max = get_query_var( 'max' );
$sale_sstc = get_query_var( 'sstc' );
$sale_uo = get_query_var( 'uo' );
if ( splitpostcode( $zip2 ) == FALSE ) {
echo 'Not a postcode, do something else';
} else {
$args = array();
$args['post_type'] = 'properties';
$args['post_status'] = 'publish';
$args['posts_per_page'] = -1;
$args['paged'] = $paged;
//$meta_query = array();
$meta_query = array( 'relation' => 'AND' );
if( isset($property_type) ) {
$meta_query[] = array(
'key' => 'type',
'value' => $property_type,
'compare' => '='
);
}
if( isset($bedrooms) ) {
$meta_query[] = array(
'key' => 'bedrooms',
'value' => intval($bedrooms),
'compare' => '>='
);
}
if( isset($price_min) ) {
$meta_query[] = array(
'key' => 'price',
'value' => intval($price_min),
'compare' => '>='
);
}
if( isset($price_max) ) {
$meta_query[] = array(
'key' => 'price',
'value' => intval($price_max),
'compare' => '<='
);
}
$property_status[] = 'Available';
if( isset($sale_sstc) ) {
$property_status[] = 'Sold Subject to Contract';
}
if( isset($sale_uo) ) {
$property_status[] = 'Under Offer';
}
//print_r($property_status);
$meta_query[] = array(
'key' => 'status',
'value' => $property_status,
'compare' => 'IN'
);
if(!empty($meta_query)) {
$args['meta_query'] = $meta_query;
}
//print_r($args);
$get_locations = new WP_Query( $args );
$results = array();
if ( $get_locations->have_posts() ) {
while ( $get_locations->have_posts() ) {
$get_locations->the_post();
$next_lat = getlntsql($zip2);
$zip1 = get_field( 'postcode' );
$lat1 = (float)get_field('latitude' );
$lon1 = (float)get_field('longitude' );
$postid = get_the_ID();
$lat2 = (float)$next_lat[0]->latitude;
$lon2 = (float)$next_lat[0]->longitude;
$theta = $lon1-$lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
if ( $miles < $proximity ) {
//$data[$key] = $value;
//array_push($results, $postid);
$results[$postid] = $miles;
}
} } else { echo 'none!'; }
wp_reset_postdata();
asort( $results, SORT_NUMERIC );
var_dump( $results );
}
The second query
Grabs the properties in the $results array for display
<!-- Listings -->
<div class="listings-container grid-layout-three">
<?php
wp_reset_query();
$args2 = array(
'post_type' => 'properties',
'post__in' => array_keys($results),
'posts_per_page' => get_option('posts_per_page'),
//'offset' => ($paged -1) * 9,
//'paged' => $paged,
'orderby' => 'post__in',
'order' => 'ASC',
);
$the_query2 = new WP_Query( $args2 );
// The Loop
if ( $the_query2->have_posts() ) {
while ( $the_query2->have_posts() ) {
$the_query2->the_post(); ?>
<!-- Listing Item -->
<div class="listing-item">
<a href="<?php echo esc_url( get_permalink() ); ?>" class="listing-img-container">
<div class="listing-badges">
<span><?php the_field( 'status' ); ?></span>
</div>
<div class="listing-img-content">
<span class="listing-price">£ <?php echo number_format( get_field( 'price' ) ); ?><i><?php if ( get_field( 'bedrooms' ) !== '0' ) { $bedrooms = sprintf( ngettext("%d Bedroom", "%d Bedrooms", get_field( 'bedrooms' )), get_field( 'bedrooms' ) ); echo $bedrooms; } ?></i></span>
</div>
<?php
$images = get_field('gallery');
if( $images ): ?>
<!-- Slider -->
<div class="listing-carousel">
<?php foreach( $images as $image ): ?>
<div><img src="<?php echo $image['url']; ?>" alt=""></div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</a>
<div class="listing-content">
<div class="listing-title">
<h4><a href="<?php echo esc_url( get_permalink() ); ?>"><?php the_field( 'type' ); ?> in <?php the_field( 'area' ); ?></a></h4>
<?php
$title_location = esc_html( get_the_title() );
$title_location_formatted = str_replace(" ", "+", $title_location);
?>
<a href="https://maps.google.com/maps?q=<?php echo $title_location_formatted; ?>&hl=en&t=v&hnear=<?php echo $title_location_formatted; ?>" class="listing-address popup-gmaps">
<i class="fa fa-map-marker"></i>
<?php echo $title_location; ?>
</a>
</div>
<?php
$date = get_field('onmarket', false, false);
// make date object
$date = new DateTime($date);
?>
<?php
$lat1 = (float)get_field('latitude' );
$lon1 = (float)get_field('longitude' );
//$distance = getDistance($lat1, $lon1, $zip2);
//$next_lat = getlntsql($zip2);
$lat2 = (float)$next_lat[0]->latitude;
$lon2 = (float)$next_lat[0]->longitude;
$theta = $lon1-$lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$zip1 = get_field('postcode');
if (isset($miles)) {
$miles = number_format( $miles, 2 ); ?>
<p style="font-weight:bold; margin-top:0; margin-bottom:0;"><?php echo $miles; ?> Miles from <?php echo $zip2; ?></p>
<?php } ?>
<div class="listing-footer">
<a href="#"><i class="fa fa-calendar-o"></i> Published: <?php echo get_the_date( 'j M Y' ); ?></a>
</div>
</div>
</div>
<!-- Listing Item / End -->
<?php
}
$big = 999999999;
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, $paged ),
'total' => $the_query2->max_num_pages,
) );
wp_reset_postdata();
?>
</div>
<!-- Listings Container / End -->
Edit 1
After some faffing, I realised the paged parameter wasn't working as expected. If you are on a page-template.php (page), rather than a archive-post.php (post), then to get the $paged parameter:
if ( get_query_var( 'paged' ) ) { $paged = get_query_var( 'paged' ); }
elseif ( get_query_var( 'page' ) ) { $paged = get_query_var( 'page' ); }
else { $paged = 1; }