File: /var/www/zaklada/wp-content/plugins/wpml-translation-management/classes/ATE/JobRecords.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() );
}
}
}
}