Skip to content

Instantly share code, notes, and snippets.

@g-maclean
Last active November 18, 2025 05:53
Show Gist options
  • Select an option

  • Save g-maclean/9c732a1290ae543e82f061326833304a to your computer and use it in GitHub Desktop.

Select an option

Save g-maclean/9c732a1290ae543e82f061326833304a to your computer and use it in GitHub Desktop.
Property Hive - Elementor - Similar Properties Query ID
add_action( 'elementor/query/similar_properties_query', function( $query ) {
global $property;
//
// STATIC DEFAULTS (taken from the shortcode)
// https://docs.wp-property-hive.com/article/312-shortcodes-similarproperties
//
$atts = array(
//'per_page' => 2, //unused
//'columns' => 2, //unused
'orderby' => 'rand',
'order' => 'asc',
'price_percentage_bounds' => 10,
'bedroom_bounds' => 0,
'matching_address_field' => '',
'property_id' => '',
'availability_id' => '',
'property_type_id' => '',
'match_property_type' => '',
'exclude' => '',
);
//
// GET MAIN PROPERTY ID
//
if ( empty($atts['property_id']) && isset($property->id) ) {
$atts['property_id'] = $property->id;
}
if ( empty($atts['property_id']) ) {
// No base property → no matches
$query->set( 'post__in', array(0) );
return;
}
//
// START BUILDING WP_QUERY ARGS
//
$department = get_post_meta( $atts['property_id'], '_department', true );
$args = array(
'post_type' => 'property',
'post__not_in' => array( $atts['property_id'] ),
'post_status' => ( ( is_user_logged_in() && current_user_can( 'manage_propertyhive' ) )
? array('publish', 'private') : 'publish' ),
'ignore_sticky_posts' => 1,
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'has_password' => false,
);
$meta_query = array();
// Match department
$meta_query[] = array(
'key' => '_department',
'value' => $department,
);
// On market
$meta_query[] = array(
'key' => '_on_market',
'value' => 'yes',
);
//
// RESIDENTIAL LOGIC
//
if ( $department !== 'commercial' ) {
// ---- Bedrooms ----
$bedrooms = get_post_meta( $atts['property_id'], '_bedrooms', true );
if ( $bedrooms !== '' ) {
$lower = $bedrooms - (int)$atts['bedroom_bounds'];
$upper = $bedrooms + (int)$atts['bedroom_bounds'];
$meta_query[] = array(
'key' => '_bedrooms',
'value' => array($lower, $upper),
'compare' => 'BETWEEN',
'type' => 'NUMERIC'
);
}
// ---- Price ----
$price = get_post_meta( $atts['property_id'], '_price_actual', true );
if ( is_numeric($price) ) {
$pct = (int)$atts['price_percentage_bounds'];
$lower = $price - ($price * $pct / 100);
$upper = $price + ($price * $pct / 100);
$meta_query[] = array(
'key' => '_price_actual',
'value' => array($lower, $upper),
'compare' => 'BETWEEN',
'type' => 'NUMERIC'
);
}
} else {
//
// COMMERCIAL LOGIC
//
$for_sale = get_post_meta( $atts['property_id'], '_for_sale', true );
$to_rent = get_post_meta( $atts['property_id'], '_to_rent', true );
$sub_meta = array('relation' => 'OR');
if ( $for_sale === 'yes' ) {
$sub_meta[] = array(
'key' => '_for_sale',
'value' => 'yes'
);
}
if ( $to_rent === 'yes' ) {
$sub_meta[] = array(
'key' => '_to_rent',
'value' => 'yes'
);
}
if ( count($sub_meta) > 1 ) {
$meta_query[] = $sub_meta;
}
}
//
// MATCH ADDRESS FIELD (address two/three/four)
//
if ( in_array($atts['matching_address_field'], ['address_two', 'address_three', 'address_four']) ) {
$value = get_post_meta( $atts['property_id'], '_' . $atts['matching_address_field'], true );
if ( $value !== '' ) {
$meta_query[] = array(
'key' => '_' . $atts['matching_address_field'],
'value' => $value,
);
}
}
//
// TAX QUERIES
//
$tax_query = array();
// Availability
if ( !empty($atts['availability_id']) ) {
$tax_query[] = array(
'taxonomy' => 'availability',
'terms' => explode(',', $atts['availability_id']),
'compare' => 'IN'
);
}
// Property type
$property_types = array();
if ( !empty($atts['property_type_id']) ) {
$property_types = explode(',', $atts['property_type_id']);
}
if ( $atts['match_property_type'] ) {
$tax_name = ($department === 'commercial' ? 'commercial_property_type' : 'property_type');
$types = wp_get_post_terms( (int)$atts['property_id'], $tax_name, array('fields'=>'ids') );
if ( !empty($types) ) {
$property_types = $types;
}
}
if ( !empty($property_types) ) {
$tax_query[] = array(
'taxonomy' => ($department === 'commercial' ? 'commercial_property_type' : 'property_type'),
'terms' => array_unique(array_filter($property_types)),
'compare' => 'IN'
);
}
// If matching address_field = location
if ( $atts['matching_address_field'] === 'location' ) {
$loc_terms = wp_get_post_terms( $atts['property_id'], 'location', array('fields'=>'ids') );
if ( !empty($loc_terms) ) {
$tax_query[] = array(
'taxonomy' => 'location',
'terms' => $loc_terms,
'compare' => 'IN'
);
}
}
if ( !empty($tax_query) ) {
$args['tax_query'] = $tax_query;
}
//
// ORDER BY DATE = on_market_change_date meta
//
if ( $atts['orderby'] === 'date' ) {
$args['orderby'] = 'meta_value';
$args['meta_key'] = '_on_market_change_date';
}
//
// EXCLUDE
//
if ( !empty($atts['exclude']) ) {
$exclude = array_map('absint', explode(',', $atts['exclude']));
$args['post__not_in'] = array_filter($exclude);
}
//
// PASS ALL ARGUMENTS TO THE ELEMENTOR QUERY
//
foreach ($args as $key => $value) {
$query->set($key, $value);
}
$query->set('meta_query', $meta_query);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment