190 lines
4.7 KiB
PHP
190 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace WPML\TM\ATE;
|
|
|
|
class Proxy extends \WPML_REST_Base {
|
|
/**
|
|
* @var \WPML_TM_ATE_AMS_Endpoints
|
|
*/
|
|
private $endpoints;
|
|
|
|
public function __construct( \WPML_TM_ATE_AMS_Endpoints $endpoints ) {
|
|
parent::__construct( 'wpml/ate/v1' );
|
|
|
|
$this->endpoints = $endpoints;
|
|
}
|
|
|
|
public function add_hooks() {
|
|
$this->register_routes();
|
|
}
|
|
|
|
public function register_routes() {
|
|
parent::register_route(
|
|
'/ate/proxy',
|
|
array(
|
|
'methods' => \WP_REST_Server::ALLMETHODS,
|
|
'callback' => [ $this, 'proxy' ],
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param \WP_REST_Request $request
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_args( \WP_REST_Request $request ) {
|
|
$request_params = $this->get_request_params( $request );
|
|
|
|
$url = $request_params['url'];
|
|
$headers = $request_params['headers'];
|
|
$query = $request_params['query'];
|
|
$content_type = $request_params['content_type'];
|
|
|
|
if ( $content_type ) {
|
|
if ( ! $headers ) {
|
|
$headers = [];
|
|
}
|
|
$headers[] = 'Content-Type: ' . $content_type;
|
|
}
|
|
|
|
$args = [
|
|
'method' => $request_params['method'],
|
|
'headers' => $headers,
|
|
];
|
|
|
|
$body = $request_params['body'];
|
|
if ( $body ) {
|
|
$args['body'] = $body;
|
|
}
|
|
|
|
return [ $url, $query, $args, $content_type ];
|
|
}
|
|
|
|
/**
|
|
* @param \WP_REST_Request $request
|
|
*
|
|
* @return true|\WP_Error
|
|
*/
|
|
private function validate_request( \WP_REST_Request $request ) {
|
|
if ( ! $this->get_request_params( $request ) ) {
|
|
return new \WP_Error( 'endpoint_without_parameters', 'Endpoint called with no parameters.', [ 'status' => 400 ] );
|
|
}
|
|
|
|
list( $url, , $args ) = $this->get_args( $request );
|
|
|
|
$has_all_required_parameters = $url && $args['method'] && $args['headers'];
|
|
if ( ! $has_all_required_parameters ) {
|
|
return new \WP_Error( 'missing_required_parameters', 'Required parameters missing.', [ 'status' => 400 ] );
|
|
}
|
|
|
|
if ( \strtolower( $request->get_method() ) !== \strtolower( $args['method'] ) ) {
|
|
return new \WP_Error( 'invalid_method', 'Invalid method.', [ 'status' => 400 ] );
|
|
}
|
|
|
|
$ateBaseUrl = $this->endpoints->get_base_url( \WPML_TM_ATE_AMS_Endpoints::SERVICE_ATE );
|
|
$amsBaseUrl = $this->endpoints->get_base_url( \WPML_TM_ATE_AMS_Endpoints::SERVICE_AMS );
|
|
|
|
if ( \strpos( \strtolower( $url ), $ateBaseUrl ) !== 0 && \strpos( \strtolower( $url ), $amsBaseUrl ) !== 0 ) {
|
|
return new \WP_Error( 'invalid_url', 'Invalid URL.', [ 'status' => 400 ] );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param \WP_REST_Request $request
|
|
*/
|
|
public function proxy( \WP_REST_Request $request ) {
|
|
list( $url, $params, $args, $content_type ) = $this->get_args( $request );
|
|
|
|
$status_code = 200;
|
|
$status_message = 'OK';
|
|
|
|
$validation = $this->validate_request( $request );
|
|
if ( \is_wp_error( $validation ) ) {
|
|
$status_code = $validation->get_error_data()['status'];
|
|
$status_message = $validation->get_error_message();
|
|
$response_body = '';
|
|
} else {
|
|
|
|
if ( \is_array( $params ) ) {
|
|
$params = \http_build_query( $params );
|
|
}
|
|
|
|
$endpoint = \http_build_url( $url, [ 'query' => $params ] );
|
|
|
|
$response = \wp_remote_request( $endpoint, $args );
|
|
|
|
$response_body = \wp_remote_retrieve_body( $response );
|
|
}
|
|
|
|
$protocol = ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' );
|
|
if ( 200 === $status_code ) {
|
|
header( "{$protocol} {$status_code} {$status_message}" );
|
|
} else {
|
|
header( "Status: ${status_code} ${status_message}" );
|
|
}
|
|
header( "Content-Type: {$content_type}" );
|
|
|
|
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
echo $response_body;
|
|
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
|
|
$this->break_the_default_response_flow();
|
|
}
|
|
|
|
/**
|
|
* @param \WP_REST_Request $request
|
|
*
|
|
* @return string[]|string
|
|
*/
|
|
public function get_allowed_capabilities( \WP_REST_Request $request ) {
|
|
return [ \WPML_Manage_Translations_Role::CAPABILITY, 'manage_options' ];
|
|
}
|
|
|
|
/**
|
|
* @param \WP_REST_Request $request
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_request_params( \WP_REST_Request $request ) {
|
|
$params = [
|
|
'url' => null,
|
|
'method' => null,
|
|
'query' => null,
|
|
'headers' => null,
|
|
'body' => null,
|
|
'content_type' => 'application/json',
|
|
];
|
|
|
|
if ( $request->get_params() ) {
|
|
$params = \array_merge( $params, $request->get_params() );
|
|
}
|
|
|
|
return $params;
|
|
}
|
|
|
|
private function break_the_default_response_flow() {
|
|
$shortcut = function () {
|
|
return function () {
|
|
die();
|
|
};
|
|
|
|
};
|
|
$die_handlers = [
|
|
'wp_die_ajax_handler',
|
|
'wp_die_json_handler',
|
|
'wp_die_jsonp_handler',
|
|
'wp_die_xmlrpc_handler',
|
|
'wp_die_xml_handler',
|
|
'wp_die_handler',
|
|
];
|
|
foreach ( $die_handlers as $die_handler ) {
|
|
\add_filter( $die_handler, $shortcut, 10 );
|
|
}
|
|
|
|
\wp_die();
|
|
}
|
|
}
|