240 lines
6.6 KiB
PHP
240 lines
6.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Register custom REST API routes.
|
|
*/
|
|
add_action(
|
|
'rest_api_init',
|
|
function () {
|
|
// Define API endpoint arguments
|
|
$slug_arg = [
|
|
'validate_callback' => function ( $param, $request, $key ) {
|
|
return( is_string( $param ) );
|
|
}
|
|
,
|
|
];
|
|
$post_slug_arg = array_merge(
|
|
$slug_arg,
|
|
[
|
|
'description' => 'String representing a valid WordPress post slug',
|
|
]
|
|
);
|
|
$page_slug_arg = array_merge(
|
|
$slug_arg,
|
|
[
|
|
'description' => 'String representing a valid WordPress page slug',
|
|
]
|
|
);
|
|
|
|
// Register routes
|
|
register_rest_route( 'api/v1', '/post', [
|
|
'methods' => 'GET',
|
|
'callback' => 'rest_get_post',
|
|
'args' => [
|
|
'slug' => array_merge(
|
|
$post_slug_arg,
|
|
[
|
|
'required' => true,
|
|
]
|
|
),
|
|
],
|
|
] );
|
|
|
|
register_rest_route( 'api/v1', '/page', [
|
|
'methods' => 'GET',
|
|
'callback' => 'rest_get_page',
|
|
'args' => [
|
|
'slug' => array_merge(
|
|
$page_slug_arg,
|
|
[
|
|
'required' => true,
|
|
]
|
|
),
|
|
],
|
|
] );
|
|
|
|
register_rest_route('api/v1', '/post/preview', [
|
|
'methods' => 'GET',
|
|
'callback' => 'rest_get_post_preview',
|
|
'args' => [
|
|
'id' => [
|
|
'validate_callback' => function ( $param, $request, $key ) {
|
|
return ( is_numeric( $param ) );
|
|
}
|
|
,
|
|
'required' => true,
|
|
'description' => 'Valid WordPress post ID',
|
|
],
|
|
],
|
|
'permission_callback' => function () {
|
|
return current_user_can( 'edit_posts' );
|
|
}
|
|
,
|
|
] );
|
|
}
|
|
);
|
|
|
|
|
|
/**
|
|
* Respond to a REST API request to get post data.
|
|
*
|
|
* @param WP_REST_Request $request Request.
|
|
* @return WP_REST_Response
|
|
*/
|
|
function rest_get_post( WP_REST_Request $request ) {
|
|
return rest_get_content( $request, 'post', __FUNCTION__ );
|
|
}
|
|
|
|
|
|
/**
|
|
* Respond to a REST API request to get page data.
|
|
*
|
|
* @param WP_REST_Request $request Request.
|
|
* @return WP_REST_Response
|
|
*/
|
|
function rest_get_page( WP_REST_Request $request ) {
|
|
return rest_get_content( $request, 'page', __FUNCTION__ );
|
|
}
|
|
|
|
|
|
/**
|
|
* Respond to a REST API request to get post or page data.
|
|
* * Handles changed slugs
|
|
* * Doesn't return posts whose status isn't published
|
|
* * Redirects to the admin when an edit parameter is present
|
|
*
|
|
* @param WP_REST_Request $request Request
|
|
* @param str $type Type
|
|
* @param str $function_name Function name
|
|
* @return WP_REST_Response
|
|
*/
|
|
function rest_get_content( WP_REST_Request $request, $type, $function_name ) {
|
|
$content_in_array = in_array(
|
|
$type,
|
|
[
|
|
'post',
|
|
'page',
|
|
],
|
|
true
|
|
);
|
|
if ( ! $content_in_array ) {
|
|
$type = 'post';
|
|
}
|
|
$slug = $request->get_param( 'slug' );
|
|
$post = get_content_by_slug( $slug, $type );
|
|
if ( ! $post ) {
|
|
return new WP_Error(
|
|
$function_name,
|
|
$slug . ' ' . $type . ' does not exist',
|
|
[
|
|
'status' => 404,
|
|
]
|
|
);
|
|
}
|
|
;
|
|
|
|
// Shortcut to WP admin page editor
|
|
$edit = $request->get_param( 'edit' );
|
|
if ( 'true' === $edit ) {
|
|
header( 'Location: /wp-admin/post.php?post=' . $post->ID . '&action=edit' );
|
|
exit;
|
|
}
|
|
$controller = new WP_REST_Posts_Controller( 'post' );
|
|
$data = $controller->prepare_item_for_response( $post, $request );
|
|
$response = $controller->prepare_response_for_collection( $data );
|
|
|
|
return new WP_REST_Response( $response );
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns a post or page given a slug. Returns false if no post matches.
|
|
*
|
|
* @param str $slug Slug
|
|
* @param str $type Valid values are 'post' or 'page'
|
|
* @return Post
|
|
*/
|
|
function get_content_by_slug( $slug, $type = 'post' ) {
|
|
$content_in_array = in_array(
|
|
$type,
|
|
[
|
|
'post',
|
|
'page',
|
|
],
|
|
true
|
|
);
|
|
if ( ! $content_in_array ) {
|
|
$type = 'post';
|
|
}
|
|
$args = [
|
|
'name' => $slug,
|
|
'post_type' => $type,
|
|
'post_status' => 'publish',
|
|
'numberposts' => 1,
|
|
];
|
|
|
|
// phpcs:ignore WordPress.VIP.RestrictedFunctions.get_posts_get_posts
|
|
$post_search_results = get_posts( $args );
|
|
|
|
if ( !$post_search_results ) {
|
|
// Maybe the slug changed
|
|
// check wp_postmeta table for old slug
|
|
$args = [
|
|
// phpcs:ignore WordPress.VIP.SlowDBQuery.slow_db_query_meta_query
|
|
'meta_query' => [
|
|
[
|
|
'key' => '_wp_old_slug',
|
|
'value' => $post_slug,
|
|
'compare' => '=',
|
|
],
|
|
],
|
|
];
|
|
$query = new WP_Query( $args );
|
|
$post_search_results = $query->posts;
|
|
}
|
|
if ( isset( $post_search_results[0] ) ) {
|
|
return $post_search_results[0];
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Respond to a REST API request to get a post's latest revision.
|
|
* * Requires a valid _wpnonce on the query string
|
|
* * User must have 'edit_posts' rights
|
|
* * Will return draft revisions of even published posts
|
|
*
|
|
* @param WP_REST_Request $request Rest request.
|
|
* @return WP_REST_Response
|
|
*/
|
|
function rest_get_post_preview( WP_REST_Request $request ) {
|
|
$post_id = $request->get_param( 'id' );
|
|
// Revisions are drafts so here we remove the default 'publish' status
|
|
remove_action( 'pre_get_posts', 'set_default_status_to_publish' );
|
|
$check_enabled = [
|
|
'check_enabled' => false,
|
|
];
|
|
if ( $revisions = wp_get_post_revisions( $post_id, $check_enabled ) ) {
|
|
$last_revision = reset( $revisions );
|
|
$rev_post = wp_get_post_revision( $last_revision->ID );
|
|
$controller = new WP_REST_Posts_Controller( 'post' );
|
|
$data = $controller->prepare_item_for_response( $rev_post, $request );
|
|
} elseif ( $post = get_post( $post_id ) ) { // There are no revisions, just return the saved parent post
|
|
$controller = new WP_REST_Posts_Controller( 'post' );
|
|
$data = $controller->prepare_item_for_response( $post, $request );
|
|
} else {
|
|
$not_found = [
|
|
'status' => 404,
|
|
];
|
|
$error = new WP_Error(
|
|
'rest_get_post_preview',
|
|
'Post ' . $post_id . ' does not exist',
|
|
$not_found
|
|
);
|
|
return $error;
|
|
}
|
|
$response = $controller->prepare_response_for_collection( $data );
|
|
return new WP_REST_Response( $response );
|
|
}
|