false, 'lng' => false, 'radius' => false, 'namequery' => false, 'query_type' => 'distance', 'address' => false, 'city' => false, 'state' => false, 'zip' => false, 'onlyzip' => false, 'country' => false, 'limit' => false, 'page' => false, 'pid' => 0, ); $input = array_filter( array_intersect_key( $_GET, $defaults ) ) + $defaults; $smtaxes = array(); if ( $taxonomies = get_object_taxonomies( 'sm-location' ) ) { foreach ( $taxonomies as $key => $tax ) { $phpsafe = str_replace( '-', '_', $tax ); $_GET += array( $phpsafe => '' ); $smtaxes[$tax] = $_GET[$phpsafe]; } } // Define my empty strings $distance_select = $distance_having = $distance_order = ''; // We're going to do a hard limit to 5000 for now. if ( !$input['limit'] || $input['limit'] > 250 || $input['limit'] == 0 ) { $limit_int = 250; $limit = "LIMIT 250"; } else { $limit_int = absint( $input['limit'] ); $limit = 'LIMIT ' . $limit_int; } $limit = apply_filters( 'sm-xml-search-limit', $limit ); if ( $input['page'] && $input['page'] < 250 ) { $offset = 'OFFSET ' . ( absint($input['page']) - 1) * absint( $input['limit'] ); } else { $offset = ''; } // Locations within specific distance or just get them all? $distance_select = $wpdb->prepare( "( 3959 * ACOS( COS( RADIANS(%s) ) * COS( RADIANS( lat_tbl.meta_value ) ) * COS( RADIANS( lng_tbl.meta_value ) - RADIANS(%s) ) + SIN( RADIANS(%s) ) * SIN( RADIANS( lat_tbl.meta_value ) ) ) ) AS distance", $input['lat'], $input['lng'], $input['lat'] ) . ', '; $distance_order = 'distance, '; if ( $input['radius'] ) { $input['radius'] = ( $input['radius'] < 1 ) ? 1 : $input['radius']; $distance_having = $wpdb->prepare( "HAVING distance < %d", $input['radius'] ); } $i = 1; $taxonomy_join = ''; foreach ( array_filter( $smtaxes ) as $taxonomy => $tax_value ) { $term_ids = explode( ',', $tax_value ); if ( $term_ids[0] == 'OR' ) { unset( $term_ids[0] ); if ( empty( $term_ids ) ) { continue; } $search_values = array( "IN (" . vsprintf( '%d' . str_repeat( ',%d', count( $term_ids ) - 1 ), $term_ids ) . ")" ); } else { $search_values = array(); foreach ( $term_ids as $term_id ) { $search_values[] = sprintf( '= %d', $term_id ); } } foreach ( $search_values as $search_value ) { $taxonomy_join .= " INNER JOIN $wpdb->term_relationships AS term_rel_$i ON posts.ID = term_rel_$i.object_id INNER JOIN $wpdb->term_taxonomy AS tax_$i ON term_rel_$i.term_taxonomy_id = tax_$i.term_taxonomy_id AND tax_$i.taxonomy = '$taxonomy' AND tax_$i.term_id $search_value "; $i++; } } // Find out how many items are in the table $total_locations_sql = $wpdb->get_var( " SELECT COUNT(*) FROM $wpdb->posts AS posts INNER JOIN $wpdb->postmeta lat_tbl ON lat_tbl.post_id = posts.ID AND lat_tbl.meta_key = 'location_lat' INNER JOIN $wpdb->postmeta lng_tbl ON lng_tbl.post_id = posts.ID AND lng_tbl.meta_key = 'location_lng' $taxonomy_join WHERE posts.post_type = 'sm-location' AND posts.post_status = 'publish' " ); $total_locations = absint($total_locations_sql); $total_pages = ceil($total_locations / $limit_int); // use ceiling to round up -- 0.01 is still "1 page" $this_page_number = absint($input['page']); $sql = "SELECT lat_tbl.meta_value AS lat, lng_tbl.meta_value AS lng, $distance_select posts.ID, posts.post_content, posts.post_title FROM $wpdb->posts AS posts INNER JOIN $wpdb->postmeta lat_tbl ON lat_tbl.post_id = posts.ID AND lat_tbl.meta_key = 'location_lat' INNER JOIN $wpdb->postmeta lng_tbl ON lng_tbl.post_id = posts.ID AND lng_tbl.meta_key = 'location_lng' $taxonomy_join WHERE posts.post_type = 'sm-location' AND posts.post_status = 'publish' GROUP BY posts.ID $distance_having ORDER BY " . apply_filters( 'sm-location-sort-order', $distance_order . ' posts.post_name ASC', $input ) . " " . $limit . " " . $offset; $sql = apply_filters( 'sm-xml-search-locations-sql', $sql ); // TODO: Consider using this to generate the marker node attributes in print_xml(). $location_field_map = array( 'location_address' => 'address', 'location_address2' => 'address2', 'location_city' => 'city', 'location_state' => 'state', 'location_zip' => 'zip', 'location_country' => 'country', 'location_phone' => 'phone', 'location_fax' => 'fax', 'location_email' => 'email', 'location_url' => 'url', 'location_special' => 'special', ); $options = $simple_map->get_options(); $show_permalink = !empty( $options['enable_permalinks'] ); if ( $locations = $wpdb->get_results( $sql ) ) { // Start looping through all locations i found in the radius foreach ( $locations as $key => $value ) { // Add postmeta data to location $custom_fields = get_post_custom( $value->ID ); foreach ( $location_field_map as $key => $field ) { if ( isset( $custom_fields[$key][0] ) ) { $value->$field = $custom_fields[$key][0]; } else { $value->$field = ''; } } $value->postid = $value->ID; $value->name = apply_filters( 'the_title', $value->post_title ); $the_content = trim( $value->post_content ); if ( !empty( $the_content ) ) { $the_content = apply_filters( 'the_content', $the_content ); } $value->description = $the_content; $value->permalink = ''; if ( $show_permalink ) { $value->permalink = get_permalink( $value->ID ); $value->permalink = apply_filters( 'the_permalink', $value->permalink ); } // List all terms for all taxonomies for this post $value->taxes = array(); foreach ( $smtaxes as $taxonomy => $tax_value ) { $phpsafe_tax = str_replace( '-', '_', $taxonomy ); $local_tax_names = ''; // Get all taxes for this post if ( $local_taxes = wp_get_object_terms( $value->ID, $taxonomy, array( 'fields' => 'names' ) ) ) { $local_tax_names = implode( ', ', $local_taxes ); } $value->taxes[$phpsafe_tax] = $local_tax_names; } } } else { // Print empty XML $locations = array(); } $locations = apply_filters( 'sm-xml-search-locations', $locations ); $output = array('locations' => $locations, 'total_locations' => $total_locations, 'total_pages' => $total_pages, 'this_page' => $this_page_number); $this->print_json( $output, $smtaxes ); } } // Prints the JSON output function print_json( $dataset, $smtaxes ) { header( 'Status: 200 OK', false, 200 ); header( 'Content-type: application/json' ); do_action( 'sm-xml-search-headers' ); do_action( 'sm-print-json', $dataset, $smtaxes ); echo json_encode( $dataset ); die(); } } }