Файловый менеджер - Редактировать - /home/topsuzmw/public_html/wp-includes/private/rest-api.zip
Назад
PK ��Z�JԾ � class-wp-rest-response.phpnu �[��� <?php /** * 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 * @var array */ protected $links = array(); /** * The route that was to create the response. * * @since 4.4.0 * @var string */ protected $matched_route = ''; /** * The handler that was used to create the response. * * @since 4.4.0 * @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 * * @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 * * @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 * * @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 * * @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 * * @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 associative 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 * * @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 * * @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 * * @return null|array The handler that was used to create the response. */ public function get_matched_handler() { return $this->matched_handler; } /** * Sets the handler that was responsible for generating the response. * * @since 4.4.0 * * @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 * * @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 * * @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 * * @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 REST 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 normalize 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 REST API. */ $additional = apply_filters( 'rest_response_link_curies', array() ); return array_merge( $curies, $additional ); } } PK ��Z�� , fields/class-wp-rest-comment-meta-fields.phpnu �[��� <?php /** * REST API: WP_REST_Comment_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to manage comment meta via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Comment_Meta_Fields extends WP_REST_Meta_Fields { /** * Retrieves the comment type for comment meta. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'comment'; } /** * Retrieves the comment meta subtype. * * @since 4.9.8 * * @return string 'comment' There are no subtypes. */ protected function get_meta_subtype() { return 'comment'; } /** * Retrieves the type for register_rest_field() in the context of comments. * * @since 4.7.0 * * @return string The REST field type. */ public function get_rest_field_type() { return 'comment'; } } PK ��Zx-,�� � ) fields/class-wp-rest-term-meta-fields.phpnu �[��� <?php /** * REST API: WP_REST_Term_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for terms via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Term_Meta_Fields extends WP_REST_Meta_Fields { /** * Taxonomy to register fields for. * * @since 4.7.0 * @var string */ protected $taxonomy; /** * Constructor. * * @since 4.7.0 * * @param string $taxonomy Taxonomy to register fields for. */ public function __construct( $taxonomy ) { $this->taxonomy = $taxonomy; } /** * Retrieves the term meta type. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'term'; } /** * Retrieves the term meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return $this->taxonomy; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @return string The REST field type. */ public function get_rest_field_type() { return 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy; } } PK ��Z���RH RH $ fields/class-wp-rest-meta-fields.phpnu �[��� <?php /** * REST API: WP_REST_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to manage meta values for an object via the REST API. * * @since 4.7.0 */ #[AllowDynamicProperties] abstract class WP_REST_Meta_Fields { /** * Retrieves the object meta type. * * @since 4.7.0 * * @return string One of 'post', 'comment', 'term', 'user', or anything * else supported by `_get_meta_table()`. */ abstract protected function get_meta_type(); /** * Retrieves the object meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return ''; } /** * Retrieves the object type for register_rest_field(). * * @since 4.7.0 * * @return string The REST field type, such as post type name, taxonomy name, 'comment', or `user`. */ abstract protected function get_rest_field_type(); /** * Registers the meta field. * * @since 4.7.0 * @deprecated 5.6.0 * * @see register_rest_field() */ public function register_field() { _deprecated_function( __METHOD__, '5.6.0' ); register_rest_field( $this->get_rest_field_type(), 'meta', array( 'get_callback' => array( $this, 'get_value' ), 'update_callback' => array( $this, 'update_value' ), 'schema' => $this->get_field_schema(), ) ); } /** * Retrieves the meta field value. * * @since 4.7.0 * * @param int $object_id Object ID to fetch meta for. * @param WP_REST_Request $request Full details about the request. * @return array Array containing the meta values keyed by name. */ public function get_value( $object_id, $request ) { $fields = $this->get_registered_fields(); $response = array(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false ); if ( $args['single'] ) { if ( empty( $all_values ) ) { $value = $args['schema']['default']; } else { $value = $all_values[0]; } $value = $this->prepare_value_for_response( $value, $request, $args ); } else { $value = array(); if ( is_array( $all_values ) ) { foreach ( $all_values as $row ) { $value[] = $this->prepare_value_for_response( $row, $request, $args ); } } } $response[ $name ] = $value; } return $response; } /** * Prepares a meta value for a response. * * This is required because some native types cannot be stored correctly * in the database, such as booleans. We need to cast back to the relevant * type before passing back to JSON. * * @since 4.7.0 * * @param mixed $value Meta value to prepare. * @param WP_REST_Request $request Current request object. * @param array $args Options for the field. * @return mixed Prepared value. */ protected function prepare_value_for_response( $value, $request, $args ) { if ( ! empty( $args['prepare_callback'] ) ) { $value = call_user_func( $args['prepare_callback'], $value, $request, $args ); } return $value; } /** * Updates meta values. * * @since 4.7.0 * * @param array $meta Array of meta parsed from the request. * @param int $object_id Object ID to fetch meta for. * @return null|WP_Error Null on success, WP_Error object on failure. */ public function update_value( $meta, $object_id ) { $fields = $this->get_registered_fields(); $error = new WP_Error(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; if ( ! array_key_exists( $name, $meta ) ) { continue; } $value = $meta[ $name ]; /* * A null value means reset the field, which is essentially deleting it * from the database and then relying on the default value. * * Non-single meta can also be removed by passing an empty array. */ if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) { $args = $this->get_registered_fields()[ $meta_key ]; if ( $args['single'] ) { $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); if ( is_wp_error( rest_validate_value_from_schema( $current, $args['schema'] ) ) ) { $error->add( 'rest_invalid_stored_value', /* translators: %s: Custom field key. */ sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } } $result = $this->delete_meta_value( $object_id, $meta_key, $name ); if ( is_wp_error( $result ) ) { $error->merge_from( $result ); } continue; } if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { $error->add( 'rest_invalid_stored_value', /* translators: %s: Custom field key. */ sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } $is_valid = rest_validate_value_from_schema( $value, $args['schema'], 'meta.' . $name ); if ( is_wp_error( $is_valid ) ) { $is_valid->add_data( array( 'status' => 400 ) ); $error->merge_from( $is_valid ); continue; } $value = rest_sanitize_value_from_schema( $value, $args['schema'] ); if ( $args['single'] ) { $result = $this->update_meta_value( $object_id, $meta_key, $name, $value ); } else { $result = $this->update_multi_meta_value( $object_id, $meta_key, $name, $value ); } if ( is_wp_error( $result ) ) { $error->merge_from( $result ); continue; } } if ( $error->has_errors() ) { return $error; } return null; } /** * Deletes a meta value for an object. * * @since 4.7.0 * * @param int $object_id Object ID the field belongs to. * @param string $meta_key Key for the field. * @param string $name Name for the field that is exposed in the REST API. * @return true|WP_Error True if meta field is deleted, WP_Error otherwise. */ protected function delete_meta_value( $object_id, $meta_key, $name ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_delete', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return true; } if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return new WP_Error( 'rest_meta_database_error', __( 'Could not delete meta value from database.' ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } /** * Updates multiple meta values for an object. * * Alters the list of values in the database to match the list of provided values. * * @since 4.7.0 * @since 6.7.0 Stores values into DB even if provided registered default value. * * @param int $object_id Object ID to update. * @param string $meta_key Key for the custom field. * @param string $name Name for the field that is exposed in the REST API. * @param array $values List of values to update to. * @return true|WP_Error True if meta fields are updated, WP_Error otherwise. */ protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } $current_values = get_metadata_raw( $meta_type, $object_id, $meta_key, false ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( ! is_array( $current_values ) ) { $current_values = array(); } $to_remove = $current_values; $to_add = $values; foreach ( $to_add as $add_key => $value ) { $remove_keys = array_keys( array_filter( $current_values, function ( $stored_value ) use ( $meta_key, $subtype, $value ) { return $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $value ); } ) ); if ( empty( $remove_keys ) ) { continue; } if ( count( $remove_keys ) > 1 ) { // To remove, we need to remove first, then add, so don't touch. continue; } $remove_key = $remove_keys[0]; unset( $to_remove[ $remove_key ] ); unset( $to_add[ $add_key ] ); } /* * `delete_metadata` removes _all_ instances of the value, so only call once. Otherwise, * `delete_metadata` will return false for subsequent calls of the same value. * Use serialization to produce a predictable string that can be used by array_unique. */ $to_remove = array_map( 'maybe_unserialize', array_unique( array_map( 'maybe_serialize', $to_remove ) ) ); foreach ( $to_remove as $value ) { if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } foreach ( $to_add as $value ) { if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } return true; } /** * Updates a meta value for an object. * * @since 4.7.0 * @since 6.7.0 Stores values into DB even if provided registered default value. * * @param int $object_id Object ID to update. * @param string $meta_key Key for the custom field. * @param string $name Name for the field that is exposed in the REST API. * @param mixed $value Updated value. * @return true|WP_Error True if the meta field was updated, WP_Error otherwise. */ protected function update_meta_value( $object_id, $meta_key, $name, $value ) { $meta_type = $this->get_meta_type(); // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( is_array( $old_value ) && 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) { return true; } if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } /** * Checks if the user provided value is equivalent to a stored value for the given meta key. * * @since 5.5.0 * * @param string $meta_key The meta key being checked. * @param string $subtype The object subtype. * @param mixed $stored_value The currently stored value retrieved from get_metadata(). * @param mixed $user_value The value provided by the user. * @return bool */ protected function is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $user_value ) { $args = $this->get_registered_fields()[ $meta_key ]; $sanitized = sanitize_meta( $meta_key, $user_value, $this->get_meta_type(), $subtype ); if ( in_array( $args['type'], array( 'string', 'number', 'integer', 'boolean' ), true ) ) { // The return value of get_metadata will always be a string for scalar types. $sanitized = (string) $sanitized; } return $sanitized === $stored_value; } /** * Retrieves all the registered meta fields. * * @since 4.7.0 * * @return array Registered fields. */ protected function get_registered_fields() { $registered = array(); $meta_type = $this->get_meta_type(); $meta_subtype = $this->get_meta_subtype(); $meta_keys = get_registered_meta_keys( $meta_type ); if ( ! empty( $meta_subtype ) ) { $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $meta_type, $meta_subtype ) ); } foreach ( $meta_keys as $name => $args ) { if ( empty( $args['show_in_rest'] ) ) { continue; } $rest_args = array(); if ( is_array( $args['show_in_rest'] ) ) { $rest_args = $args['show_in_rest']; } $default_args = array( 'name' => $name, 'single' => $args['single'], 'type' => ! empty( $args['type'] ) ? $args['type'] : null, 'schema' => array(), 'prepare_callback' => array( $this, 'prepare_value' ), ); $default_schema = array( 'type' => $default_args['type'], 'title' => empty( $args['label'] ) ? '' : $args['label'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); $rest_args = array_merge( $default_args, $rest_args ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; if ( null === $rest_args['schema']['default'] ) { $rest_args['schema']['default'] = static::get_empty_value_for_type( $type ); } $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { continue; } if ( empty( $rest_args['single'] ) ) { $rest_args['schema'] = array( 'type' => 'array', 'items' => $rest_args['schema'], ); } $registered[ $name ] = $rest_args; } return $registered; } /** * Retrieves the object's meta schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Field schema data. */ public function get_field_schema() { $fields = $this->get_registered_fields(); $schema = array( 'description' => __( 'Meta fields.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array(), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => array( $this, 'check_meta_is_array' ), ), ); foreach ( $fields as $args ) { $schema['properties'][ $args['name'] ] = $args['schema']; } return $schema; } /** * Prepares a meta value for output. * * Default preparation for meta fields. Override by passing the * `prepare_callback` in your `show_in_rest` options. * * @since 4.7.0 * * @param mixed $value Meta value from the database. * @param WP_REST_Request $request Request object. * @param array $args REST-specific options for the meta key. * @return mixed Value prepared for output. If a non-JsonSerializable object, null. */ public static function prepare_value( $value, $request, $args ) { if ( $args['single'] ) { $schema = $args['schema']; } else { $schema = $args['schema']['items']; } if ( '' === $value && in_array( $schema['type'], array( 'boolean', 'integer', 'number' ), true ) ) { $value = static::get_empty_value_for_type( $schema['type'] ); } if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { return null; } return rest_sanitize_value_from_schema( $value, $schema ); } /** * Check the 'meta' value of a request is an associative array. * * @since 4.7.0 * * @param mixed $value The meta value submitted in the request. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter name. * @return array|false The meta array, if valid, false otherwise. */ public function check_meta_is_array( $value, $request, $param ) { if ( ! is_array( $value ) ) { return false; } return $value; } /** * Recursively add additionalProperties = false to all objects in a schema if no additionalProperties setting * is specified. * * This is needed to restrict properties of objects in meta values to only * registered items, as the REST API will allow additional properties by * default. * * @since 5.3.0 * @deprecated 5.6.0 Use rest_default_additional_properties_to_false() instead. * * @param array $schema The schema array. * @return array */ protected function default_additional_properties_to_false( $schema ) { _deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' ); return rest_default_additional_properties_to_false( $schema ); } /** * Gets the empty value for a schema type. * * @since 5.3.0 * * @param string $type The schema type. * @return mixed */ protected static function get_empty_value_for_type( $type ) { switch ( $type ) { case 'string': return ''; case 'boolean': return false; case 'integer': return 0; case 'number': return 0.0; case 'array': case 'object': return array(); default: return null; } } } PK ��Zr���X X ) fields/class-wp-rest-user-meta-fields.phpnu �[��� <?php /** * REST API: WP_REST_User_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for users via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_User_Meta_Fields extends WP_REST_Meta_Fields { /** * Retrieves the user meta type. * * @since 4.7.0 * * @return string The user meta type. */ protected function get_meta_type() { return 'user'; } /** * Retrieves the user meta subtype. * * @since 4.9.8 * * @return string 'user' There are no subtypes. */ protected function get_meta_subtype() { return 'user'; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @return string The user REST field type. */ public function get_rest_field_type() { return 'user'; } } PK ��Z`&�� � ) fields/class-wp-rest-post-meta-fields.phpnu �[��� <?php /** * REST API: WP_REST_Post_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for posts via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Post_Meta_Fields extends WP_REST_Meta_Fields { /** * Post type to register fields for. * * @since 4.7.0 * @var string */ protected $post_type; /** * Constructor. * * @since 4.7.0 * * @param string $post_type Post type to register fields for. */ public function __construct( $post_type ) { $this->post_type = $post_type; } /** * Retrieves the post meta type. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'post'; } /** * Retrieves the post meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return $this->post_type; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @see register_rest_field() * * @return string The REST field type. */ public function get_rest_field_type() { return $this->post_type; } } PK ��Ze����g �g class-wp-rest-request.phpnu �[��� <?php /** * 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 behavior 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 * * @link https://www.php.net/manual/en/class.arrayaccess.php */ #[AllowDynamicProperties] class WP_REST_Request implements ArrayAccess { /** * HTTP method. * * @since 4.4.0 * @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 * @var array Contains GET, POST and FILES keys mapping to arrays of data. */ protected $params; /** * HTTP headers for the request. * * @since 4.4.0 * @var array Map of key to value. Key is always lowercase, as per HTTP specification. */ protected $headers = array(); /** * Body data. * * @since 4.4.0 * @var string Binary data from the request. */ protected $body = null; /** * Route matched for the request. * * @since 4.4.0 * @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 * @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 * @var bool */ protected $parsed_json = false; /** * Used to determine if the body data has been parsed yet. * * @since 4.4.0 * @var bool */ protected $parsed_body = false; /** * Constructor. * * @since 4.4.0 * * @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 * * @return string HTTP method. */ public function get_method() { return $this->method; } /** * Sets HTTP method for the request. * * @since 4.4.0 * * @param string $method HTTP method. */ public function set_method( $method ) { $this->method = strtoupper( $method ); } /** * Retrieves all headers from the request. * * @since 4.4.0 * * @return array Map of key to value. Key is always lowercase, as per HTTP specification. */ public function get_headers() { return $this->headers; } /** * Determines if the request is the given method. * * @since 6.8.0 * * @param string $method HTTP method. * @return bool Whether the request is of the given method. */ public function is_method( $method ) { return $this->get_method() === strtoupper( $method ); } /** * 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 https://stackoverflow.com/q/18185366 * @link https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#missing-disappearing-http-headers * @link https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers * * @since 4.4.0 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @return array|null Map containing 'value' and 'parameters' keys * or null when no valid Content-Type header was * available. */ 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 ( ! str_contains( $value, '/' ) ) { 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; } /** * Checks if the request has specified a JSON Content-Type. * * @since 5.6.0 * * @return bool True if the Content-Type header is JSON. */ public function is_json_content_type() { $content_type = $this->get_content_type(); return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] ); } /** * Retrieves the parameter priority order. * * Used when checking parameters in WP_REST_Request::get_param(). * * @since 4.4.0 * * @return string[] Array of types to check, in order of priority. */ protected function get_parameter_order() { $order = array(); if ( $this->is_json_content_type() ) { $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, true ) ) { $order[] = 'POST'; } $order[] = 'GET'; $order[] = 'URL'; $order[] = 'defaults'; /** * Filters the parameter priority order for a REST API request. * * The order affects which parameters are checked when using WP_REST_Request::get_param() * and family. This acts similarly to PHP's `request_order` setting. * * @since 4.4.0 * * @param string[] $order Array of types to check, in order of priority. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_request_parameter_order', $order, $this ); } /** * Retrieves a parameter from the request. * * @since 4.4.0 * * @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; } /** * Checks if a parameter exists in the request. * * This allows distinguishing between an omitted parameter, * and a parameter specifically set to null. * * @since 5.3.0 * * @param string $key Parameter name. * @return bool True if a param exists for the given key. */ public function has_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { return true; } } return false; } /** * Sets a parameter on the request. * * If the given parameter key exists in any parameter type an update will take place, * otherwise a new param will be created in the first parameter type (respecting * get_parameter_order()). * * @since 4.4.0 * * @param string $key Parameter name. * @param mixed $value Parameter value. */ public function set_param( $key, $value ) { $order = $this->get_parameter_order(); $found_key = false; foreach ( $order as $type ) { if ( 'defaults' !== $type && is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { $this->params[ $type ][ $key ] = $value; $found_key = true; } } if ( ! $found_key ) { $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 * * @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; } } // Exclude rest_route if pretty permalinks are not enabled. if ( ! get_option( 'permalink_structure' ) ) { unset( $params['rest_route'] ); } return $params; } /** * Retrieves parameters from the route itself. * * These are parsed from the URL using the regex. * * @since 4.4.0 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @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 * * @return string Binary data from the request body. */ public function get_body() { return $this->body; } /** * Sets body content. * * @since 4.4.0 * * @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 * * @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. * @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. if ( ! $this->is_json_content_type() ) { return true; } $body = $this->get_body(); if ( empty( $body ) ) { return true; } $params = json_decode( $body, true ); /* * Check for a parsing error. */ if ( null === $params && JSON_ERROR_NONE !== json_last_error() ) { // Ensure subsequent calls receive error instance. $this->parsed_json = false; $error_data = array( 'status' => WP_Http::BAD_REQUEST, 'json_error_code' => json_last_error(), '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. * * @since 4.4.0 */ 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 ); /* * 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 * * @return string Route matching regex. */ public function get_route() { return $this->route; } /** * Sets the route that matched the request. * * @since 4.4.0 * * @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 * * @return array Attributes for the request. */ public function get_attributes() { return $this->attributes; } /** * Sets the attributes for the request. * * @since 4.4.0 * * @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 * * @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(); $invalid_details = 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; } /** @var mixed|WP_Error $sanitized_value */ $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); if ( is_wp_error( $sanitized_value ) ) { $invalid_params[ $key ] = implode( ' ', $sanitized_value->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $sanitized_value )->get_data(); } else { $this->params[ $type ][ $key ] = $sanitized_value; } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: List of invalid parameters. */ sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } return true; } /** * Checks whether this request is valid according to its attributes. * * @since 4.4.0 * * @return true|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(); $args = empty( $attributes['args'] ) ? array() : $attributes['args']; foreach ( $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', /* translators: %s: List of required parameters. */ 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(); $invalid_details = array(); foreach ( $args as $key => $arg ) { $param = $this->get_param( $key ); if ( null !== $param && ! empty( $arg['validate_callback'] ) ) { /** @var bool|\WP_Error $valid_check */ $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 ] = implode( ' ', $valid_check->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $valid_check )->get_data(); } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: List of invalid parameters. */ sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } if ( isset( $attributes['validate_callback'] ) ) { $valid_check = call_user_func( $attributes['validate_callback'], $this ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } if ( false === $valid_check ) { // A WP_Error instance is preferred, but false is supported for parity with the per-arg validate_callback. return new WP_Error( 'rest_invalid_params', __( 'Invalid parameters.' ), array( 'status' => 400 ) ); } } return true; } /** * Checks if a parameter is set. * * @since 4.4.0 * * @param string $offset Parameter name. * @return bool Whether the parameter is set. */ #[ReturnTypeWillChange] 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 * * @param string $offset Parameter name. * @return mixed|null Value if set, null otherwise. */ #[ReturnTypeWillChange] public function offsetGet( $offset ) { return $this->get_param( $offset ); } /** * Sets a parameter on the request. * * @since 4.4.0 * * @param string $offset Parameter name. * @param mixed $value Parameter value. */ #[ReturnTypeWillChange] public function offsetSet( $offset, $value ) { $this->set_param( $offset, $value ); } /** * Removes a parameter from the request. * * @since 4.4.0 * * @param string $offset Parameter name. */ #[ReturnTypeWillChange] 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. * * @since 4.5.0 * * @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' ) && str_starts_with( $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 REST API 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 ); } } PK ��ZeX�� , search/class-wp-rest-term-search-handler.phpnu �[��� <?php /** * REST API: WP_REST_Term_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class representing a search handler for terms in the REST API. * * @since 5.6.0 * * @see WP_REST_Search_Handler */ class WP_REST_Term_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.6.0 */ public function __construct() { $this->type = 'term'; $this->subtypes = array_values( get_taxonomies( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ); } /** * Searches terms for a given search request. * * @since 5.6.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type int[] $ids Found term IDs. * @type string|int|WP_Error $total Numeric string containing the number of terms in that * taxonomy, 0 if there are no results, or WP_Error if * the requested taxonomy does not exist. * } */ public function search_items( WP_REST_Request $request ) { $taxonomies = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $taxonomies, true ) ) { $taxonomies = $this->subtypes; } $page = (int) $request['page']; $per_page = (int) $request['per_page']; $query_args = array( 'taxonomy' => $taxonomies, 'hide_empty' => false, 'offset' => ( $page - 1 ) * $per_page, 'number' => $per_page, ); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['exclude'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['include'] = $request['include']; } /** * Filters the query arguments for a REST API term search request. * * Enables adding extra arguments or setting defaults for a term search request. * * @since 5.6.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_term_search_query', $query_args, $request ); $query = new WP_Term_Query(); $found_terms = $query->query( $query_args ); $found_ids = wp_list_pluck( $found_terms, 'term_id' ); unset( $query_args['offset'], $query_args['number'] ); $total = wp_count_terms( $query_args ); // wp_count_terms() can return a falsey value when the term has no children. if ( ! $total ) { $total = 0; } return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } /** * Prepares the search result for a given term ID. * * @since 5.6.0 * * @param int $id Term ID. * @param array $fields Fields to include for the term. * @return array { * Associative array containing fields for the term based on the `$fields` parameter. * * @type int $id Optional. Term ID. * @type string $title Optional. Term name. * @type string $url Optional. Term permalink URL. * @type string $type Optional. Term taxonomy name. * } */ public function prepare_item( $id, array $fields ) { $term = get_term( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = $term->name; } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_term_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $term->taxonomy; } return $data; } /** * Prepares links for the search result of a given ID. * * @since 5.6.0 * * @param int $id Item ID. * @return array[] Array of link arrays for the given item. */ public function prepare_item_links( $id ) { $term = get_term( $id ); $links = array(); $item_route = rest_get_route_for_term( $term ); if ( $item_route ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $term->taxonomy ) ), ); return $links; } } PK ��Z:�Z Z 3 search/class-wp-rest-post-format-search-handler.phpnu �[��� <?php /** * REST API: WP_REST_Post_Format_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class representing a search handler for post formats in the REST API. * * @since 5.6.0 * * @see WP_REST_Search_Handler */ class WP_REST_Post_Format_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.6.0 */ public function __construct() { $this->type = 'post-format'; } /** * Searches the post formats for a given search request. * * @since 5.6.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type string[] $ids Array containing slugs for the matching post formats. * @type int $total Total count for the matching search results. * } */ public function search_items( WP_REST_Request $request ) { $format_strings = get_post_format_strings(); $format_slugs = array_keys( $format_strings ); $query_args = array(); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } /** * Filters the query arguments for a REST API post format search request. * * Enables adding extra arguments or setting defaults for a post format search request. * * @since 5.6.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_post_format_search_query', $query_args, $request ); $found_ids = array(); foreach ( $format_slugs as $format_slug ) { if ( ! empty( $query_args['search'] ) ) { $format_string = get_post_format_string( $format_slug ); $format_slug_match = stripos( $format_slug, $query_args['search'] ) !== false; $format_string_match = stripos( $format_string, $query_args['search'] ) !== false; if ( ! $format_slug_match && ! $format_string_match ) { continue; } } $format_link = get_post_format_link( $format_slug ); if ( $format_link ) { $found_ids[] = $format_slug; } } $page = (int) $request['page']; $per_page = (int) $request['per_page']; return array( self::RESULT_IDS => array_slice( $found_ids, ( $page - 1 ) * $per_page, $per_page ), self::RESULT_TOTAL => count( $found_ids ), ); } /** * Prepares the search result for a given post format. * * @since 5.6.0 * * @param string $id Item ID, the post format slug. * @param array $fields Fields to include for the item. * @return array { * Associative array containing fields for the post format based on the `$fields` parameter. * * @type string $id Optional. Post format slug. * @type string $title Optional. Post format name. * @type string $url Optional. Post format permalink URL. * @type string $type Optional. String 'post-format'. *} */ public function prepare_item( $id, array $fields ) { $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_post_format_string( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_format_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } return $data; } /** * Prepares links for the search result. * * @since 5.6.0 * * @param string $id Item ID, the post format slug. * @return array Links for the given item. */ public function prepare_item_links( $id ) { return array(); } } PK ��Z�?�� � , search/class-wp-rest-post-search-handler.phpnu �[��� <?php /** * REST API: WP_REST_Post_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core class representing a search handler for posts in the REST API. * * @since 5.0.0 * * @see WP_REST_Search_Handler */ class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.0.0 */ public function __construct() { $this->type = 'post'; // Support all public post types except attachments. $this->subtypes = array_diff( array_values( get_post_types( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ), array( 'attachment' ) ); } /** * Searches posts for a given search request. * * @since 5.0.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type int[] $ids Array containing the matching post IDs. * @type int $total Total count for the matching search results. * } */ public function search_items( WP_REST_Request $request ) { // Get the post types to search for the current request. $post_types = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $post_types, true ) ) { $post_types = $this->subtypes; } $query_args = array( 'post_type' => $post_types, 'post_status' => 'publish', 'paged' => (int) $request['page'], 'posts_per_page' => (int) $request['per_page'], 'ignore_sticky_posts' => true, ); if ( ! empty( $request['search'] ) ) { $query_args['s'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['post__not_in'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['post__in'] = $request['include']; } /** * Filters the query arguments for a REST API post search request. * * Enables adding extra arguments or setting defaults for a post search request. * * @since 5.1.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_post_search_query', $query_args, $request ); $query = new WP_Query(); $posts = $query->query( $query_args ); // Querying the whole post object will warm the object cache, avoiding an extra query per result. $found_ids = wp_list_pluck( $posts, 'ID' ); $total = $query->found_posts; return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } /** * Prepares the search result for a given post ID. * * @since 5.0.0 * * @param int $id Post ID. * @param array $fields Fields to include for the post. * @return array { * Associative array containing fields for the post based on the `$fields` parameter. * * @type int $id Optional. Post ID. * @type string $title Optional. Post title. * @type string $url Optional. Post permalink URL. * @type string $type Optional. Post type. * } */ public function prepare_item( $id, array $fields ) { $post = get_post( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $post->ID; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { if ( post_type_supports( $post->post_type, 'title' ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } else { $data[ WP_REST_Search_Controller::PROP_TITLE ] = ''; } } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_permalink( $post->ID ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } if ( in_array( WP_REST_Search_Controller::PROP_SUBTYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_SUBTYPE ] = $post->post_type; } return $data; } /** * Prepares links for the search result of a given ID. * * @since 5.0.0 * * @param int $id Item ID. * @return array Links for the given item. */ public function prepare_item_links( $id ) { $post = get_post( $id ); $links = array(); $item_route = rest_get_route_for_post( $post ); if ( ! empty( $item_route ) ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( 'wp/v2/types/' . $post->post_type ), ); return $links; } /** * Overwrites the default protected and private title format. * * By default, WordPress will show password protected or private posts with a title of * "Protected: %s" or "Private: %s", as the REST API communicates the status of a post * in a machine-readable format, we remove the prefix. * * @since 5.0.0 * * @return string Title format. */ public function protected_title_format() { return '%s'; } /** * Attempts to detect the route to access a single item. * * @since 5.0.0 * @deprecated 5.5.0 Use rest_get_route_for_post() * @see rest_get_route_for_post() * * @param WP_Post $post Post object. * @return string REST route relative to the REST base URI, or empty string if unknown. */ protected function detect_rest_item_route( $post ) { _deprecated_function( __METHOD__, '5.5.0', 'rest_get_route_for_post()' ); return rest_get_route_for_post( $post ); } } PK ��Z��p�� � '