diff --git a/includes/api/class-sp-rest-api.php b/includes/api/class-sp-rest-api.php index 0ce94ccb..a951f3d9 100644 --- a/includes/api/class-sp-rest-api.php +++ b/includes/api/class-sp-rest-api.php @@ -49,6 +49,13 @@ class SP_REST_API { if ( ! class_exists( 'SP_REST_Terms_Controller' ) ) { require_once dirname( __FILE__ ) . '/class-sp-rest-terms-controller.php'; } + + // Create Player Controller + if ( ! class_exists( 'SP_REST_Players_Controller' ) ) { + require_once dirname( __FILE__ ) . '/class-sp-rest-players-controller.php'; + $player_controller = new SP_REST_Players_Controller(); + $player_controller->register_routes(); + } do_action( 'sportspress_create_rest_routes' ); } diff --git a/includes/api/class-sp-rest-players-controller.php b/includes/api/class-sp-rest-players-controller.php new file mode 100644 index 00000000..798577f6 --- /dev/null +++ b/includes/api/class-sp-rest-players-controller.php @@ -0,0 +1,160 @@ +post_type ); + $this->namespace = 'sportspress/v2'; + } + + /** + * Register the routes for players. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'args' => $this->get_collection_params(), + ) + ) ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $query_args = $this->prepare_objects_query( $request ); + $query_results = $this->get_objects( $query_args ); + + $objects = array(); + foreach ( $query_results['objects'] as $object ) { + $data = $this->prepare_item_for_response( $object, $request ); + $objects[] = $this->prepare_response_for_collection( $data ); + } + + $page = (int) $query_args['paged']; + $max_pages = $query_results['pages']; + + $response = rest_ensure_response( $objects ); + $response->header( 'X-WP-Total', $query_results['total'] ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Prepare objects query. + * + * @since 2.5 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + // Filter players by team id + if ( ! empty( $request['team_id'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => 'sp_team', + 'value' => $request['team_id'] + ) ); + } + + // Filter players by current team id + if ( ! empty( $request['current_team_id'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => 'sp_current_team', + 'value' => $request['current_team_id'] + ) ); + } + + // Filter players by past team id + if ( ! empty( $request['past_team_id'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => 'sp_past_team', + 'value' => $request['past_team_id'] + ) ); + } + + return $this->prepare_items_query( $args, $request ); + } + + /** + * Get objects. + * + * @since 3.0.0 + * @param array $query_args Query args. + * @return array + */ + protected function get_objects( $query_args ) { + $query = new WP_Query(); + $result = $query->query( $query_args ); + + $total_posts = $query->found_posts; + if ( $total_posts < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $query_args['paged'] ); + $count_query = new WP_Query(); + $count_query->query( $query_args ); + $total_posts = $count_query->found_posts; + } + + return array( + 'objects' => $result, + 'total' => (int) $total_posts, + 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), + ); + } + +} diff --git a/includes/api/class-sp-rest-posts-controller.php b/includes/api/class-sp-rest-posts-controller.php index 78b7de33..219fbf9b 100644 --- a/includes/api/class-sp-rest-posts-controller.php +++ b/includes/api/class-sp-rest-posts-controller.php @@ -6,5 +6,76 @@ if ( class_exists( 'WP_REST_Posts_Controller' ) ) { parent::__construct( $post_type ); $this->namespace = 'sportspress/v2'; } + + /** + * Add meta query. + * + * @since 2.5 + * @param array $args Query args. + * @param array $meta_query Meta query. + * @return array + */ + protected function add_meta_query( $args, $meta_query ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = $meta_query; + + return $args['meta_query']; + } + + /** + * Prepare objects query. + * + * @since 2.5 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + if ( 'date' === $args['orderby'] ) { + $args['orderby'] = 'date ID'; + } + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * Filter the query arguments for a request. + * + * Enables adding extra arguments or setting defaults for a post + * collection request. + * + * @param array $args Key value array of query var to query value. + * @param WP_REST_Request $request The request used. + */ + $args = apply_filters( "sportspress_rest_{$this->post_type}_object_query", $args, $request ); + + return $this->prepare_items_query( $args, $request ); + } } } diff --git a/includes/class-sp-post-types.php b/includes/class-sp-post-types.php index a066f966..af06b688 100644 --- a/includes/class-sp-post-types.php +++ b/includes/class-sp-post-types.php @@ -512,7 +512,7 @@ class SP_Post_types { 'show_in_nav_menus' => true, 'menu_icon' => 'dashicons-groups', 'show_in_rest' => true, - 'rest_controller_class' => 'SP_REST_Posts_Controller', + 'rest_controller_class' => 'SP_REST_Players_Controller', 'rest_base' => 'players', ) )