2015-10-07 4 views
1

Я как бы новичок с SQL + PHP, и я пытаюсь добавить функцию в плагин, где все работает нормально, если эта проблема не возникает.Пользовательский SQL-запрос для объединения двух таксономий

Link for my page

У меня есть две выпадающие, одна из которых с его корреспондентского систематики. Предполагается, что я ищу совпадающий результат между выпадающим списком, но этого не происходит, я могу выполнить поиск одного или другого выпадающего списка/таксономии.

Код для этого действия заключается в следующем

public function find_nearby_locations() { 

     global $wpdb, $wpsl, $wpsl_settings; 

     $store_data = array(); 

     /* Set the correct earth radius in either km or miles. 
     * We need this to calculate the distance between two coordinates. 
     */ 
     $radius = ($wpsl_settings['distance_unit'] == 'km') ? 6371 : 3959; 

     /* The placeholder values for the prepared statement in the sql query. */ 
     $placeholder_values = array(
      $radius, 
      $_GET['lat'], 
      $_GET['lng'], 
      $_GET['lat'] 
     ); 

     /* Check if we need to filter the results by category. */ 
     if (isset($_GET['filter']) && $_GET['filter']) { 
      $placeholder_values[] = $_GET['filter']; 


      $cat_filter = 
      "INNER JOIN $wpdb->term_relationships AS term_rel ON posts.ID = term_rel.object_id 
      INNER JOIN $wpdb->term_taxonomy AS term_tax ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id 
      AND (term_tax.taxonomy = 'wpsl_store_category' OR term_tax.taxonomy = 'wpsl_custom_category') AND term_tax.term_id = %d"; 






     } else { 
      $cat_filter = ''; 
     } 

     /** 
     * If WPML is active we include 'GROUP BY lat' in the sql query 
     * to prevent duplicate locations from showing up in the results. 
     * 
     * This is a problem when a store location for example 
     * exists in 4 different languages. They would all fall within 
     * the selected radius, but we only need one store ID for the 'icl_object_id' 
     * function to get the correct store ID for the current language.   
     */ 
     if ($wpsl->i18n->wpml_exists()) { 
      $group_by = 'GROUP BY lat'; 
     } else { 
      $group_by = ''; 
     } 

     /* If autoload is enabled we need to check if there is a limit to the 
     * amount of locations we need to show. 
     * 
     * Otherwise include the radius and max results limit in the sql query. 
     */ 
     if (isset($_GET['autoload']) && $_GET['autoload']) { 
      $limit = ''; 

      if ($wpsl_settings['autoload_limit']) { 
       $limit = 'LIMIT %d'; 
       $placeholder_values[] = $wpsl_settings['autoload_limit']; 
      } 

      $sql_sort = 'ORDER BY distance '. $limit; 
     } else { 
      array_push($placeholder_values, $this->check_store_filter('radius'), $this->check_store_filter('max_results')); 
      $sql_sort = 'HAVING distance < %d ORDER BY distance LIMIT 0, %d'; 
     } 

     $placeholder_values = apply_filters('wpsl_sql_placeholder_values', $placeholder_values); 

     /* The sql that will check which store locations fall within 
     * the selected radius based on the lat and lng values. 
     */ 
     $sql = apply_filters('wpsl_sql', 
       "SELECT post_lat.meta_value AS lat, 
         post_lng.meta_value AS lng, 
         posts.ID, 
         (%d * acos(cos(radians(%s)) * cos(radians(post_lat.meta_value)) * cos(radians(post_lng.meta_value) - radians(%s)) + sin(radians(%s)) * sin(radians(post_lat.meta_value)))) 
        AS distance 
        FROM $wpdb->posts AS posts 
      INNER JOIN $wpdb->postmeta AS post_lat ON post_lat.post_id = posts.ID AND post_lat.meta_key = 'wpsl_lat' 
      INNER JOIN $wpdb->postmeta AS post_lng ON post_lng.post_id = posts.ID AND post_lng.meta_key = 'wpsl_lng' 
       $cat_filter 
       WHERE posts.post_type = 'wpsl_stores' 
        AND posts.post_status = 'publish' $group_by $sql_sort" 

     ); 

     $stores = $wpdb->get_results($wpdb->prepare($sql, $placeholder_values)); 

     if ($stores ) { 
      $store_data = apply_filters('wpsl_store_data', $this->get_store_meta_data($stores)); 
     } 

     return $store_data; 
    } 

я уже работал над этим куском кода, ранее это было только показать один таксономия результат с этим кодом:

$cat_filter = "INNER JOIN $wpdb->term_relationships AS term_rel ON posts.ID = term_rel.object_id 
         INNER JOIN $wpdb->term_taxonomy AS term_tax ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id 
         AND term_tax.taxonomy = 'wpsl_store_category' 
         AND term_tax.term_id = %d"; 

Так что я думаю проблема находится в $ cat_filter элемент (просто догадка). То, что я пытаюсь сделать, - это получить результат, соответствующий результатам выпадающего списка.

Я уже пробовал заменить OR для И, но, конечно, мне не повезло.

Кто-нибудь может мне помочь? Я не прошу полностью написать код, но за любой совет, который вы можете получить!

Заранее благодарен!

ответ

1

Сначала вы должны обновить свой JavaScript, чтобы представить оба идентификатора термина таксономии, когда они установлены - в настоящее время он отправляет только одно значение для «фильтра». Вам также понадобится вторая JOIN для тех же таблиц таксономии, которую вы можете сделать, передав массив и отбросив все это в цикл.

if (!empty($filters)){ 
    // if we have any filters we want to join to term_relationships 
    $cat_filter = "INNER JOIN $wpdb->term_relationships AS term_rel 
         ON posts.ID = term_rel.object_id"; 

    // iterate the tax IDs in the "filter" array, use $i to make each table alias unique 
    foreach ($filters as $i => $filter){ 
     // for each filter join to the term_tax table using the tax ID 
     $cat_filter.= "INNER JOIN $wpdb->term_taxonomy AS term_tax{$i} 
          ON term_rel.term_taxonomy_id = term_tax{$i}.term_taxonomy_id 
          AND term_tax{$i}.taxonomy = 'wpsl_store_category' 
          AND term_tax{$i}.term_id = %d"; 

     // add the tax ID to the values for prepare() 
     $placeholder_values[] = $filter; 
    } 
} 
+0

'$ cat_filter = «INNER JOIN $ wpdb-> term_relationships КАК term_rel ПО posts.ID = term_rel.object_id INNER JOIN $ wpdb-> term_taxonomy КАК term_tax ПО term_rel.term_taxonomy_id = term_tax.term_taxonomy_id И (term_tax.taxonomy = 'wpsl_store_category' ИЛИ ​​term_tax.taxonomy = 'wpsl_custom_category') AND term_tax.term_id =% d "; ' Возможно, я был неясно, это код, который работает лучше всего. Этот код выбирает оба таксономии.
Но я думаю, что этот фрагмент, который вы написали, не будет работать, потому что он просто получает одну таксономию ... –

+0

Код, который я включил, будет искать несколько таксономий, ваш код (из того, что размещен в вопросе) ищет только один 'term_id' , Если вы посмотрите на код в моем ответе, второе соединение будет включено в цикл, если 'filters' является массивом' term_id', то они будут включены в запрос. – doublesharp

+0

Я пробовал это, но не повезло. Думаю, есть что-то еще, что нужно изменить. –

Смежные вопросы