Files
doitinpoland.com/wp-content/plugins/wpml-translation-management/classes/ATE/API/class-wpml-tm-ate-api.php
2023-09-12 21:41:04 +02:00

431 lines
11 KiB
PHP

<?php
use WPML\TM\ATE\ClonedSites\FingerprintGenerator;
use WPML\TM\ATE\Log\Entry;
use WPML\TM\ATE\Log\ErrorEvents;
use WPML\TM\ATE\ClonedSites\ApiCommunication as ClonedSitesHandler;
/**
* @author OnTheGo Systems
*/
class WPML_TM_ATE_API {
private $wp_http;
private $auth;
private $endpoints;
/**
* @var ClonedSitesHandler
*/
private $clonedSitesHandler;
/**
* @var FingerprintGenerator
*/
private $fingerprintGenerator;
/**
* WPML_TM_ATE_API constructor.
*
* @param WP_Http $wp_http
* @param WPML_TM_ATE_Authentication $auth
* @param WPML_TM_ATE_AMS_Endpoints $endpoints
*/
public function __construct(
WP_Http $wp_http,
WPML_TM_ATE_Authentication $auth,
WPML_TM_ATE_AMS_Endpoints $endpoints,
ClonedSitesHandler $clonedSitesHandler,
FingerprintGenerator $fingerprintGenerator
) {
$this->wp_http = $wp_http;
$this->auth = $auth;
$this->endpoints = $endpoints;
$this->clonedSitesHandler = $clonedSitesHandler;
$this->fingerprintGenerator = $fingerprintGenerator;
}
/**
* @param array $params
*
* @see https://bitbucket.org/emartini_crossover/ate/wiki/API/V1/jobs/create
*
* @return mixed
* @throws \InvalidArgumentException
*/
public function create_jobs( array $params ) {
return $this->requestWithLog(
$this->endpoints->get_ate_jobs(),
[
'method' => 'POST',
'body' => $params,
]
);
}
/**
* @param int|string|array $ate_job_id
*
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function confirm_received_job( $ate_job_id ) {
return $this->requestWithLog( $this->endpoints->get_ate_confirm_job( $ate_job_id ) );
}
/**
* @param int $job_id
* @param string $return_url
*
* @return string|WP_Error
* @throws \InvalidArgumentException
*/
public function get_editor_url( $job_id, $return_url ) {
$lock = $this->clonedSitesHandler->checkCloneSiteLock();
if ( $lock ) {
return new WP_Error( 'communication_error', 'ATE communication is locked, please update configuration' );
}
$url = $this->endpoints->get_ate_editor();
$url = str_replace(
[
'{job_id}',
'{translator_email}',
'{return_url}',
],
[
$job_id,
urlencode( filter_var( wp_get_current_user()->user_email, FILTER_SANITIZE_URL ) ),
urlencode( filter_var( $return_url, FILTER_SANITIZE_URL ) ),
],
$url
);
return $this->auth->get_signed_url_with_parameters( 'GET', $url, null );
}
/**
* @param int $ate_job_id
* @param WPML_Element_Translation_Job $job_object
*
* @return array
*/
public function clone_job( $ate_job_id, WPML_Element_Translation_Job $job_object ) {
$url = $this->endpoints->get_clone_job( $ate_job_id );
$result = $this->requestWithLog(
$url,
[
'method' => 'POST',
'body' => [
'id' => $ate_job_id,
'notify_url' =>
WPML_TM_REST_ATE_Public::get_receive_ate_job_url( $job_object->get_id() ),
'site_identifier' => wpml_get_site_id( WPML_TM_ATE::SITE_ID_SCOPE ),
'source_id' => wpml_tm_get_records()
->icl_translate_job_by_job_id( $job_object->get_id() )
->rid(),
'permalink' => $job_object->get_url( true ),
'ate_ams_console_url' => wpml_tm_get_ams_ate_console_url(),
],
]
);
if ( $result && ! is_wp_error( $result ) ) {
return [
'id' => $result->job_id,
'ate_status' =>
isset( $result->status ) ? $result->status : WPML_TM_ATE_AMS_Endpoints::ATE_JOB_STATUS_CREATED,
];
} else {
return false;
}
}
/**
* @param int $ate_job_id
*
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function get_job( $ate_job_id ) {
if ( ! $ate_job_id ) {
return null;
}
return $this->requestWithLog( $this->endpoints->get_ate_jobs( $ate_job_id ) );
}
/**
* If `$job_ids` is not an empty array,
* the `$statuses` parameter will be ignored in ATE's endpoint.
*
* @see https://bitbucket.org/emartini_crossover/ate/wiki/API/V1/jobs/status
*
* @param null|array $job_ids
* @param null|array $statuses
*
* @return array|mixed|null|object|WP_Error
* @throws \InvalidArgumentException
*/
public function get_jobs( $job_ids, $statuses = null ) {
return $this->requestWithLog( $this->endpoints->get_ate_jobs( $job_ids, $statuses ) );
}
/**
* @param $wpml_job_ids
*
* @return array|mixed|object|WP_Error|null
*/
public function get_jobs_by_wpml_ids( $wpml_job_ids ) {
return $this->requestWithLog( $this->endpoints->get_ate_jobs_by_wpml_job_ids( $wpml_job_ids ) );
}
/**
* @param array $pairs
* @see https://bitbucket.org/emartini_crossover/ate/wiki/API/V1/migration/migrate
* @return bool
*/
public function migrate_source_id( array $pairs ) {
$lock = $this->clonedSitesHandler->checkCloneSiteLock();
if ( $lock ) {
return false;
}
$verb = 'POST';
$url = $this->auth->get_signed_url_with_parameters( $verb, $this->endpoints->get_source_id_migration(), $pairs );
if ( is_wp_error( $url ) ) {
return $url;
}
$result = $this->wp_http->request(
$url,
array(
'timeout' => 60,
'method' => $verb,
'headers' => $this->json_headers(),
'body' => wp_json_encode( $pairs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
)
);
if ( ! is_wp_error( $result ) ) {
$result = $this->clonedSitesHandler->handleClonedSiteError( $result );
}
return $this->get_response_errors( $result ) === null;
}
private function get_response( $result ) {
$errors = $this->get_response_errors( $result );
if ( is_wp_error( $errors ) ) {
return $errors;
}
return $this->get_response_body( $result );
}
private function get_response_body( $result ) {
if ( is_array( $result ) && array_key_exists( 'body', $result ) && ! is_wp_error( $result ) ) {
$body = json_decode( $result['body'] );
if ( isset( $body->authenticated ) && ! (bool) $body->authenticated ) {
return new WP_Error( 'ate_auth_failed', $body->message );
}
return $body;
}
return $result;
}
private function get_response_errors( $response ) {
$response_errors = null;
if ( is_wp_error( $response ) ) {
$response_errors = $response;
} elseif ( array_key_exists( 'body', $response ) && $response['response']['code'] >= 400 ) {
$errors = array();
$response_body = json_decode( $response['body'], true );
if ( is_array( $response_body ) && array_key_exists( 'errors', $response_body ) ) {
$errors = $response_body['errors'];
}
$response_errors = new WP_Error( $response['response']['code'], $response['response']['message'], $errors );
}
return $response_errors;
}
/**
* @return array
*/
private function json_headers() {
return [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
FingerprintGenerator::SITE_FINGERPRINT_HEADER => $this->fingerprintGenerator->getSiteFingerprint(),
];
}
/**
* @param array $args
*
* @return string
*/
private function encode_body_args( array $args ) {
return wp_json_encode( $args, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
}
/**
* @param string $xliff_url
*
* @return string
* @throws Requests_Exception
*/
public function get_remote_xliff_content( $xliff_url ) {
/** @var \WP_Error|array $response */
$response = wp_remote_get( $xliff_url );
if ( is_wp_error( $response ) ) {
throw new Requests_Exception( $response->get_error_message(), $response->get_error_code() );
} elseif ( isset( $response['response']['code'] ) && 200 !== (int) $response['response']['code'] ) {
throw new Requests_Exception( $response['response']['message'], $response['response']['code'] );
} elseif ( ! isset( $response['body'] ) || ! trim( $response['body'] ) ) {
throw new Requests_Exception( 'Missing body', 0 );
}
return $response['body'];
}
public function override_site_id( $site_id ) {
$this->auth->override_site_id( $site_id );
}
public function get_website_id( $site_url ) {
$lock = $this->clonedSitesHandler->checkCloneSiteLock();
if ( $lock ) {
return null;
}
$signed_url = $this->auth->get_signed_url_with_parameters( 'GET', $this->endpoints->get_websites() );
if ( is_wp_error( $signed_url ) ) {
return null;
}
$requestArguments = [ 'headers' => $this->json_headers() ];
$response = $this->wp_http->request( $signed_url, $requestArguments );
if ( ! is_wp_error( $response ) ) {
$response = $this->clonedSitesHandler->handleClonedSiteError( $response );
}
$sites = $this->get_response( $response );
foreach ( $sites as $site ) {
if ( $site->url === $site_url ) {
return $site->uuid;
}
}
return null;
}
/**
* @see https://bitbucket.org/emartini_crossover/ate/wiki/API/V1/sync/all
*
* @param array $ateJobIds
*
* @return array|mixed|null|object|WP_Error
* @throws \InvalidArgumentException
*/
public function sync_all( array $ateJobIds ) {
return $this->requestWithLog(
$this->endpoints->get_sync_all(),
[
'method' => 'POST',
'body' => [ 'ids' => $ateJobIds ],
]
);
}
/**
* @see https://bitbucket.org/emartini_crossover/ate/wiki/API/V1/sync/page
*
* @param string $token
* @param int $page
*
* @return array|mixed|null|object|WP_Error
* @throws \InvalidArgumentException
*/
public function sync_page( $token, $page ) {
return $this->requestWithLog( $this->endpoints->get_sync_page( $token, $page ) );
}
/**
* @param string $url
* @param array $requestArgs
*
* @return array|mixed|object|string|WP_Error|null
*/
private function request( $url, array $requestArgs = [] ) {
$lock = $this->clonedSitesHandler->checkCloneSiteLock();
if ( $lock ) {
return $lock;
}
$requestArgs = array_merge(
[
'timeout' => 60,
'method' => 'GET',
'headers' => $this->json_headers(),
],
$requestArgs
);
$bodyArgs = isset( $requestArgs['body'] ) && is_array( $requestArgs['body'] )
? $requestArgs['body'] : null;
$signedUrl = $this->auth->get_signed_url_with_parameters( $requestArgs['method'], $url, $bodyArgs );
if ( is_wp_error( $signedUrl ) ) {
return $signedUrl;
}
if ( $bodyArgs ) {
$requestArgs['body'] = $this->encode_body_args( $bodyArgs );
}
$result = $this->wp_http->request( $signedUrl, $requestArgs );
if ( ! is_wp_error( $result ) ) {
$result = $this->clonedSitesHandler->handleClonedSiteError( $result );
}
return $this->get_response( $result );
}
/**
* @param string $url
* @param array $requestArgs
*
* @return array|mixed|object|string|WP_Error|null
*/
private function requestWithLog( $url, array $requestArgs = [] ) {
$response = $this->request( $url, $requestArgs );
if ( is_wp_error( $response ) ) {
$entry = new Entry();
$entry->event = ErrorEvents::SERVER_ATE;
$entry->description = $response->get_error_message();
$entry->extraData = [
'url' => $url,
'requestArgs' => $requestArgs,
];
wpml_tm_ate_ams_log( $entry );
}
return $response;
}
}