206 lines
4.3 KiB
PHP
206 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace WPML\TM\ATE;
|
|
|
|
use Exception;
|
|
use WPML\Collect\Support\Collection;
|
|
use WPML_TM_ATE_API_Error;
|
|
use WPML_TM_Editors;
|
|
|
|
class JobRecords {
|
|
|
|
const FIELD_ATE_JOB_ID = 'ate_job_id';
|
|
const FIELD_IS_EDITING = 'is_editing';
|
|
|
|
/** @var \wpdb $wpdb */
|
|
private $wpdb;
|
|
|
|
/** @var Collection $jobs */
|
|
private $jobs;
|
|
|
|
public function __construct( \wpdb $wpdb ) {
|
|
$this->wpdb = $wpdb;
|
|
$this->jobs = wpml_collect( [] );
|
|
}
|
|
|
|
/**
|
|
* This method will retrieve data from the ATE job ID.
|
|
* Beware of the returned data shape which is not standard.
|
|
*
|
|
* @param int $ateJobId
|
|
*
|
|
* @return array|null
|
|
*/
|
|
public function get_data_from_ate_job_id( $ateJobId ) {
|
|
$ateJobId = (int) $ateJobId;
|
|
|
|
$this->warmCache( [], [ $ateJobId ] );
|
|
|
|
$job = $this->jobs->first(
|
|
function( JobRecord $job ) use ( $ateJobId ) {
|
|
return $job->ateJobId === $ateJobId;
|
|
}
|
|
);
|
|
|
|
if ( $job ) {
|
|
/** @var JobRecord $job */
|
|
return [
|
|
'wpml_job_id' => $job->wpmlJobId,
|
|
'ate_job_data' => [
|
|
'ate_job_id' => $job->ateJobId,
|
|
],
|
|
];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param int $wpmlJobId
|
|
* @param array $ateJobData
|
|
*/
|
|
public function store( $wpmlJobId, array $ateJobData ) {
|
|
$ateJobData['job_id'] = (int) $wpmlJobId;
|
|
|
|
$this->warmCache( [ $wpmlJobId ] );
|
|
$job = $this->jobs->get( $wpmlJobId );
|
|
|
|
if ( ! $job ) {
|
|
$job = new JobRecord();
|
|
$job->wpmlJobId = (int) $wpmlJobId;
|
|
}
|
|
|
|
if ( isset( $ateJobData[ self::FIELD_ATE_JOB_ID ] ) ) {
|
|
$job->ateJobId = $ateJobData[ self::FIELD_ATE_JOB_ID ];
|
|
}
|
|
|
|
$this->persist( $job );
|
|
}
|
|
|
|
/**
|
|
* @param JobRecord $job
|
|
*/
|
|
public function persist( JobRecord $job ) {
|
|
$this->jobs->put( $job->wpmlJobId, $job );
|
|
|
|
$this->wpdb->update(
|
|
$this->wpdb->prefix . 'icl_translate_job',
|
|
[ 'editor_job_id' => $job->ateJobId ],
|
|
[ 'job_id' => $job->wpmlJobId ],
|
|
[ '%d' ],
|
|
[ '%d' ]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* This method will load in-memory the required jobs.
|
|
*
|
|
* @param array $wpmlJobIds
|
|
* @param array $ateJobIds
|
|
*/
|
|
public function warmCache( array $wpmlJobIds, array $ateJobIds = [] ) {
|
|
$wpmlJobIds = wpml_collect( $wpmlJobIds )->reject( $this->isAlreadyLoaded( 'wpmlJobId' ) )->toArray();
|
|
$ateJobIds = wpml_collect( $ateJobIds )->reject( $this->isAlreadyLoaded( 'ateJobId' ) )->toArray();
|
|
|
|
$where = [];
|
|
|
|
if ( $wpmlJobIds ) {
|
|
$where[] = 'job_id IN(' . wpml_prepare_in( $wpmlJobIds, '%d' ) . ')';
|
|
}
|
|
|
|
if ( $ateJobIds ) {
|
|
$where[] = 'editor_job_id IN(' . wpml_prepare_in( $ateJobIds, '%d' ) . ')';
|
|
}
|
|
|
|
if ( ! $where ) {
|
|
return;
|
|
}
|
|
|
|
$whereHasJobIds = implode( ' OR ', $where );
|
|
|
|
$rows = $this->wpdb->get_results(
|
|
"
|
|
SELECT job_id, editor_job_id
|
|
FROM {$this->wpdb->prefix}icl_translate_job
|
|
WHERE editor = '" . WPML_TM_Editors::ATE . "' AND ({$whereHasJobIds})
|
|
"
|
|
);
|
|
|
|
foreach ( $rows as $row ) {
|
|
$job = new JobRecord( $row );
|
|
$this->jobs->put( $job->wpmlJobId, $job );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $idPropertyName
|
|
*
|
|
* @return \Closure
|
|
*/
|
|
private function isAlreadyLoaded( $idPropertyName ) {
|
|
$loadedIds = $this->jobs->pluck( $idPropertyName )->values()->toArray();
|
|
|
|
return function( $jobId ) use ( $loadedIds ) {
|
|
return in_array( $jobId, $loadedIds, true );
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param int $wpmlJobId
|
|
*
|
|
* @return int
|
|
*/
|
|
public function get_ate_job_id( $wpmlJobId ) {
|
|
return $this->get( $wpmlJobId )->ateJobId;
|
|
}
|
|
|
|
/**
|
|
* @param int $wpmlJobId
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_editing_job( $wpmlJobId ) {
|
|
return $this->get( $wpmlJobId )->isEditing();
|
|
}
|
|
|
|
/**
|
|
* @param $wpmlJobId
|
|
*
|
|
* @return JobRecord
|
|
*/
|
|
public function get( $wpmlJobId ) {
|
|
if ( ! $this->jobs->has( $wpmlJobId ) ) {
|
|
$this->warmCache( [ (int) $wpmlJobId ] );
|
|
}
|
|
|
|
/** @var null|JobRecord $job */
|
|
$job = $this->jobs->get( $wpmlJobId );
|
|
|
|
if ( ! $job || ! $job->ateJobId ) {
|
|
$this->restoreJobDataFromATE( $wpmlJobId );
|
|
$job = $this->jobs->get( $wpmlJobId, new JobRecord() );
|
|
}
|
|
|
|
return $job;
|
|
}
|
|
|
|
/**
|
|
* This method will try to recover the job data from ATE server,
|
|
* and persist it in the local repository.
|
|
*
|
|
* @param int $wpmlJobId
|
|
*/
|
|
private function restoreJobDataFromATE( $wpmlJobId ) {
|
|
$data = apply_filters( 'wpml_tm_ate_job_data_fallback', [], $wpmlJobId );
|
|
|
|
if ( $data ) {
|
|
try {
|
|
$this->store( $wpmlJobId, $data );
|
|
} catch ( Exception $e ) {
|
|
$error_log = new WPML_TM_ATE_API_Error();
|
|
$error_log->log( $e->getMessage() );
|
|
}
|
|
}
|
|
}
|
|
}
|