← Back
Editing: filter-rest-routes.php
<?php /** * @package Polylang */ /** * Class to manage REST routes filterable by language. * * @since 3.5 */ class PLL_Filter_REST_Routes { /** * Cached REST routes filterable by language ordered by types. * * @var string[] * @phpstan-var array<string, string> */ private $filtered_routes = array(); /** * @var PLL_Model */ private $model; /** * Constructor. * * @since 3.5 * * @param PLL_Model $model Shared instance of the current PLL_Model. */ public function __construct( PLL_Model $model ) { $this->model = $model; } /** * Adds query parameters to preload paths. * * @since 3.5 * * @param (string|string[])[] $preload_paths Array of paths to preload. * @param array $args Array of query strings to add paired by key/value. * @return (string|string[])[] */ public function add_query_parameters( array $preload_paths, array $args ): array { foreach ( $preload_paths as $k => $path ) { if ( empty( $path ) ) { continue; } $query_params = array(); // If the method request is OPTIONS, $path is an array and the first element is the path if ( is_array( $path ) ) { $temp_path = $path[0]; } else { $temp_path = $path; } $path_parts = wp_parse_url( $temp_path ); if ( ! isset( $path_parts['path'] ) || ! $this->is_filtered( $path_parts['path'] ) ) { continue; } if ( ! empty( $path_parts['query'] ) ) { parse_str( $path_parts['query'], $query_params ); } // Add params in query params foreach ( $args as $key => $value ) { $query_params[ $key ] = $value; } // Sort query params to put it in the same order as the preloading middleware does ksort( $query_params ); // Replace the key by the correct path with query params reordered $sorted_path = add_query_arg( urlencode_deep( $query_params ), $path_parts['path'] ); if ( is_array( $path ) ) { $preload_paths[ $k ][0] = $sorted_path; } else { $preload_paths[ $k ] = $sorted_path; } } return $preload_paths; } /** * Adds inline script to declare filtered REST route on client side. * * @since 3.5 * * @param string $script_handle Name of the script to add the inline script to. * @return void */ public function add_inline_script( string $script_handle ) { $script_var = 'window.pllFilteredRoutes = ' . (string) wp_json_encode( $this->get() ); wp_add_inline_script( $script_handle, $script_var, 'before' ); } /** * Returns filtered REST routes by entity type (e.g. post type or taxonomy). * * @since 3.5 * * @return string[] REST routes. * @phpstan-return array<string, string> */ private function get(): array { if ( ! empty( $this->filtered_routes ) ) { return $this->filtered_routes; } $translatable_post_types = $this->model->get_translated_post_types(); $translatable_taxonomies = $this->model->get_translated_taxonomies(); $post_types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_rest' => true ), 'objects' ); $filtered_entities = $this->extract_filtered_rest_entities( array_merge( $post_types, $taxonomies ), array_merge( $translatable_post_types, $translatable_taxonomies ) ); /** * Filters REST routes filterable by languages. * * @since 3.7 * * @param string[] $routes Array of filterable REST routes, with types as key. */ $this->filtered_routes = apply_filters( 'pll_filtered_rest_routes', array_merge( $filtered_entities, array( 'search' => 'wp/v2/search' ) ) ); return $this->filtered_routes; } /** * Tells if a given route is fileterable by language. * * @since 3.5 * * @param string $rest_route Route to test. * @return bool Whether the route is filterable or not. */ private function is_filtered( string $rest_route ): bool { $rest_route = trim( $rest_route ); return ! preg_match( '/\d+$/', $rest_route ) && in_array( trim( $rest_route, '/' ), $this->get(), true ); } /** * Extracts filterable REST route from an array of entity objects * from a list of translatable entities (e.g. post types or taxonomies). * * @since 3.5 * * @param object[] $rest_entities Array of post type or taxonomy objects. * @param string[] $translatable_entities Array of translatable entity names. * @return string[] Filtered routes. * @phpstan-param array<WP_Post_Type|WP_Taxonomy> $rest_entities * @phpstan-return array<string, string> */ private function extract_filtered_rest_entities( array $rest_entities, array $translatable_entities ) { $filtered_entities = array(); foreach ( $rest_entities as $rest_entity ) { if ( in_array( $rest_entity->name, $translatable_entities, true ) ) { $rest_base = empty( $rest_entity->rest_base ) ? $rest_entity->name : $rest_entity->rest_base; $rest_namespace = empty( $rest_entity->rest_namespace ) ? 'wp/v2' : $rest_entity->rest_namespace; $filtered_entities[ $rest_entity->name ] = "{$rest_namespace}/{$rest_base}"; } } return $filtered_entities; } }
Save File
Cancel