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,36 @@
<?php
class WPML_TP_Apply_Single_Job {
/** @var WPML_TP_Translations_Repository */
private $translations_repository;
/** @var WPML_TP_Apply_Translation_Strategies */
private $strategy_dispatcher;
/**
* @param WPML_TP_Translations_Repository $translations_repository
* @param WPML_TP_Apply_Translation_Strategies $strategy_dispatcher
*/
public function __construct(
WPML_TP_Translations_Repository $translations_repository,
WPML_TP_Apply_Translation_Strategies $strategy_dispatcher
) {
$this->translations_repository = $translations_repository;
$this->strategy_dispatcher = $strategy_dispatcher;
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TM_Job_Entity
* @throws WPML_TP_API_Exception
*/
public function apply( WPML_TM_Job_Entity $job ) {
$translations = $this->translations_repository->get_job_translations_by_job_entity( $job );
$this->strategy_dispatcher->get( $job )->apply( $job, $translations );
$job->set_status( ICL_TM_COMPLETE );
return $job;
}
}

View File

@@ -0,0 +1,69 @@
<?php
class WPML_TP_Apply_Translation_Post_Strategy implements WPML_TP_Apply_Translation_Strategy {
/** @var WPML_TP_Jobs_API */
private $jobs_api;
/** @var wpdb */
private $wpdb;
/**
* @param WPML_TP_Jobs_API $jobs_api
*/
public function __construct( WPML_TP_Jobs_API $jobs_api ) {
$this->jobs_api = $jobs_api;
global $wpdb;
$this->wpdb = $wpdb;
}
/**
* @param WPML_TM_Job_Entity $job
* @param WPML_TP_Translation_Collection $translations
*
* @return void
* @throws WPML_TP_API_Exception
*/
public function apply( WPML_TM_Job_Entity $job, WPML_TP_Translation_Collection $translations ) {
if ( ! $job instanceof WPML_TM_Post_Job_Entity ) {
throw new InvalidArgumentException( 'A job must have post type' );
}
kses_remove_filters();
wpml_tm_save_data( $this->build_data( $job, $translations ) );
kses_init();
$this->jobs_api->update_job_state( $job, 'delivered' );
}
/**
* @param WPML_TM_Job_Entity $job
* @param WPML_TP_Translation_Collection $translations
*
* @return array
*/
private function build_data( WPML_TM_Post_Job_Entity $job, WPML_TP_Translation_Collection $translations ) {
$data = array(
'job_id' => $job->get_translate_job_id(),
'fields' => array(),
'complete' => 1
);
/** @var WPML_TP_Translation $translation */
foreach ( $translations as $translation ) {
foreach ( $job->get_elements() as $element ) {
if ( $element->get_type() === $translation->get_field() ) {
$data['fields'][ $element->get_type() ] = array(
'data' => $translation->get_target(),
'finished' => 1,
'tid' => $element->get_id(),
'field_type' => $element->get_type(),
'format' => $element->get_format()
);
}
}
}
return $data;
}
}

View File

@@ -0,0 +1,62 @@
<?php
class WPML_TP_Apply_Translation_Strategies {
/** @var WPML_TP_Apply_Translation_Post_Strategy */
private $post_strategy;
/** @var WPML_TP_Apply_Translation_String_Strategy */
private $string_strategy;
/** @var wpdb */
private $wpdb;
/**
* @param wpdb $wpdb
*/
public function __construct( wpdb $wpdb ) {
$this->wpdb = $wpdb;
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TP_Apply_Translation_Strategy
*/
public function get( WPML_TM_Job_Entity $job ) {
switch ( $job->get_type() ) {
case WPML_TM_Job_Entity::STRING_TYPE:
return $this->get_string_strategy();
case WPML_TM_Job_Entity::POST_TYPE:
case WPML_TM_Job_Entity::PACKAGE_TYPE:
case WPML_TM_Job_Entity::STRING_BATCH:
return $this->get_post_strategy();
default:
throw new InvalidArgumentException( 'Job type: ' . $job->get_type() . ' is not supported' );
}
}
/**
* @return WPML_TP_Apply_Translation_Post_Strategy
*/
private function get_post_strategy() {
if ( ! $this->post_strategy ) {
$this->post_strategy = new WPML_TP_Apply_Translation_Post_Strategy( wpml_tm_get_tp_jobs_api() );
}
return $this->post_strategy;
}
/**
* @return WPML_TP_Apply_Translation_String_Strategy
*/
private function get_string_strategy() {
if ( ! $this->string_strategy ) {
$this->string_strategy = new WPML_TP_Apply_Translation_String_Strategy(
wpml_tm_get_tp_jobs_api(),
$this->wpdb
);
}
return $this->string_strategy;
}
}

View File

@@ -0,0 +1,11 @@
<?php
interface WPML_TP_Apply_Translation_Strategy {
/**
* @param WPML_TM_Job_Entity $job
* @param WPML_TP_Translation_Collection $translations
*
* @return void
*/
public function apply( WPML_TM_Job_Entity $job, WPML_TP_Translation_Collection $translations );
}

View File

@@ -0,0 +1,62 @@
<?php
class WPML_TP_Apply_Translation_String_Strategy implements WPML_TP_Apply_Translation_Strategy {
/** @var WPML_TP_Jobs_API */
private $jobs_api;
/** @var wpdb */
private $wpdb;
/**
* @param WPML_TP_Jobs_API $jobs_api
* @param wpdb $wpdb
*/
public function __construct( WPML_TP_Jobs_API $jobs_api, wpdb $wpdb ) {
$this->jobs_api = $jobs_api;
$this->wpdb = $wpdb;
}
/**
* @param WPML_TM_Job_Entity $job
* @param WPML_TP_Translation_Collection $translations
*
* @return void
* @throws WPML_TP_API_Exception
*/
public function apply( WPML_TM_Job_Entity $job, WPML_TP_Translation_Collection $translations ) {
if ( ! icl_translation_add_string_translation(
$job->get_tp_id(),
$this->map_translations_to_legacy_array( $translations ),
$translations->get_target_language()
)
) {
throw new WPML_TP_API_Exception( 'Could not apply string translation!' );
}
$this->update_local_job_status( $job, ICL_TM_COMPLETE );
$this->jobs_api->update_job_state( $job, 'delivered' );
}
/**
* @param WPML_TM_Job_Entity $job
* @param int $status
*/
private function update_local_job_status( WPML_TM_Job_Entity $job, $status ) {
$this->wpdb->update(
$this->wpdb->prefix . 'icl_core_status',
array( 'status' => $status ),
array( 'id' => $job->get_id() )
);
}
private function map_translations_to_legacy_array( WPML_TP_Translation_Collection $translations ) {
$result = array();
/** @var WPML_TP_Translation $translation */
foreach ( $translations as $translation ) {
$result[ $translation->get_field() ] = $translation->get_target();
}
return $result;
}
}

View File

@@ -0,0 +1,141 @@
<?php
class WPML_TP_Apply_Translations {
/** @var WPML_TM_Jobs_Repository */
private $jobs_repository;
/** @var WPML_TP_Apply_Single_Job */
private $apply_single_job;
/** @var WPML_TP_Sync_Jobs */
private $tp_sync;
/**
* @param WPML_TM_Jobs_Repository $jobs_repository
* @param WPML_TP_Apply_Single_Job $apply_single_job
* @param WPML_TP_Sync_Jobs $tp_sync
*/
public function __construct(
WPML_TM_Jobs_Repository $jobs_repository,
WPML_TP_Apply_Single_Job $apply_single_job,
WPML_TP_Sync_Jobs $tp_sync
) {
$this->jobs_repository = $jobs_repository;
$this->apply_single_job = $apply_single_job;
$this->tp_sync = $tp_sync;
}
/**
* @param array $params
*
* @return WPML_TM_Jobs_Collection
* @throws WPML_TP_API_Exception
*/
public function apply( array $params ) {
$jobs = $this->get_jobs( $params );
if ( $this->has_in_progress_jobs( $jobs ) ) {
$jobs = $this->sync_jobs( $jobs );
}
$cancelled_jobs = $jobs->filter_by_status( ICL_TM_NOT_TRANSLATED );
$downloaded_jobs = new WPML_TM_Jobs_Collection(
$jobs->filter_by_status( ICL_TM_TRANSLATION_READY_TO_DOWNLOAD )
->map( array( $this->apply_single_job, 'apply' ) )
);
return $downloaded_jobs->append( $cancelled_jobs );
}
/**
* @param WPML_TM_Jobs_Collection $jobs
*
* @return bool
*/
private function has_in_progress_jobs( WPML_TM_Jobs_Collection $jobs ) {
return count( $jobs->filter_by_status( ICL_TM_IN_PROGRESS ) ) > 0;
}
/**
* @param array $params
*
* @return array|WPML_TM_Jobs_Collection
*/
private function get_jobs( array $params ) {
if ( $params ) {
if ( isset( $params['original_element_id'], $params['element_type'] ) ) {
$jobs = $this->get_jobs_by_original_element( $params['original_element_id'], $params['element_type'] );
} else {
$jobs = $this->get_jobs_by_ids( $params );
}
} else {
$jobs = $this->get_all_ready_jobs();
}
return $jobs;
}
/**
* @param int $original_element_id
* @param string $element_type
*
* @return WPML_TM_Jobs_Collection
*/
private function get_jobs_by_original_element( $original_element_id, $element_type ) {
$params = new WPML_TM_Jobs_Search_Params();
$params->set_scope( WPML_TM_Jobs_Search_Params::SCOPE_REMOTE );
$params->set_original_element_id( $original_element_id );
$params->set_job_types( $element_type );
return $this->jobs_repository->get( $params );
}
/**
* @param array $params
*
* @return WPML_TM_Jobs_Collection
*/
private function get_jobs_by_ids( array $params ) {
$jobs = array();
foreach ( $params as $param ) {
$jobs[] = $this->jobs_repository->get_job( $param['id'], $param['type'] );
}
return new WPML_TM_Jobs_Collection( $jobs );
}
/**
* @return WPML_TM_Jobs_Collection
*/
private function get_all_ready_jobs() {
return $this->jobs_repository->get(
new WPML_TM_Jobs_Search_Params(
array(
'status' => array( ICL_TM_TRANSLATION_READY_TO_DOWNLOAD ),
'scope' => WPML_TM_Jobs_Search_Params::SCOPE_REMOTE,
)
)
);
}
/**
* @param WPML_TM_Jobs_Collection $jobs
*
* @return WPML_TM_Jobs_Collection
* @throws WPML_TP_API_Exception
*/
private function sync_jobs( WPML_TM_Jobs_Collection $jobs ) {
$synced_jobs = $this->tp_sync->sync();
/** @var WPML_TM_Job_Entity $job */
foreach ( $jobs as $job ) {
foreach ( $synced_jobs as $synced_job ) {
if ( $job->is_equal( $synced_job ) ) {
$job->set_status( $synced_job->get_status() );
break;
}
}
}
return $jobs;
}
}

View File

@@ -0,0 +1,55 @@
<?php
use WPML\FP\Fns;
use function WPML\FP\invoke;
class WPML_TP_Translation_Collection implements IteratorAggregate {
/** @var WPML_TP_Translation[] */
private $translations;
/** @var string */
private $source_language;
/** @var string */
private $target_language;
/**
* @param WPML_TP_Translation[] $translations
* @param string $source_language
* @param string $target_language
*/
public function __construct( array $translations, $source_language, $target_language ) {
$this->translations = $translations;
$this->source_language = $source_language;
$this->target_language = $target_language;
}
/**
* @return string
*/
public function get_source_language() {
return $this->source_language;
}
/**
* @return string
*/
public function get_target_language() {
return $this->target_language;
}
public function getIterator() {
return new ArrayIterator( $this->translations );
}
/**
* @return array
*/
public function to_array() {
return [
'source_language' => $this->source_language,
'target_language' => $this->target_language,
'translations' => Fns::map( invoke( 'to_array' ), $this->translations ),
];
}
}

View File

@@ -0,0 +1,48 @@
<?php
class WPML_TP_Translation {
/** @var string */
private $field;
/** @var string */
private $source;
/** @var string */
private $target;
/**
* @param string $field
* @param string $source
* @param string $target
*/
public function __construct( $field, $source, $target ) {
$this->field = $field;
$this->source = $source;
$this->target = $target;
}
/**
* @return string
*/
public function get_field() {
return $this->field;
}
/**
* @return string
*/
public function get_source() {
return $this->source;
}
/**
* @return string
*/
public function get_target() {
return $this->target;
}
public function to_array() {
return get_object_vars( $this );
}
}

View File

@@ -0,0 +1,69 @@
<?php
class WPML_TP_Translations_Repository {
/** @var WPML_TP_XLIFF_API */
private $xliff_api;
/** @var WPML_TM_Jobs_Repository */
private $jobs_repository;
/**
* @param WPML_TP_XLIFF_API $xliff_api
* @param WPML_TM_Jobs_Repository $jobs_repository
*/
public function __construct( WPML_TP_XLIFF_API $xliff_api, WPML_TM_Jobs_Repository $jobs_repository ) {
$this->xliff_api = $xliff_api;
$this->jobs_repository = $jobs_repository;
}
/**
* @param int $job_id
* @param int $job_type
* @param bool $parse When true, it returns the parsed translation, otherwise, it returns the raw XLIFF.
*
* @return WPML_TP_Translation_Collection|string
* @throws WPML_TP_API_Exception|InvalidArgumentException
*/
public function get_job_translations( $job_id, $job_type, $parse = true ) {
$job = $this->jobs_repository->get_job( $job_id, $job_type );
if ( ! $job ) {
throw new InvalidArgumentException( 'Cannot find job' );
}
return $this->get_job_translations_by_job_entity( $job, $parse );
}
/**
* @param WPML_TM_Job_Entity $job
* @param bool $parse When true, it returns the parsed translation, otherwise, it returns the raw XLIFF.
*
* @return WPML_TP_Translation_Collection|string
* @throws WPML_TP_API_Exception
*/
public function get_job_translations_by_job_entity( WPML_TM_Job_Entity $job, $parse = true ) {
$correct_states = array( ICL_TM_TRANSLATION_READY_TO_DOWNLOAD, ICL_TM_COMPLETE );
if ( ! in_array( $job->get_status(), $correct_states, true ) ) {
throw new InvalidArgumentException( 'Job\'s translation is not ready.' );
}
if ( ! $job->get_tp_id() ) {
throw new InvalidArgumentException( 'This is only a local job.' );
}
$translations = $this->xliff_api->get_remote_translations( $job->get_tp_id(), $parse );
if ( $parse ) {
/**
* It filters translations coming from the Translation Proxy.
*
* @param \WPML_TP_Translation_Collection $translations
* @param \WPML_TM_Job_Entity $job
*/
$translations = apply_filters( 'wpml_tm_proxy_translations', $translations, $job );
}
return $translations;
}
}