201 lines
5.3 KiB
PHP
201 lines
5.3 KiB
PHP
<?php
|
|
/**
|
|
* Class WC_REST_Payments_Files_Controller
|
|
*
|
|
* @package WooCommerce\Payments\Admin
|
|
*/
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* REST controller for files.
|
|
*/
|
|
class WC_REST_Payments_Files_Controller extends WC_Payments_REST_Controller {
|
|
|
|
/**
|
|
* Endpoint path.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $rest_base = 'payments/file';
|
|
|
|
/**
|
|
* Configure REST API routes.
|
|
*/
|
|
public function register_routes() {
|
|
register_rest_route(
|
|
$this->namespace,
|
|
'/' . $this->rest_base,
|
|
[
|
|
'methods' => WP_REST_Server::CREATABLE,
|
|
'callback' => [ $this, 'upload_file' ],
|
|
'permission_callback' => [ $this, 'check_permission' ],
|
|
]
|
|
);
|
|
|
|
register_rest_route(
|
|
$this->namespace,
|
|
'/' . $this->rest_base . '/(?P<file_id>\w+)/details',
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [ $this, 'get_file_detail' ],
|
|
'permission_callback' => [ $this, 'check_permission' ],
|
|
]
|
|
);
|
|
|
|
register_rest_route(
|
|
$this->namespace,
|
|
'/' . $this->rest_base . '/(?P<file_id>\w+)/content',
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [ $this, 'get_file_content' ],
|
|
'permission_callback' => [ $this, 'check_permission' ],
|
|
]
|
|
);
|
|
|
|
register_rest_route(
|
|
$this->namespace,
|
|
'/' . $this->rest_base . '/(?P<file_id>\w+)',
|
|
[
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => [ $this, 'get_file' ],
|
|
'permission_callback' => [],
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create file and respond with file object via API.
|
|
*
|
|
* @param WP_REST_Request $request Full data about the request.
|
|
*/
|
|
public function upload_file( $request ) {
|
|
return $this->forward_request( 'upload_file', [ $request ] );
|
|
}
|
|
|
|
/**
|
|
* Retrieve a file content via API.
|
|
*
|
|
* @param WP_REST_Request $request - request object.
|
|
*
|
|
* @return WP_Error|WP_HTTP_Response
|
|
*/
|
|
public function get_file( WP_REST_Request $request ) {
|
|
$file_id = $request->get_param( 'file_id' );
|
|
$as_account = (bool) $request->get_param( 'as_account' );
|
|
|
|
$file_service = new WC_Payments_File_Service();
|
|
$purpose = get_transient( WC_Payments_File_Service::CACHE_KEY_PREFIX_PURPOSE . $file_id . '_' . ( $as_account ? '1' : '0' ) );
|
|
|
|
if ( ! $purpose ) {
|
|
$file = $this->forward_request( 'get_file', [ $file_id, $as_account ] );
|
|
|
|
if ( is_wp_error( $file ) ) {
|
|
return $this->file_error_response( $file );
|
|
}
|
|
$purpose = $file->get_data()['purpose'];
|
|
set_transient( WC_Payments_File_Service::CACHE_KEY_PREFIX_PURPOSE . $file_id, $purpose, WC_Payments_File_Service::CACHE_PERIOD );
|
|
}
|
|
|
|
if ( ! $file_service->is_file_public( $purpose ) && ! $this->check_permission() ) {
|
|
return new WP_Error(
|
|
'rest_forbidden',
|
|
__( 'Sorry, you are not allowed to do that.', 'woocommerce-payments' ),
|
|
[ 'status' => rest_authorization_required_code() ]
|
|
);
|
|
}
|
|
|
|
$result = $this->forward_request( 'get_file_contents', [ $file_id, $as_account ] );
|
|
|
|
if ( is_wp_error( $result ) ) {
|
|
return $this->file_error_response( $result );
|
|
}
|
|
|
|
/**
|
|
* WP_REST_Server will convert the response data to JSON prior to output it.
|
|
* Using this filter to prevent it, and output the data from WP_HTTP_Response instead.
|
|
*/
|
|
add_filter(
|
|
'rest_pre_serve_request',
|
|
function ( bool $served, WP_HTTP_Response $response ): bool {
|
|
echo $response->get_data(); // @codingStandardsIgnoreLine
|
|
return true;
|
|
},
|
|
10,
|
|
2
|
|
);
|
|
|
|
return new WP_HTTP_Response(
|
|
base64_decode( $result->get_data()['file_content'] ), // @codingStandardsIgnoreLine
|
|
200,
|
|
[
|
|
'Content-Type' => $result->get_data()['content_type'],
|
|
'Content-Disposition' => 'inline',
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Retrieve file details via the API.
|
|
*
|
|
* Example response:
|
|
* {
|
|
* "id": "file_1Np1S5J5cIRIG92xknlr0iND",
|
|
* "object": "file",
|
|
* "created": 1694405421,
|
|
* "expires_at": 1717733421,
|
|
* "filename": "Screenshot 2023-09-04 at 5.08.31\u202fPM.png",
|
|
* "purpose": "dispute_evidence",
|
|
* "size": 21444,
|
|
* "title": null,
|
|
* "type": "png",
|
|
* }
|
|
*
|
|
* @param WP_REST_Request $request Full data about the request.
|
|
*
|
|
* @return mixed|WP_Error
|
|
*/
|
|
public function get_file_detail( WP_REST_Request $request ) {
|
|
$file_id = $request->get_param( 'file_id' );
|
|
$as_account = (bool) $request->get_param( 'as_account' );
|
|
|
|
return $this->forward_request( 'get_file', [ $file_id, $as_account ] );
|
|
}
|
|
|
|
/**
|
|
* Retrieve file contents via the API as a base64 encoded string.
|
|
*
|
|
* Example response:
|
|
* {
|
|
* "content_type": "image\/png",
|
|
* "file_content": "iVBORw.......",
|
|
* }
|
|
*
|
|
* @param WP_REST_Request $request Full data about the request.
|
|
*
|
|
* @return mixed|WP_Error
|
|
*/
|
|
public function get_file_content( WP_REST_Request $request ) {
|
|
$file_id = $request->get_param( 'file_id' );
|
|
$as_account = (bool) $request->get_param( 'as_account' );
|
|
|
|
return $this->forward_request( 'get_file_contents', [ $file_id, $as_account ] );
|
|
}
|
|
|
|
/**
|
|
* Convert error response
|
|
*
|
|
* @param WP_Error $error - error.
|
|
*
|
|
* @return WP_Error
|
|
*/
|
|
private function file_error_response( WP_Error $error ): WP_Error {
|
|
$error_status_code = 'resource_missing' === $error->get_error_code() ? WP_Http::NOT_FOUND : WP_Http::INTERNAL_SERVER_ERROR;
|
|
return new WP_Error(
|
|
$error->get_error_code(),
|
|
$error->get_error_message(),
|
|
[ 'status' => $error_status_code ]
|
|
);
|
|
}
|
|
}
|