Filtern mehrerer benutzerdefinierter Felder mit der WP-REST-API 2

Ich möchte Beiträge basierend auf mehreren benutzerdefinierten Feldern mit AND-Beziehung filtern. Etwas wie das:

$args = array( 'post_type' => 'product', 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'color', 'value' => 'blue', 'compare' => '=', ), array( 'key' => 'price', 'value' => array( 20, 100 ), 'type' => 'numeric', 'compare' => 'BETWEEN', ), ), ); 

Ich könnte sogar mehr Filter haben. Wie kann ich diese in REST API 2-Filter konvertieren?

Solutions Collecting From Web of "Filtern mehrerer benutzerdefinierter Felder mit der WP-REST-API 2"

Diese Lösung funktioniert mit get_items() in /lib/endpoints/class-wp-rest-posts-controller.php der v2 WP Rest API .


Zuerst werden Sie die GET Argumente wie für ein new WP_Query() konstruieren wollen. Der einfachste Weg dazu ist http_build_query() .

 $args = array ( 'filter' => array ( 'meta_query' => array ( 'relation' => 'AND', array ( 'key' => 'color', 'value' => 'blue', 'compare' => '=', ), array ( 'key' => 'test', 'value' => 'testing', 'compare' => '=', ), ), ), ); $field_string = http_build_query( $args ); 

Es wird etwas wie produzieren:

filter%5Bmeta_query%5D%5Brelation%5D=AND&filter%5Bmeta_query%5D%5B0%5D%5Bkey%5D=color&filter%5Bmeta_query%5D%5B0%5D%5Bvalue%5D=blue&filter%5Bmeta_query%5D%5B0%5D%5Bcompare%5D=%3D&filter%5Bmeta_query%5D%5B1%5D%5Bkey%5D=test&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D=testing&filter%5Bmeta_query%5D%5B1%5D%5Bcompare%5D=%3D

Wenn Sie lesbar sind, können Sie auch Chrome-Tools und decodeURIComponent('your-query-here') , um das Lesen zu vereinfachen, wenn Sie es in Ihre JSON-Rest-API-URL casting:

https://demo.wp-api.org/wp-json/wp/v2/product?filter[meta_query][relation]=AND&filter[meta_query][0][key]=color&filter[meta_query][0][value]=blue&filter[meta_query][0][compare]==&filter[meta_query][1][key]=test&filter[meta_query][1][value]=testing&filter[meta_query][1][compare]==

Hinweis: Um Ihren benutzerdefinierten Post-Typ zu verwenden, würden Sie das product vorher ?

/wp-json/wp/v2/?filter[meta_query]


Also haben Sie Ihre Anfrage, aber wir müssen WP anweisen, wie man mit ein paar Dingen umgeht:

  1. Hinzufügen von REST-Unterstützung für den benutzerdefinierten Posttyp- product
  2. Zulassen der Abfrage args meta_query
  3. Parsen von meta_query

 // 1) Add CPT Support  function wpse_20160526_add_product_rest_support() { global $wp_post_types; //be sure to set this to the name of your post type! $post_type_name = 'product'; if( isset( $wp_post_types[ $post_type_name ] ) ) { $wp_post_types[$post_type_name]->show_in_rest = true; $wp_post_types[$post_type_name]->rest_base = $post_type_name; $wp_post_types[$post_type_name]->rest_controller_class = 'WP_REST_Posts_Controller'; } } add_action( 'init', 'wpse_20160526_add_product_rest_support', 25 ); // 2) Add `meta_query` support in the GET request function wpse_20160526_rest_query_vars( $valid_vars ) { $valid_vars = array_merge( $valid_vars, array( 'meta_query' ) ); // Omit meta_key, meta_value if you don't need them return $valid_vars; } add_filter( 'rest_query_vars', 'wpse_20160526_rest_query_vars', PHP_INT_MAX, 1 ); // 3) Parse Custom Args function wpse_20160526_rest_product_query( $args, $request ) { if ( isset( $args[ 'meta_query' ] ) ) { $relation = 'AND'; if( isset($args['meta_query']['relation']) && in_array($args['meta_query']['relation'], array('AND', 'OR'))) { $relation = sanitize_text_field( $args['meta_query']['relation'] ); } $meta_query = array( 'relation' => $relation ); foreach ( $args['meta_query'] as $inx => $query_req ) { /* Array ( [key] => test [value] => testing [compare] => = ) */ $query = array(); if( is_numeric($inx)) { if( isset($query_req['key'])) { $query['key'] = sanitize_text_field($query_req['key']); } if( isset($query_req['value'])) { $query['value'] = sanitize_text_field($query_req['value']); } if( isset($query_req['type'])) { $query['type'] = sanitize_text_field($query_req['type']); } if( isset($query_req['compare']) && in_array($query_req['compare'], array('=', '!=', '>','>=','< ','<=','LIKE','NOT LIKE','IN','NOT IN','BETWEEN','NOT BETWEEN', 'NOT EXISTS')) ) { $query['compare'] = sanitize_text_field($query_req['compare']); } } if( ! empty($query) ) $meta_query[] = $query; } // replace with sanitized query args $args['meta_query'] = $meta_query; } return $args; } add_action( 'rest_product_query', 'wpse_20160526_rest_product_query', 10, 2 ); 

Hier ist ein Test, den ich auf Localhost gemacht habe:

