246 lines
7.1 KiB
PHP
246 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace SiteSync;
|
|
|
|
use WP_Error;
|
|
use WP_REST_Request;
|
|
use WP_REST_Response;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* REST controller for Site Sync plugin.
|
|
*
|
|
* Handles REST API endpoints for synchronization, media, and authentication.
|
|
*/
|
|
class REST_Controller {
|
|
private const ROUTE_NAMESPACE = 'site-sync/v1';
|
|
|
|
/**
|
|
* Settings instance.
|
|
*
|
|
* @var Settings
|
|
*/
|
|
private $settings;
|
|
|
|
/**
|
|
* Sync_Engine instance.
|
|
*
|
|
* @var Sync_Engine
|
|
*/
|
|
private $engine;
|
|
|
|
/**
|
|
* REST_Controller constructor.
|
|
*
|
|
* @param Settings $settings Settings instance.
|
|
* @param Sync_Engine $engine Sync_Engine instance.
|
|
*/
|
|
public function __construct( Settings $settings, Sync_Engine $engine ) {
|
|
$this->settings = $settings;
|
|
$this->engine = $engine;
|
|
}
|
|
|
|
/**
|
|
* Registers REST API hooks for the Site Sync plugin.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function hooks(): void {
|
|
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
|
|
}
|
|
|
|
/**
|
|
* Registers all REST API routes for the Site Sync plugin.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register_routes(): void {
|
|
register_rest_route(
|
|
self::ROUTE_NAMESPACE,
|
|
'/handshake',
|
|
array(
|
|
'methods' => 'GET',
|
|
'callback' => array( $this, 'handshake' ),
|
|
'permission_callback' => '__return_true',
|
|
)
|
|
);
|
|
|
|
register_rest_route(
|
|
self::ROUTE_NAMESPACE,
|
|
'/inbox',
|
|
array(
|
|
'methods' => 'POST',
|
|
'callback' => array( $this, 'receive_inbox' ),
|
|
'permission_callback' => array( $this, 'check_auth' ),
|
|
)
|
|
);
|
|
|
|
register_rest_route(
|
|
self::ROUTE_NAMESPACE,
|
|
'/outbox',
|
|
array(
|
|
'methods' => 'GET',
|
|
'callback' => array( $this, 'send_outbox' ),
|
|
'permission_callback' => array( $this, 'check_auth' ),
|
|
)
|
|
);
|
|
|
|
register_rest_route(
|
|
self::ROUTE_NAMESPACE,
|
|
'/media',
|
|
array(
|
|
'methods' => 'POST',
|
|
'callback' => array( $this, 'handle_media' ),
|
|
'permission_callback' => array( $this, 'check_auth' ),
|
|
'args' => array(
|
|
'external_id' => array(
|
|
'required' => true,
|
|
'type' => 'string',
|
|
),
|
|
'mime_type' => array(
|
|
'required' => true,
|
|
'type' => 'string',
|
|
),
|
|
'filename' => array(
|
|
'required' => false,
|
|
'type' => 'string',
|
|
),
|
|
),
|
|
)
|
|
);
|
|
|
|
register_rest_route(
|
|
self::ROUTE_NAMESPACE,
|
|
'/media',
|
|
array(
|
|
'methods' => 'GET',
|
|
'callback' => array( $this, 'send_media' ),
|
|
'permission_callback' => array( $this, 'check_auth' ),
|
|
'args' => array(
|
|
'external_id' => array(
|
|
'required' => true,
|
|
'type' => 'string',
|
|
),
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handles the handshake endpoint for the Site Sync plugin.
|
|
*
|
|
* Returns basic site and plugin information for synchronization.
|
|
*
|
|
* @return WP_REST_Response
|
|
*/
|
|
public function handshake() {
|
|
$settings = $this->settings->ensure_defaults();
|
|
|
|
return new WP_REST_Response(
|
|
array(
|
|
'site_uuid' => $settings['site_uuid'],
|
|
'schema' => 'v1',
|
|
'site_url' => home_url(),
|
|
'version' => SITE_SYNC_VERSION,
|
|
'capabilities' => array(
|
|
'content' => true,
|
|
'taxonomies' => true,
|
|
'media' => true,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handles the inbox endpoint for receiving synchronization payloads.
|
|
*
|
|
* @param WP_REST_Request $request The REST request object containing the payload.
|
|
* @return WP_REST_Response The response after processing the inbox payload.
|
|
*/
|
|
public function receive_inbox( WP_REST_Request $request ) {
|
|
$payload = $request->get_json_params() ? $request->get_json_params() : array();
|
|
$result = $this->engine->handle_inbox( $payload );
|
|
|
|
return new WP_REST_Response( $result );
|
|
}
|
|
|
|
/**
|
|
* Handles the outbox endpoint for sending synchronization payloads.
|
|
*
|
|
* @return WP_REST_Response The response containing the outbox payload.
|
|
*/
|
|
public function send_outbox() {
|
|
$result = $this->engine->provide_outbox( true );
|
|
$this->engine->commit_outbox( $result['cursor'], $result['meta']['counts'] ?? array() );
|
|
|
|
if ( isset( $result['meta'] ) ) {
|
|
unset( $result['meta'] );
|
|
}
|
|
|
|
return new WP_REST_Response( $result );
|
|
}
|
|
|
|
/**
|
|
* Handles the media endpoint for receiving and storing media files.
|
|
*
|
|
* @param WP_REST_Request $request The REST request object containing media data.
|
|
* @return WP_REST_Response|WP_Error The response after processing the media upload or WP_Error on failure.
|
|
*/
|
|
public function handle_media( WP_REST_Request $request ) {
|
|
$result = $this->engine->receive_media_stream( $request );
|
|
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
|
|
return new WP_REST_Response(
|
|
array(
|
|
'status' => 'ok',
|
|
'stored' => $result,
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handles the media endpoint for sending media files.
|
|
*
|
|
* @param WP_REST_Request $request The REST request object containing the external_id parameter.
|
|
* @return WP_REST_Response|WP_Error The response containing the media file or WP_Error on failure.
|
|
*/
|
|
public function send_media( WP_REST_Request $request ) {
|
|
$externalId = $request->get_param( 'external_id' );
|
|
$media = $this->engine->get_media_file( $externalId );
|
|
|
|
if ( is_wp_error( $media ) ) {
|
|
return $media;
|
|
}
|
|
|
|
$response = new WP_REST_Response( $media['contents'] );
|
|
$response->set_status( 200 );
|
|
$response->header( 'Content-Type', $media['mime'] );
|
|
$response->header( 'Content-Disposition', 'attachment; filename="' . $media['filename'] . '"' );
|
|
$response->header( 'X-Site-Sync-Checksum', $media['checksum'] );
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Checks authentication for REST API requests.
|
|
*
|
|
* @param WP_REST_Request $request The REST request object.
|
|
* @return true|WP_Error True if authentication passes, WP_Error otherwise.
|
|
*/
|
|
public function check_auth( WP_REST_Request $request ) {
|
|
$result = Auth::verify( $request, $this->settings );
|
|
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|