first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
<?php
/**
* @author OnTheGo Systems
*/
namespace WPML\TM\ATE\REST;
use WP_REST_Request;
use WPML\Collect\Support\Collection;
use WPML\Element\API\PostTranslations;
use WPML\FP\Cast;
use WPML\FP\Fns;
use WPML\FP\Logic;
use WPML\FP\Obj;
use WPML\FP\Relation;
use WPML\TM\API\Jobs;
use WPML\TM\ATE\Download\Process;
use WPML\TM\ATE\Review\PreviewLink;
use WPML\TM\ATE\Review\ReviewStatus;
use WPML\TM\ATE\Review\StatusIcons;
use WPML\TM\ATE\SyncLock;
use WPML\TM\REST\Base;
use WPML_TM_ATE_AMS_Endpoints;
use function WPML\Container\make;
use function WPML\FP\pipe;
class Download extends Base {
/**
* @return array
*/
public function get_routes() {
return [
[
'route' => WPML_TM_ATE_AMS_Endpoints::DOWNLOAD_JOBS,
'args' => [
'methods' => 'POST',
'callback' => [ $this, 'download' ],
],
],
];
}
/**
* @param WP_REST_Request $request
*
* @return array
*/
public function get_allowed_capabilities( WP_REST_Request $request ) {
return [
'manage_options',
'manage_translations',
'translate',
];
}
public function download( WP_REST_Request $request ) {
$lock = make( SyncLock::class );
if ( ! $lock->create( $request->get_param( 'lockKey' ) ) ) {
return [];
}
$jobs = make( Process::class )->run( $request->get_param( 'jobs' ) );
return $this->getJobs( $jobs, $request->get_param( 'returnUrl' ) )->all();
}
/**
* @param Collection $processedJobs
* @param string $returnUrl
*
* @return Collection
*/
public static function getJobs( Collection $processedJobs, $returnUrl ) {
$getLink = Logic::ifElse(
ReviewStatus::doesJobNeedReview(),
Fns::converge( PreviewLink::getWithSpecifiedReturnUrl( $returnUrl ), [ Obj::prop( 'translatedPostId' ), Obj::prop( 'jobId' ) ] ),
pipe( Obj::prop( 'jobId' ), Jobs::getEditUrl( $returnUrl ) )
);
$getLabel = Logic::ifElse(
ReviewStatus::doesJobNeedReview(),
StatusIcons::getReviewTitle( 'language_code' ),
StatusIcons::getEditTitle( 'language_code' )
);
return $processedJobs->pluck( 'jobId' )
->map( Jobs::get() )
->map( Obj::addProp( 'translatedPostId', Jobs::getTranslatedPostId() ) )
->map( Obj::renameProp( 'job_id', 'jobId' ) )
->map( Obj::renameProp( 'editor_job_id', 'ateJobId' ) )
->map( Obj::addProp( 'viewLink', $getLink ) )
->map( Obj::addProp( 'label', $getLabel ) )
->map( Obj::pick( [ 'jobId', 'viewLink', 'automatic', 'status', 'label', 'review_status', 'ateJobId' ] ) )
->map( Obj::evolve( [
'jobId' => Cast::toInt(),
'automatic' => Cast::toInt(),
'status' => Cast::toInt(),
'ateJobId' => Cast::toInt(),
] ) );
}
}

View File

