feat: add rest transport client
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* REST package transport client.
|
||||
*
|
||||
* @package WPContentSync
|
||||
*/
|
||||
|
||||
namespace WPContentSync\Transport;
|
||||
|
||||
use WPContentSync\Package\ContentPackage;
|
||||
|
||||
final class RestTransportClient {
|
||||
public function testConnection( string $base_url, string $username, string $application_password ): bool {
|
||||
$response = wp_remote_get(
|
||||
$this->endpoint( $base_url, 'status' ),
|
||||
$this->requestArgs( $username, $application_password )
|
||||
);
|
||||
|
||||
$this->assertSuccessfulResponse( $response, 200 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function sendPackage( string $base_url, string $username, string $application_password, ContentPackage $package ): bool {
|
||||
$body = wp_json_encode( array( 'package' => $package->toArray() ) );
|
||||
|
||||
if ( false === $body ) {
|
||||
throw RestTransportException::remoteRejected( 'Unable to encode REST package payload.' );
|
||||
}
|
||||
|
||||
$args = $this->requestArgs( $username, $application_password );
|
||||
$args['body'] = $body;
|
||||
$args['headers']['Content-Type'] = 'application/json';
|
||||
|
||||
$response = wp_remote_post( $this->endpoint( $base_url, 'package' ), $args );
|
||||
|
||||
$this->assertSuccessfulResponse( $response, 200 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function endpoint( string $base_url, string $route ): string {
|
||||
return rtrim( $base_url, '/' ) . '/wp-json/wp-content-sync/v1/' . ltrim( $route, '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function requestArgs( string $username, string $application_password ): array {
|
||||
return array(
|
||||
'timeout' => 15,
|
||||
'headers' => array(
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Basic auth requires base64-encoded username:application-password credentials.
|
||||
'Authorization' => 'Basic ' . base64_encode( $username . ':' . $application_password ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $response HTTP response.
|
||||
*/
|
||||
private function assertSuccessfulResponse( $response, int $expected_code ): void {
|
||||
if ( is_wp_error( $response ) ) {
|
||||
throw RestTransportException::connectionFailed( $response->get_error_message() );
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code( $response );
|
||||
|
||||
if ( 401 === $status_code || 403 === $status_code ) {
|
||||
throw RestTransportException::authenticationFailed( 'REST authentication failed.' );
|
||||
}
|
||||
|
||||
if ( $expected_code !== $status_code ) {
|
||||
throw RestTransportException::remoteRejected( $this->responseMessage( $response ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $response HTTP response.
|
||||
*/
|
||||
private function responseMessage( array $response ): string {
|
||||
$body = wp_remote_retrieve_body( $response );
|
||||
$decoded = json_decode( $body, true );
|
||||
|
||||
if ( is_array( $decoded ) && isset( $decoded['message'] ) && is_string( $decoded['message'] ) ) {
|
||||
return $decoded['message'];
|
||||
}
|
||||
|
||||
return 'REST transport request failed.';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user