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,61 @@
<?php
class WPML_TP_Sync_Ajax_Handler {
const AJAX_ACTION = 'wpml-tp-sync-job-states';
/** @var WPML_TP_Sync_Jobs */
private $tp_sync;
/** @var WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up */
private $wpml_tm_last_picked_up;
/**
* WPML_TP_Sync_Jobs constructor.
*
* @param WPML_TP_Sync_Jobs $tp_sync
* @param WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up
*/
public function __construct( WPML_TP_Sync_Jobs $tp_sync, WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up ) {
$this->tp_sync = $tp_sync;
$this->wpml_tm_last_picked_up = $wpml_tm_last_picked_up;
}
public function add_hooks() {
add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'handle' ) );
}
public function handle() {
try {
if ( isset( $_REQUEST['update_last_picked_up'] ) ) {
$this->wpml_tm_last_picked_up->set();
}
$jobs = $this->tp_sync->sync();
do_action( 'wpml_tm_empty_mail_queue' );
wp_send_json_success( $jobs->map( array( $this, 'map_job_to_result' ) ) );
return true;
} catch ( Exception $e ) {
wp_send_json_error( $e->getMessage(), 503 );
return false;
}
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return array
*/
public function map_job_to_result( WPML_TM_Job_Entity $job ) {
return array(
'id' => $job->get_id(),
'type' => $job->get_type(),
'status' => $job->get_status(),
'hasCompletedTranslation' => $job->has_completed_translation(),
'needsUpdate' => $job->does_need_update(),
);
}
}

View File

@@ -0,0 +1,10 @@
<?php
class WPML_TM_Sync_Installer_Wrapper {
/**
* @return bool
*/
public function is_wpml_registered() {
return (bool) WP_Installer::instance()->get_site_key( 'wpml' );
}
}

View File

@@ -0,0 +1,62 @@
<?php
class WPML_TM_Sync_Jobs_Revision {
/** @var WPML_TM_Jobs_Repository */
private $jobs_repository;
/** @var WPML_TP_Jobs_API */
private $tp_api;
/**
* WPML_TM_Sync_Jobs_Revision constructor.
*
* @param WPML_TM_Jobs_Repository $jobs_repository
* @param WPML_TP_Jobs_API $tp_api
*/
public function __construct( WPML_TM_Jobs_Repository $jobs_repository, WPML_TP_Jobs_API $tp_api ) {
$this->jobs_repository = $jobs_repository;
$this->tp_api = $tp_api;
}
/**
* @return WPML_TM_Job_Entity[]
* @throws WPML_TP_API_Exception
*/
public function sync() {
$result = array();
$tp_statuses_of_revised_jobs = $this->tp_api->get_revised_jobs();
if ( $tp_statuses_of_revised_jobs ) {
$revised_jobs = array();
foreach ( $tp_statuses_of_revised_jobs as $tp_job_status ) {
$revised_jobs[ $tp_job_status->get_tp_id() ] = $tp_job_status->get_revision();
}
$job_search = new WPML_TM_Jobs_Search_Params(
array(
'scope' => WPML_TM_Jobs_Search_Params::SCOPE_REMOTE,
'tp_id' => array_keys( $revised_jobs ),
)
);
/** @var WPML_TM_Job_Entity $job */
foreach ( $this->jobs_repository->get( $job_search ) as $job ) {
if ( isset( $revised_jobs[ $job->get_tp_id() ] ) && $job->get_revision() < $revised_jobs[ $job->get_tp_id() ] ) {
$job->set_status( WPML_TP_Job_States::map_tp_state_to_local( WPML_TP_Job_States::TRANSLATION_READY ) );
$job->set_revision( $revised_jobs[ $job->get_tp_id() ] );
$result[] = $job;
do_action( 'wpml_tm_revised_job_notification', $job->get_id() );
}
}
}
return $result;
}
}

View File

