This commit is contained in:
Javier Casares 2026-02-19 11:15:55 +00:00
commit f7702f2872
25 changed files with 6453 additions and 0 deletions

View file

@ -0,0 +1,209 @@
<?php
/**
* REST API Class
*
* Registers and handles REST API endpoints for OpenGraph image fallback.
*
* @package ROBOTSTXT_OG
* @since 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class Robotstxt_OG_REST_API
*
* Provides REST API endpoints for the OpenGraph plugin.
*
* @since 1.0.0
*/
class Robotstxt_OG_REST_API {
/**
* REST API namespace.
*
* @since 1.0.0
* @var string
*/
const NAMESPACE = 'robotstxt-og/v1';
/**
* Image resolver instance.
*
* @since 1.0.0
* @var Robotstxt_OG_Image_Resolver
*/
private Robotstxt_OG_Image_Resolver $resolver;
/**
* Constructor.
*
* @since 1.0.0
*
* @param Robotstxt_OG_Image_Resolver $resolver Image resolver instance.
*/
public function __construct( Robotstxt_OG_Image_Resolver $resolver ) {
$this->resolver = $resolver;
}
/**
* Initialize REST API hooks.
*
* @since 1.0.0
*
* @return void
*/
public function init(): void {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
/**
* Register REST API routes.
*
* @since 1.0.0
*
* @return void
*/
public function register_routes(): void {
// Resolve endpoint: force re-resolve a post's fallback image.
register_rest_route(
self::NAMESPACE,
'/resolve/(?P<post_id>[\d]+)',
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'handle_resolve' ),
'permission_callback' => array( $this, 'check_permission' ),
'args' => array(
'post_id' => array(
'required' => true,
'validate_callback' => function ( $value ) {
return is_numeric( $value ) && (int) $value > 0;
},
'sanitize_callback' => 'absint',
'description' => __( 'The post ID to resolve the fallback image for.', 'robotstxt-og' ),
),
),
)
);
// Status endpoint: get current cached status for a post.
register_rest_route(
self::NAMESPACE,
'/status/(?P<post_id>[\d]+)',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'handle_status' ),
'permission_callback' => array( $this, 'check_permission' ),
'args' => array(
'post_id' => array(
'required' => true,
'validate_callback' => function ( $value ) {
return is_numeric( $value ) && (int) $value > 0;
},
'sanitize_callback' => 'absint',
'description' => __( 'The post ID to get the fallback image status for.', 'robotstxt-og' ),
),
),
)
);
}
/**
* Handle the resolve endpoint.
*
* Forces re-resolution of the fallback image for the specified post.
*
* @since 1.0.0
*
* @param WP_REST_Request $request REST request object.
* @return WP_REST_Response|WP_Error Response object.
*/
public function handle_resolve( WP_REST_Request $request ) {
$post_id = (int) $request->get_param( 'post_id' );
// Verify post exists.
$post = get_post( $post_id );
if ( ! $post ) {
return new WP_Error(
'post_not_found',
__( 'Post not found.', 'robotstxt-og' ),
array( 'status' => 404 )
);
}
// Clear existing cache and resolve.
$this->resolver->clear_cache( $post_id );
$resolved_url = $this->resolver->resolve_image( $post_id );
$data = array(
'post_id' => $post_id,
'resolved_url' => $resolved_url,
'cached' => ! empty( get_post_meta( $post_id, '_og_image_fallback_url', true ) ),
'success' => ! empty( $resolved_url ),
);
return new WP_REST_Response( $data, 200 );
}
/**
* Handle the status endpoint.
*
* Returns the current cached fallback image status for a post.
*
* @since 1.0.0
*
* @param WP_REST_Request $request REST request object.
* @return WP_REST_Response|WP_Error Response object.
*/
public function handle_status( WP_REST_Request $request ) {
$post_id = (int) $request->get_param( 'post_id' );
// Verify post exists.
$post = get_post( $post_id );
if ( ! $post ) {
return new WP_Error(
'post_not_found',
__( 'Post not found.', 'robotstxt-og' ),
array( 'status' => 404 )
);
}
$cached_url = get_post_meta( $post_id, '_og_image_fallback_url', true );
$thumbnail_id = get_post_thumbnail_id( $post_id );
$original_url = $thumbnail_id ? wp_get_attachment_url( $thumbnail_id ) : '';
$data = array(
'post_id' => $post_id,
'cached_url' => $cached_url,
'original_url' => $original_url,
'has_cache' => ! empty( $cached_url ),
);
return new WP_REST_Response( $data, 200 );
}
/**
* Check REST API permission.
*
* Requires manage_options capability.
*
* @since 1.0.0
*
* @return bool|WP_Error True if authorized, WP_Error otherwise.
*/
public function check_permission() {
if ( ! current_user_can( 'manage_options' ) ) {
return new WP_Error(
'rest_forbidden',
__( 'You do not have permission to access this endpoint.', 'robotstxt-og' ),
array( 'status' => 403 )
);
}
return true;
}
}