Aus Sicherheitsgründen ist eine Meta-Abfrage auf WP Api nicht erlaubt. Zuerst müssen Sie Meta_Query zu rest_query hinzufügen, indem Sie diese function in Ihrem WordPress-Theme functions.php hinzufügen

 function api_allow_meta_query( $valid_vars ) { $valid_vars = array_merge( $valid_vars, array( 'meta_query') ); return $valid_vars; } add_filter( 'rest_query_vars', 'api_allow_meta_query' ); 

Danach müssen Sie die HTML-Abfrage erstellen, indem Sie diese function auf der anderen Website verwenden, die die Daten von der WordPress-Website erhält

 $curl = curl_init(); $fields = array ( 'filter[meta_query]' => array ( 'relation' => 'AND', array ( 'key' => 'color', 'value' => 'blue', 'compare' => '=' ), array ( 'key' => 'price', 'value' => array ( 20, 100 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), ), ); $field_string = http_build_query($fields); curl_setopt_array($curl, array ( CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://yourwordpreswebssite.com/wp-json/wp/v2/posts?' . $field_string ) ); $result = curl_exec($curl); echo htmlentities($result); 

Ich ändere das Array Felder, so dass das Aussehen jetzt wie Ihre Abfrage Argumente. Die codierte Abfragezeichenfolge sieht folgendermaßen aus:

 http://yourwordpreswebssite.com/wp-json/wp/v2/posts?filter%5Btaxonomy%5D=product&filter%5Bmeta_query%5D%5Brelation%5D=AND&filter%5Bmeta_query%5D%5B0%5D%5Bkey%5D=color&filter%5Bmeta_query%5D%5B0%5D%5Bvalue%5D=blue&filter%5Bmeta_query%5D%5B0%5D%5Bcompare%5D=%3D&filter%5Bmeta_query%5D%5B1%5D%5Bkey%5D=price&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D%5B0%5D=20&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D%5B1%5D=100&filter%5Bmeta_query%5D%5B1%5D%5Btype%5D=numeric&filter%5Bmeta_query%5D%5B1%5D%5Bcompare%5D=BETWEEN 

Durch die Verwendung von urldecode() , die in diesem Fall wird: urldecode('http://yourwordpreswebssite.com/wp-json/wp/v2/posts?' . $field_string); Sie werden eine URL wie diese haben:

 http://yourwordpreswebssite.com/wp-json/wp/v2/posts?filter[taxonomy]=product&filter[meta_query][relation]=AND&filter[meta_query][0][key]=color&filter[meta_query][0][value]=blue&filter[meta_query][0][compare]==&filter[meta_query][1][key]=price&filter[meta_query][1][value][0]=20&filter[meta_query][1][value][1]=100&filter[meta_query][1][type]=numeric&filter[meta_query][1][compare]=BETWEEN 

Wenn Sie uns Ihre Live-Website-URL zur Verfügung stellen können, können wir sie mit Postboten direkt auf Ihrer Website testen, da sie auf localhost oder einer bestehenden WordPress-Website getestet werden müssen, um benutzerdefinierte Posts zu erstellen und Meta-Felder usw. hinzuzufügen. Prost!

Du kannst es ohne Rest API machen. So (Es ist mein Postfilter)

     $ paged = (get_query_var ('paged'))?  get_query_var ('paged'): 1;
 $ args = Array (
         'paged' => $ paged,
         'orderby' => 'date', // сортировка по дате у нас будет в любом случае (новы можете изменить / доработать это)
         'bestellen' => 'DESC',
     );

     // создаём массив $ args ['meta_query'] отмечен чекбокс
     if (isset ($ _GET ['price_min']) || isset ($ _GET ['price_max']) || isset ($ _GET ['type']))
         $ args ['meta_query'] = array ('relation' => 'AND');  // UND значит все условия meta_query должны выполняться


     if ($ Typ) {
         $ args ['meta_query'] [] = Array (
             "Schlüssel" => "Typ",
             'Wert' => $ Typ,
         );
     };

     if ($ plan) {
         $ args ['meta_query'] [] = Array (
             "Schlüssel" => "Plan",
             'Wert' => $ Plan,
         );
     };

     if ($ room_num) {
         $ args ['meta_query'] [] = Array (
             "Schlüssel" => "room_num",
             'Wert' => $ room_num,
         );
     };

     if ($ etage) {
         $ args ['meta_query'] [] = Array (
             'key' => 'etage',
             'Wert' => $ etage,
         );
     };  

     if ($ price_min || $ price_max) {
         $ args ['meta_query'] [] = Array (
             'Schlüssel' => 'Preis',
             'Wert' => Array ($ price_min, $ price_max),
             'typ' => 'numerisch',
             'vergleichen' => 'BETWEEN'
         );
     };  

     if ($ bereich_min || $ bereich_max) {
         $ args ['meta_query'] [] = Array (
             'Schlüssel' => 'Bereich',
             'wert' => array ($ bereich_min, $ bereich_max),
             'typ' => 'numerisch',
             'vergleichen' => 'BETWEEN'
         );
     };

In WordPress 4.7 wurde das filter entfernt.

Sie können es wieder aktivieren, indem Sie dieses Plugin vom WordPress-Team installieren. Erst danach können Sie eine der in den anderen Antworten vorgeschlagenen Lösungen verwenden.

Ich habe keine Lösung gefunden, um dasselbe zu tun, ohne das Plugin zu installieren.