Make WordPress Core


Ignore:
Timestamp:
02/02/2021 07:23:08 PM (6 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Allow for the posts endpoint include/exclude terms query to include_children.

For example the categories or categories_exclude parameters can now optionally accept an object with a terms property that accepts the list of term ids and a new include_children property which controls the Tax Query include_children field.

Props jason_the_adams, jnylen0, birgire, dlh.
Fixes #39494.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r50024 r50157  
    281281                }
    282282
    283                 $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
    284 
    285                 if ( ! empty( $request['tax_relation'] ) ) {
    286                         $args['tax_query'] = array( 'relation' => $request['tax_relation'] );
    287                 }
    288 
    289                 foreach ( $taxonomies as $taxonomy ) {
    290                         $base        = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
    291                         $tax_exclude = $base . '_exclude';
    292 
    293                         if ( ! empty( $request[ $base ] ) ) {
    294                                 $args['tax_query'][] = array(
    295                                         'taxonomy'         => $taxonomy->name,
    296                                         'field'            => 'term_id',
    297                                         'terms'            => $request[ $base ],
    298                                         'include_children' => false,
    299                                 );
    300                         }
    301 
    302                         if ( ! empty( $request[ $tax_exclude ] ) ) {
    303                                 $args['tax_query'][] = array(
    304                                         'taxonomy'         => $taxonomy->name,
    305                                         'field'            => 'term_id',
    306                                         'terms'            => $request[ $tax_exclude ],
    307                                         'include_children' => false,
    308                                         'operator'         => 'NOT IN',
    309                                 );
    310                         }
    311                 }
     283                $args = $this->prepare_tax_query( $args, $request );
    312284
    313285                // Force the post_type argument, since it's not a user input variable.
     
    28002772                );
    28012773
    2802                 $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
    2803 
    2804                 if ( ! empty( $taxonomies ) ) {
    2805                         $query_params['tax_relation'] = array(
    2806                                 'description' => __( 'Limit result set based on relationship between multiple taxonomies.' ),
    2807                                 'type'        => 'string',
    2808                                 'enum'        => array( 'AND', 'OR' ),
    2809                         );
    2810                 }
    2811 
    2812                 foreach ( $taxonomies as $taxonomy ) {
    2813                         $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
    2814 
    2815                         $query_params[ $base ] = array(
    2816                                 /* translators: %s: Taxonomy name. */
    2817                                 'description' => sprintf( __( 'Limit result set to all items that have the specified term assigned in the %s taxonomy.' ), $base ),
    2818                                 'type'        => 'array',
    2819                                 'items'       => array(
    2820                                         'type' => 'integer',
    2821                                 ),
    2822                                 'default'     => array(),
    2823                         );
    2824 
    2825                         $query_params[ $base . '_exclude' ] = array(
    2826                                 /* translators: %s: Taxonomy name. */
    2827                                 'description' => sprintf( __( 'Limit result set to all items except those that have the specified term assigned in the %s taxonomy.' ), $base ),
    2828                                 'type'        => 'array',
    2829                                 'items'       => array(
    2830                                         'type' => 'integer',
    2831                                 ),
    2832                                 'default'     => array(),
    2833                         );
    2834                 }
     2774                $query_params = $this->prepare_taxonomy_limit_schema( $query_params );
    28352775
    28362776                if ( 'post' === $this->post_type ) {
     
    29002840                return $statuses;
    29012841        }
     2842
     2843        /**
     2844         * Prepares the 'tax_query' for a collection of posts.
     2845         *
     2846         * @since 5.7.0
     2847         *
     2848         * @param array           $args    WP_Query arguments.
     2849         * @param WP_REST_Request $request Full details about the request.
     2850         * @return array Updated query arguments.
     2851         */
     2852        private function prepare_tax_query( array $args, WP_REST_Request $request ) {
     2853                $relation = $request['tax_relation'];
     2854
     2855                if ( $relation ) {
     2856                        $args['tax_query'] = array( 'relation' => $relation );
     2857                }
     2858
     2859                $taxonomies = wp_list_filter(
     2860                        get_object_taxonomies( $this->post_type, 'objects' ),
     2861                        array( 'show_in_rest' => true )
     2862                );
     2863
     2864                foreach ( $taxonomies as $taxonomy ) {
     2865                        $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     2866
     2867                        $tax_include = $request[ $base ];
     2868                        $tax_exclude = $request[ $base . '_exclude' ];
     2869
     2870                        if ( $tax_include ) {
     2871                                $terms            = array();
     2872                                $include_children = false;
     2873
     2874                                if ( rest_is_array( $tax_include ) ) {
     2875                                        $terms = $tax_include;
     2876                                } elseif ( rest_is_object( $tax_include ) ) {
     2877                                        $terms            = empty( $tax_include['terms'] ) ? array() : $tax_include['terms'];
     2878                                        $include_children = ! empty( $tax_include['include_children'] );
     2879                                }
     2880
     2881                                if ( $terms ) {
     2882                                        $args['tax_query'][] = array(
     2883                                                'taxonomy'         => $taxonomy->name,
     2884                                                'field'            => 'term_id',
     2885                                                'terms'            => $terms,
     2886                                                'include_children' => $include_children,
     2887                                        );
     2888                                }
     2889                        }
     2890
     2891                        if ( $tax_exclude ) {
     2892                                $terms            = array();
     2893                                $include_children = false;
     2894
     2895                                if ( rest_is_array( $tax_exclude ) ) {
     2896                                        $terms = $tax_exclude;
     2897                                } elseif ( rest_is_object( $tax_exclude ) ) {
     2898                                        $terms            = empty( $tax_exclude['terms'] ) ? array() : $tax_exclude['terms'];
     2899                                        $include_children = ! empty( $tax_exclude['include_children'] );
     2900                                }
     2901
     2902                                if ( $terms ) {
     2903                                        $args['tax_query'][] = array(
     2904                                                'taxonomy'         => $taxonomy->name,
     2905                                                'field'            => 'term_id',
     2906                                                'terms'            => $terms,
     2907                                                'include_children' => $include_children,
     2908                                                'operator'         => 'NOT IN',
     2909                                        );
     2910                                }
     2911                        }
     2912                }
     2913
     2914                return $args;
     2915        }
     2916
     2917        /**
     2918         * Prepares the collection schema for including and excluding items by terms.
     2919         *
     2920         * @since 5.7.0
     2921         *
     2922         * @param array $query_params Collection schema.
     2923         * @return array Updated schema.
     2924         */
     2925        private function prepare_taxonomy_limit_schema( array $query_params ) {
     2926                $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) );
     2927
     2928                if ( ! $taxonomies ) {
     2929                        return $query_params;
     2930                }
     2931
     2932                $query_params['tax_relation'] = array(
     2933                        'description' => __( 'Limit result set based on relationship between multiple taxonomies.' ),
     2934                        'type'        => 'string',
     2935                        'enum'        => array( 'AND', 'OR' ),
     2936                );
     2937
     2938                $limit_schema = array(
     2939                        'type'  => array( 'object', 'array' ),
     2940                        'oneOf' => array(
     2941                                array(
     2942                                        'title'       => __( 'Term ID List' ),
     2943                                        'description' => __( 'Match terms with the listed IDs.' ),
     2944                                        'type'        => 'array',
     2945                                        'items'       => array(
     2946                                                'type' => 'integer',
     2947                                        ),
     2948                                ),
     2949                                array(
     2950                                        'title'                => __( 'Term ID Taxonomy Query' ),
     2951                                        'description'          => __( 'Perform an advanced term query.' ),
     2952                                        'type'                 => 'object',
     2953                                        'properties'           => array(
     2954                                                'terms'            => array(
     2955                                                        'description' => __( 'Term IDs.' ),
     2956                                                        'type'        => 'array',
     2957                                                        'items'       => array(
     2958                                                                'type' => 'integer',
     2959                                                        ),
     2960                                                        'default'     => array(),
     2961                                                ),
     2962                                                'include_children' => array(
     2963                                                        'description' => __( 'Whether to include child terms in the terms limiting the result set.' ),
     2964                                                        'type'        => 'boolean',
     2965                                                        'default'     => false,
     2966                                                ),
     2967                                        ),
     2968                                        'additionalProperties' => false,
     2969                                ),
     2970                        ),
     2971                );
     2972
     2973                $include_schema = array_merge(
     2974                        array(
     2975                                /* translators: %s: Taxonomy name. */
     2976                                'description' => __( 'Limit result set to items with specific terms assigned in the %s taxonomy.' ),
     2977                        ),
     2978                        $limit_schema
     2979                );
     2980                $exclude_schema = array_merge(
     2981                        array(
     2982                                /* translators: %s: Taxonomy name. */
     2983                                'description' => __( 'Limit result set to items except those with specific terms assigned in the %s taxonomy.' ),
     2984                        ),
     2985                        $limit_schema
     2986                );
     2987
     2988                foreach ( $taxonomies as $taxonomy ) {
     2989                        $base         = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
     2990                        $base_exclude = $base . '_exclude';
     2991
     2992                        $query_params[ $base ]                = $include_schema;
     2993                        $query_params[ $base ]['description'] = sprintf( $query_params[ $base ]['description'], $base );
     2994
     2995                        $query_params[ $base_exclude ]                = $exclude_schema;
     2996                        $query_params[ $base_exclude ]['description'] = sprintf( $query_params[ $base_exclude ]['description'], $base );
     2997
     2998                        if ( ! $taxonomy->hierarchical ) {
     2999                                unset( $query_params[ $base ]['oneOf'][1]['properties']['include_children'] );
     3000                                unset( $query_params[ $base_exclude ]['oneOf'][1]['properties']['include_children'] );
     3001                        }
     3002                }
     3003
     3004                return $query_params;
     3005        }
    29023006}
Note: See TracChangeset for help on using the changeset viewer.