@@ -0,0 +1,79 @@
<?php
class WPML_TM_Sync_Jobs_Status {
/** @var WPML_TM_Jobs_Repository */
private $jobs_repository;
/** @var WPML_TP_Jobs_API */
private $tp_api;
/**
* WPML_TM_Sync_Jobs_Status constructor.
*
* @param WPML_TM_Jobs_Repository $jobs_repository
* @param WPML_TP_Jobs_API $tp_api
*/
public function __construct( WPML_TM_Jobs_Repository $jobs_repository, WPML_TP_Jobs_API $tp_api ) {
$this->jobs_repository = $jobs_repository;
$this->tp_api = $tp_api;
}
/**
* @return WPML_TM_Jobs_Collection
* @throws WPML_TP_API_Exception
*/
public function sync() {
return $this->update_tp_state_of_jobs(
$this->jobs_repository->get(
new WPML_TM_Jobs_Search_Params(
array(
'status' => array( ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ),
'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 update_tp_state_of_jobs( WPML_TM_Jobs_Collection $jobs ) {
$tp_ids = $this->extract_tp_id_from_jobs( $jobs );
if ( $tp_ids ) {
$tp_statuses = $this->tp_api->get_jobs_statuses( $tp_ids );
foreach ( $tp_statuses as $job_status ) {
$job = $jobs->get_by_tp_id( $job_status->get_tp_id() );
if ( $job ) {
$job->set_status( WPML_TP_Job_States::map_tp_state_to_local( $job_status->get_status() ) );
$job->set_ts_status( $job_status->get_ts_status() );
if ( WPML_TP_Job_States::CANCELLED === $job_status->get_status() ) {
do_action( 'wpml_tm_canceled_job_notification', $job );
}
}
}
}
return $jobs;
}
/**
* @param WPML_TM_Jobs_Collection $jobs
*
* @return array
*/
private function extract_tp_id_from_jobs( WPML_TM_Jobs_Collection $jobs ) {
$tp_ids = array();
foreach ( $jobs as $job ) {
$tp_ids[] = $job->get_tp_id();
}
return $tp_ids;
}
}

View File

@@ -0,0 +1,44 @@
<?php
class WPML_TP_Sync_Jobs {
/** @var WPML_TM_Sync_Jobs_Status */
private $jobs_status_sync;
/** @var WPML_TM_Sync_Jobs_Revision */
private $jobs_revision_sync;
/** @var WPML_TP_Sync_Update_Job */
private $update_job;
/**
* WPML_TP_Sync_Jobs constructor.
*
* @param WPML_TM_Sync_Jobs_Status $jobs_status_sync
* @param WPML_TM_Sync_Jobs_Revision $jobs_revision_sync
* @param WPML_TP_Sync_Update_Job $update_job
*/
public function __construct(
WPML_TM_Sync_Jobs_Status $jobs_status_sync,
WPML_TM_Sync_Jobs_Revision $jobs_revision_sync,
WPML_TP_Sync_Update_Job $update_job
) {
$this->jobs_status_sync = $jobs_status_sync;
$this->jobs_revision_sync = $jobs_revision_sync;
$this->update_job = $update_job;
}
/**
* @return WPML_TM_Jobs_Collection
* @throws WPML_TP_API_Exception
*/
public function sync() {
return new WPML_TM_Jobs_Collection(
$this->jobs_status_sync
->sync()
->append( $this->jobs_revision_sync->sync() )
->filter_by_status( array( ICL_TM_IN_PROGRESS, ICL_TM_WAITING_FOR_TRANSLATOR ), true )
->map( array( $this->update_job, 'update_state' ) )
);
}
}

View File

@@ -0,0 +1,147 @@
<?php
use WPML\FP\Relation;
use \WPML\LIB\WP\Post;
class WPML_TP_Sync_Update_Job {
private $strategies = array(
WPML_TM_Job_Entity::POST_TYPE => 'update_post_job',
WPML_TM_Job_Entity::STRING_TYPE => 'update_string_job',
WPML_TM_Job_Entity::PACKAGE_TYPE => 'update_post_job',
WPML_TM_Job_Entity::STRING_BATCH => 'update_post_job',
);
/** @var wpdb */
private $wpdb;
/** @var SitePress */
private $sitepress;
/**
* @param wpdb $wpdb
*/
public function __construct( wpdb $wpdb, SitePress $sitepress ) {
$this->wpdb = $wpdb;
$this->sitepress = $sitepress;
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TM_Job_Entity
*/
public function update_state( WPML_TM_Job_Entity $job ) {
if ( ! array_key_exists( $job->get_type(), $this->strategies ) ) {
return $job;
}
$method = $this->strategies[ $job->get_type() ];
return call_user_func( array( $this, $method ), $job );
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TM_Job_Entity
*/
private function update_string_job( WPML_TM_Job_Entity $job ) {
if ( $job->get_tp_id() ) {
$this->wpdb->update(
$this->wpdb->prefix . 'icl_core_status',
array(
'status' => $job->get_status(),
'tp_revision' => $job->get_revision(),
'ts_status' => $this->get_ts_status_in_ts_format( $job ),
),
array( 'rid' => $job->get_tp_id() )
);
}
$data = array(
'status' => $job->get_status(),
);
if ( ICL_TM_NOT_TRANSLATED === $job->get_status() ) {
$data['translator_id'] = null;
}
$this->wpdb->update(
$this->wpdb->prefix . 'icl_string_translations',
$data,
array( 'id' => $job->get_id() )
);
icl_update_string_status( $job->get_original_element_id() );
return $job;
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TM_Job_Entity
*/
private function update_post_job( WPML_TM_Job_Entity $job ) {
$job_id = $job->get_id();
if ( $job->get_status() === ICL_TM_NOT_TRANSLATED ) {
$prev_status = $this->get_job_prev_status( $job_id );
if ( $prev_status && Relation::propEq( 'needs_update', '1', $prev_status ) ) {
$this->wpdb->update( $this->wpdb->prefix . 'icl_translation_status', $prev_status, [ 'rid' => $job_id ] );
$job->set_needs_update( true );
return $job;
}
}
$this->wpdb->update(
$this->wpdb->prefix . 'icl_translation_status',
array(
'status' => $job->get_status(),
'tp_revision' => $job->get_revision(),
'ts_status' => $this->get_ts_status_in_ts_format( $job ),
),
array( 'rid' => $job_id )
);
if (
ICL_TM_NOT_TRANSLATED === $job->get_status()
&& ( $post_type = Post::getType( $job->get_original_element_id() ) )
) {
$this->sitepress->delete_orphan_element(
$job->get_original_element_id(),
'post_' . $post_type,
$job->get_target_language()
);
}
return $job;
}
private function get_job_prev_status( $job_id ) {
$previous_state = $this->wpdb->get_var(
$this->wpdb->prepare(
"SELECT _prevstate
FROM {$this->wpdb->prefix}icl_translation_status
WHERE rid=%d
LIMIT 1",
$job_id
)
);
return unserialize( $previous_state );
}
/**
* In the db, we store the exact json format that we get from TS. It includes an extra ts_status key
*
* @param WPML_TM_Job_Entity $job
*
* @return string
*/
private function get_ts_status_in_ts_format( WPML_TM_Job_Entity $job ) {
$ts_status = $job->get_ts_status();
return $ts_status ? wp_json_encode( array( 'ts_status' => json_decode( (string) $ts_status ) ) ) : null;
}
}

View File

@@ -0,0 +1,15 @@
<?php
class WPML_TP_Sync_Orphan_Jobs_Factory {
/**
* @return WPML_TP_Sync_Orphan_Jobs
*/
public function create() {
global $wpdb, $sitepress;
return new WPML_TP_Sync_Orphan_Jobs(
wpml_tm_get_jobs_repository(),
new WPML_TP_Sync_Update_Job( $wpdb, $sitepress )
);
}
}

View File

@@ -0,0 +1,45 @@
<?php
class WPML_TP_Sync_Orphan_Jobs {
/** @var WPML_TM_Jobs_Repository */
private $jobs_repository;
/** @var WPML_TP_Sync_Update_Job */
private $update_job;
/**
* @param WPML_TM_Jobs_Repository $jobs_repository
* @param WPML_TP_Sync_Update_Job $update_job
*/
public function __construct( WPML_TM_Jobs_Repository $jobs_repository, WPML_TP_Sync_Update_Job $update_job ) {
$this->jobs_repository = $jobs_repository;
$this->update_job = $update_job;
}
/**
* @return WPML_TM_Jobs_Collection
*/
public function cancel_orphans() {
$params = new WPML_TM_Jobs_Search_Params(
array(
'scope' => WPML_TM_Jobs_Search_Params::SCOPE_REMOTE,
'tp_id' => 0,
'status' => array( ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ),
)
);
return $this->jobs_repository->get( $params )->map( array( $this, 'cancel_job' ), true );
}
/**
* @param WPML_TM_Job_Entity $job
*
* @return WPML_TM_Job_Entity
*/
public function cancel_job( WPML_TM_Job_Entity $job ) {
$job->set_status( ICL_TM_NOT_TRANSLATED );
return $this->update_job->update_state( $job );
}
}