@@ -0,0 +1,148 @@
<?php
namespace WPML\TM\ATE\REST;
use WPML\TM\ATE\ReturnedJobsQueue;
use WP_REST_Request;
use WPML\Rest\Adaptor;
use WPML\TM\REST\Base;
use WPML_TM_ATE_AMS_Endpoints;
use \WPML_TM_ATE_API;
use \WPML_TM_ATE_Jobs;
use \WPML_TM_Jobs_Repository;
use WPML\FP\Obj;
use WPML\TM\ATE\Log\Entry;
use WPML\TM\ATE\Log\EventsTypes;
class FixJob extends Base {
/**
* @var WPML_TM_ATE_Jobs
*/
private $ateJobs;
/**
* @var WPML_TM_ATE_API
*/
private $ateApi;
/**
* @var WPML_TM_Jobs_Repository
*/
private $jobsRepository;
const PARAM_ATE_JOB_ID = 'ateJobId';
const PARAM_WPML_JOB_ID = 'jobId';
public function __construct( Adaptor $adaptor, WPML_TM_ATE_API $ateApi, WPML_TM_ATE_Jobs $ateJobs ) {
parent::__construct( $adaptor );
$this->ateApi = $ateApi;
$this->ateJobs = $ateJobs;
$this->jobsRepository = wpml_tm_get_jobs_repository();
}
/**
* @return array
*/
public function get_routes() {
return [
[
'route' => WPML_TM_ATE_AMS_Endpoints::FIX_JOB,
'args' => [
'methods' => 'GET',
'callback' => [ $this, 'fix_job' ],
],
],
];
}
/**
* @param WP_REST_Request $request
*
* @return array
*/
public function get_allowed_capabilities( WP_REST_Request $request ) {
return [
'manage_options',
'manage_translations',
'translate',
];
}
/**
* @param WP_REST_Request $request
*
* @return bool[]
*/
public function fix_job( WP_REST_Request $request ) {
try {
$ateJobId = $request->get_param( self::PARAM_ATE_JOB_ID );
$wpmlJobId = $request->get_param( self::PARAM_WPML_JOB_ID );
$processedJobResult = $this->process( $ateJobId, $wpmlJobId );
if ( $processedJobResult ) {
return [ 'completed' => true, 'error' => false ];
}
} catch ( \Exception $e ) {
$this->logException( $e, [ 'ateJobId' => $ateJobId, 'wpmlJobId' => $wpmlJobId ] );
return [ 'completed' => false, 'error' => true ];
}
return [ 'completed' => false, 'error' => false ];
}
/**
* Processes the job status.
*
* @param $ateJobId
* @param $wpmlJobId
*
* @return bool
* @throws \Requests_Exception
*/
public function process( $ateJobId, $wpmlJobId ) {
$ateJob = $this->ateApi->get_job( $ateJobId )->$ateJobId;
$xliffUrl = Obj::prop('translated_xliff', $ateJob);
if ( $xliffUrl ) {
$xliffContent = $this->ateApi->get_remote_xliff_content( $xliffUrl, [ 'jobId' => $wpmlJobId, 'ateJobId' => $ateJobId ] );
$receivedWpmlJobId = $this->ateJobs->apply( $xliffContent );
if ( $receivedWpmlJobId && intval( $receivedWpmlJobId ) !== intval( $wpmlJobId ) ) {
$error_message = sprintf( 'The received wpmlJobId (%s) does not match (%s).', $receivedWpmlJobId, $wpmlJobId );
throw new \Exception( $error_message );
}
if ( $receivedWpmlJobId ) {
ReturnedJobsQueue::remove( $wpmlJobId );
return true;
}
}
return false;
}
/**
* @param \Exception $e
* @param array|null $job
*/
private function logException( \Exception $e, $job = null ) {
$entry = new Entry();
$entry->description = $e->getMessage();
if ( $job ) {
$entry->ateJobId = Obj::prop('ateJobId', $job);
$entry->wpmlJobId = Obj::prop('wpmlJobId', $job);
$entry->extraData = [ 'downloadUrl' => Obj::prop('url', $job) ];
}
if ( $e instanceof \Requests_Exception ) {
$entry->eventType = EventsTypes::SERVER_XLIFF;
} else {
$entry->eventType = EventsTypes::JOB_DOWNLOAD;
}
wpml_tm_ate_ams_log( $entry );
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace WPML\TM\ATE\REST;
use WPML\FP\Obj;
use WPML\TM\API\ATE;
use WPML\FP\Maybe;
use WPML\FP\Fns;
use WPML\TM\API\Jobs;
use WPML\TM\REST\Base;
use function WPML\Container\make;
use function WPML\FP\pipe;
use function WPML\FP\curryN;
/**
* @author OnTheGo Systems
*/
class PublicReceive extends \WPML_TM_ATE_Required_Rest_Base {
const CODE_UNPROCESSABLE_ENTITY = 422;
const CODE_OK = 200;
const ENDPOINT_JOBS_RECEIVE = '/ate/jobs/receive/';
function add_hooks() {
$this->register_routes();
}
function register_routes() {
parent::register_route(
self::ENDPOINT_JOBS_RECEIVE . '(?P<wpmlJobId>\d+)',
array(
'methods' => 'GET',
'callback' => array( $this, 'receive_ate_job' ),
'args' => array(
'wpmlJobId' => array(
'required' => true,
'type' => 'int',
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'integer' ),
),
),
'permission_callback' => '__return_true',
)
);
}
public function get_allowed_capabilities( \WP_REST_Request $request ) {
return [];
}
/**
* @param \WP_REST_Request $request
*
* @return true|\WP_Error
*/
public function receive_ate_job( \WP_REST_Request $request ) {
$wpmlJobId = $request->get_param( 'wpmlJobId' );
$ateAPI = make( ATE::class );
$getXLIFF = pipe(
Obj::prop( 'job_id' ),
Fns::safe( [ $ateAPI, 'checkJobStatus' ] ),
Fns::map( Obj::prop( 'translated_xliff' ) )
);
$applyTranslations = Fns::converge(
Fns::liftA3( curryN( 3, [ $ateAPI, 'applyTranslation' ] ) ),
[
Fns::safe( Obj::prop( 'job_id' ) ),
Fns::safe( Obj::prop( 'original_doc_id' ) ),
$getXLIFF
]
);
return Maybe::of( $wpmlJobId )
->map( Jobs::get() )
->chain( $applyTranslations )
->map( Fns::always( new \WP_REST_Response( null, self::CODE_OK ) ) )
->getOrElse( new \WP_Error( self::CODE_UNPROCESSABLE_ENTITY ) );
}
/**
* @param int $wpml_job_id
*
* @return string
*/
public static function get_receive_ate_job_url( $wpml_job_id ) {
return self::get_url( self::ENDPOINT_JOBS_RECEIVE . $wpml_job_id );
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace WPML\TM\ATE\REST;
use WP_REST_Request;
use WPML\TM\ATE\Retry\Arguments;
use WPML\TM\ATE\Retry\Process;
use WPML\TM\REST\Base;
use WPML_TM_ATE_AMS_Endpoints;
use function WPML\Container\make;
class Retry extends Base {
/**
* @return array
*/
public function get_routes() {
return [
[
'route' => WPML_TM_ATE_AMS_Endpoints::RETRY_JOBS,
'args' => [
'methods' => 'POST',
'callback' => [ $this, 'retry' ],
],
],
];
}
/**
* @param WP_REST_Request $request
*
* @return array
*/
public function get_allowed_capabilities( WP_REST_Request $request ) {
return [
'manage_options',
'manage_translations',
'translate',
];
}
/**
* @param WP_REST_Request $request
*
* @return array
* @throws \Auryn\InjectionException
*/
public function retry( WP_REST_Request $request ) {
return (array) make( Process::class )->run( $request->get_param( 'jobsToProcess' ) );
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace WPML\TM\ATE\REST;
use WP_REST_Request;
use WPML\Collect\Support\Collection;
use WPML\FP\Cast;
use WPML\FP\Fns;
use WPML\FP\Logic;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\FP\Relation;
use WPML\Rest\Adaptor;
use WPML\TM\API\Jobs;
use WPML\TM\ATE\Download\Job;
use WPML\TM\ATE\Review\PreviewLink;
use WPML\TM\ATE\Review\ReviewStatus;
use WPML\TM\ATE\Review\StatusIcons;
use WPML\TM\ATE\Sync\Arguments;
use WPML\TM\ATE\Sync\Factory;
use WPML\TM\ATE\Sync\Process;
use WPML\TM\ATE\Sync\Result;
use WPML\TM\ATE\SyncLock;
use WPML\TM\REST\Base;
use WPML\Utilities\KeyedLock;
use WPML_TM_ATE_AMS_Endpoints;
use function WPML\Container\make;
use function WPML\FP\pipe;
class Sync extends Base {
/**
* @return array
*/
public function get_routes() {
return [
[
'route' => WPML_TM_ATE_AMS_Endpoints::SYNC_JOBS,
'args' => [
'methods' => 'POST',
'callback' => [ $this, 'sync' ],
'args' => [
'lockKey' => self::getStringType(),
'ateToken' => self::getStringType(),
'page' => self::getIntType(),
'numberOfPages' => self::getIntType(),
],
],
],
];
}
/**
* @param WP_REST_Request $request
*
* @return array
*/
public function get_allowed_capabilities( WP_REST_Request $request ) {
return [
'manage_options',
'manage_translations',
'translate',
];
}
/**
* @param WP_REST_Request $request
*
* @return array
* @throws \Auryn\InjectionException
*/
public function sync( WP_REST_Request $request ) {
$args = new Arguments();
$args->ateToken = $request->get_param( 'ateToken' );
$args->page = $request->get_param( 'nextPage' );
$args->numberOfPages = $request->get_param( 'numberOfPages' );
$args->includeManualAndLongstandingJobs = $request->get_param( 'includeManualAndLongstandingJobs' );
$lock = make( SyncLock::class );
$lockKey = $lock->create( $request->get_param( 'lockKey' ) );
if ( $lockKey ) {
$result = make( Process::class )->run( $args );
$result->lockKey = $lockKey;
$jobsFromDB = Fns::filter(
Logic::complement( $this->findSyncedJob( $result->jobs ) ),
$this->getJobStatuses( $request->get_param( 'jobIds' ), $request->get_param( 'returnUrl' ) )
);
$result = $this->createResultWithJobs( Lst::concat( $result->jobs, $jobsFromDB ), $result );
} else {
$result = $this->createResultWithJobs( $this->getJobStatuses( $request->get_param( 'jobIds' ), $request->get_param( 'returnUrl' ) ) );
}
return (array) $result;
}
private function getJobStatuses( $wpmlJobIds, $returnUrl ) {
if ( ! $wpmlJobIds ) {
return [];
}
global $wpdb;
$ids = wpml_prepare_in( $wpmlJobIds, '%d' );
$sql = "
SELECT jobs.job_id as jobId, statuses.status as status, jobs.editor_job_id as ateJobId FROM {$wpdb->prefix}icl_translate_job as jobs
INNER JOIN {$wpdb->prefix}icl_translation_status as statuses ON statuses.rid = jobs.rid
WHERE jobs.job_id IN ( {$ids} ) AND 1 = %d
"; // I need additional AND condition to utilize prepare function which is required to make writing unit tests easier. It's not perfect but saves a lot of time now
$result = $wpdb->get_results( $wpdb->prepare( $sql , 1) );
if ( ! is_array( $result ) ) {
return [];
}
$jobs = Fns::map( Obj::evolve( [
'jobId' => Cast::toInt(),
'status' => Cast::toInt(),
'ateJobId' => Cast::toInt(),
] ), $result );
list( $completed, $notCompleted ) = \wpml_collect( $jobs )->partition( Relation::propEq( 'status', ICL_TM_COMPLETE ) );
if ( count( $completed ) ) {
$completed = Download::getJobs( $completed, $returnUrl )->map( function ( $job ) {
return (array) $job;
} );
}
return $completed->merge( $notCompleted )->all();
}
private function findSyncedJob( $jobsFromATE ) {
return function ( $jobFromDb ) use ( $jobsFromATE ) {
return Lst::find( Relation::propEq( 'jobId', Obj::prop( 'jobId', $jobFromDb ) ), $jobsFromATE );
};
}
/**
* @param array $jobs
* @param Result|null $template
*
* @return Result
*/
private function createResultWithJobs( array $jobs, Result $template = null ) {
$result = $template ? clone $template : new Result();
$result->jobs = $jobs;
return $result;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* @author OnTheGo Systems
*/
abstract class WPML_TM_ATE_Required_Rest_Base extends WPML_REST_Base {
const REST_NAMESPACE = 'wpml/tm/v1';
/**
* WPML_TM_ATE_Required_Rest_Base constructor.
*/
public function __construct() {
parent::__construct( self::REST_NAMESPACE );
}
/**
* @param WP_REST_Request $request
*
* @return bool
*/
public function validate_permission( WP_REST_Request $request ) {
return WPML_TM_ATE_Status::is_enabled() && parent::validate_permission( $request );
}
/**
* @param string $endpoint
*
* @return string
*/
static function get_url( $endpoint ) {
return get_rest_url( null, '/' . self::REST_NAMESPACE . $endpoint );
}
}

View File

@@ -0,0 +1,12 @@
<?php
class WPML_TM_REST_AMS_Clients_Factory extends WPML_REST_Factory_Loader {
/**
* @return \WPML_TM_REST_AMS_Clients
* @throws \Auryn\InjectionException
*/
public function create() {
return \WPML\Container\make( '\WPML_TM_REST_AMS_Clients' );
}
}

View File

@@ -0,0 +1,152 @@
<?php
/**
* @author OnTheGo Systems
*/
use WPML\FP\Fns;
use WPML\FP\Obj;
class WPML_TM_REST_AMS_Clients extends WPML_REST_Base {
private $api;
private $ams_user_records;
/** @var WPML_TM_AMS_Translator_Activation_Records $translator_activation_records */
private $translator_activation_records;
/**
* @var WPML_TM_ATE_AMS_Endpoints
*/
private $strings;
public function __construct(
WPML_TM_AMS_API $api,
WPML_TM_AMS_Users $ams_user_records,
WPML_TM_AMS_Translator_Activation_Records $translator_activation_records,
WPML_TM_MCS_ATE_Strings $strings
) {
parent::__construct( 'wpml/tm/v1' );
$this->api = $api;
$this->ams_user_records = $ams_user_records;
$this->translator_activation_records = $translator_activation_records;
$this->strings = $strings;
}
function add_hooks() {
$this->register_routes();
}
function register_routes() {
parent::register_route(
'/ams/register_manager',
array(
'methods' => 'POST',
'callback' => array( $this, 'register_manager' ),
)
);
parent::register_route(
'/ams/synchronize/translators',
array(
'methods' => 'GET',
'callback' => array( $this, 'synchronize_translators' ),
)
);
parent::register_route(
'/ams/synchronize/managers',
array(
'methods' => 'GET',
'callback' => array( $this, 'synchronize_managers' ),
)
);
parent::register_route(
'/ams/status',
array(
'methods' => 'GET',
'callback' => array( $this, 'get_status' ),
)
);
parent::register_route(
'/ams/console',
array(
'methods' => 'GET',
'callback' => array( $this, 'get_console' ),
)
);
}
/**
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function register_manager() {
$current_user = wp_get_current_user();
$translators = $this->ams_user_records->get_translators();
$managers = $this->ams_user_records->get_managers();
$handleError = function ( $error ) {
return [
'enabled' => false,
'error' => $error
];
};
return $this->api->register_manager( $current_user, $translators, $managers )
->coalesce( $handleError, Fns::always( [ 'enabled' => true ] ) )
->get();
}
/**
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function synchronize_translators() {
$translators = $this->ams_user_records->get_translators();
$result = $this->api->synchronize_translators( $translators );
if ( is_wp_error( $result ) ) {
return $result;
}
$this->translator_activation_records->update( $result['translators'] );
return array( 'result' => $result );
}
/**
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function synchronize_managers() {
$managers = $this->ams_user_records->get_managers();
$result = $this->api->synchronize_managers( $managers );
if ( is_wp_error( $result ) ) {
return $result;
}
return array( 'result' => $result );
}
/**
* @return array|mixed|null|object|WP_Error
* @throws \InvalidArgumentException
*/
public function get_status() {
return $this->api->get_status();
}
public function get_console() {
return $this->strings->get_auto_login();
}
function get_allowed_capabilities( WP_REST_Request $request ) {
return array( 'manage_translations', 'manage_options' );
}
}

View File

@@ -0,0 +1,12 @@
<?php
class WPML_TM_REST_ATE_API_Factory extends WPML_REST_Factory_Loader {
/**
* @return \WPML_TM_REST_ATE_API
* @throws \Auryn\InjectionException
*/
public function create() {
return \WPML\Container\make( '\WPML_TM_REST_ATE_API' );
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_REST_ATE_API extends WPML_TM_ATE_Required_Rest_Base {
const CAPABILITY_CREATE = 'manage_translations';
const CAPABILITY_READ = 'translate';
private $api;
/**
* WPML_TM_REST_AMS_Clients constructor.
*
* @param WPML_TM_ATE_API $api
*/
public function __construct( WPML_TM_ATE_API $api ) {
parent::__construct();
$this->api = $api;
}
function add_hooks() {
$this->register_routes();
}
function register_routes() {
parent::register_route(
'/ate/jobs',
array(
'methods' => 'POST',
'callback' => array( $this, 'create_jobs' ),
)
);
parent::register_route(
'/ate/jobs/(?P<ateJobId>\d+)',
array(
'methods' => 'GET',
'callback' => array( $this, 'get_job' ),
)
);
}
/**
* @param WP_REST_Request $request
*
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function create_jobs( WP_REST_Request $request ) {
return $this->api->create_jobs( $request->get_params() );
}
/**
* @param WP_REST_Request $request
*
* @return array|WP_Error
* @throws \InvalidArgumentException
*/
public function get_job( WP_REST_Request $request ) {
$ate_job_id = $request->get_param( 'ateJobId' );
return $this->api->get_job( $ate_job_id );
}
function get_allowed_capabilities( WP_REST_Request $request ) {
if ( 'GET' === $request->get_method() ) {
return array( self::CAPABILITY_CREATE, self::CAPABILITY_READ );
}
return self::CAPABILITY_CREATE;
}
}

View File

@@ -0,0 +1,14 @@
<?php
class WPML_TM_REST_ATE_Jobs_Factory extends WPML_REST_Factory_Loader {
public function create() {
$ate_jobs_records = wpml_tm_get_ate_job_records();
$ate_jobs = new WPML_TM_ATE_Jobs( $ate_jobs_records );
return new WPML_TM_REST_ATE_Jobs(
$ate_jobs,
wpml_tm_get_ate_jobs_repository()
);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_REST_ATE_Jobs extends WPML_TM_ATE_Required_Rest_Base {
const CAPABILITY = 'manage_translations';
private $ate_jobs;
/** @var WPML_TM_ATE_Job_Repository */
private $job_repository;
/**
* WPML_TM_REST_ATE_Jobs constructor.
*
* @param WPML_TM_ATE_Jobs $ate_jobs
* @param WPML_TM_ATE_Job_Repository $job_repository
*/
public function __construct( WPML_TM_ATE_Jobs $ate_jobs, WPML_TM_ATE_Job_Repository $job_repository ) {
parent::__construct();
$this->ate_jobs = $ate_jobs;
$this->job_repository = $job_repository;
}
function add_hooks() {
$this->register_routes();
}
function register_routes() {
parent::register_route(
WPML_TM_ATE_AMS_Endpoints::STORE_JOB,
array(
'methods' => 'POST',
'callback' => array( $this, 'store_ate_job' ),
'args' => array(
'wpml_job_id' => array(
'required' => true,
'type' => 'string',
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'integer' ),
),
'ate_job_data' => array(
'required' => true,
'type' => 'array',
),
),
)
);
}
/**
* @param WP_REST_Request $request
*
* @return bool
* @throws \InvalidArgumentException
*/
public function store_ate_job( WP_REST_Request $request ) {
$wpml_job_id = $request->get_param( 'wpml_job_id' );
$ate_job_data = $request->get_param( 'ate_job_data' );
$this->ate_jobs->store( $wpml_job_id, $ate_job_data );
return true;
}
function get_allowed_capabilities( WP_REST_Request $request ) {
return self::CAPABILITY;
}
}

View File

@@ -0,0 +1,8 @@
<?php
class WPML_TM_REST_XLIFF_Factory extends WPML_REST_Factory_Loader {
public function create() {
return new WPML_TM_REST_XLIFF();
}
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_REST_XLIFF extends WPML_TM_ATE_Required_Rest_Base {
const CAPABILITY = 'translate';
function add_hooks() {
$this->register_routes();
}
function register_routes() {
parent::register_route(
'/xliff/fetch/(?P<jobId>\d+)',
array(
'methods' => 'GET',
'callback' => array( $this, 'fetch_xliff' ),
)
);
}
/**
* @param WP_REST_Request $request
*
* @return array
* @throws \InvalidArgumentException
*/
public function fetch_xliff( WP_REST_Request $request ) {
$result = null;
$wpml_translation_job_factory = wpml_tm_load_job_factory();
$iclTranslationManagement = wpml_load_core_tm();
$job_id = $request->get_param( 'jobId' );
$writer = new WPML_TM_Xliff_Writer( $wpml_translation_job_factory );
$xliff = base64_encode( $writer->generate_job_xliff( $job_id ) );
$job = $iclTranslationManagement->get_translation_job( (int) $job_id, false, false, 1 );
$result = array(
'content' => $xliff,
'sourceLang' => $job->source_language_code,
'targetLang' => $job->language_code,
);
return $result;
}
function get_allowed_capabilities( WP_REST_Request $request ) {
return self::CAPABILITY;
}
}