first commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\ATE\Download;
|
||||
|
||||
use Exception;
|
||||
use WPML\TM\ATE\ReturnedJobsQueue;
|
||||
use WPML_TM_ATE_API;
|
||||
use WPML_TM_ATE_Jobs;
|
||||
|
||||
class Consumer {
|
||||
|
||||
/** @var WPML_TM_ATE_API $ateApi */
|
||||
private $ateApi;
|
||||
|
||||
/** @var WPML_TM_ATE_Jobs $ateJobs */
|
||||
private $ateJobs;
|
||||
|
||||
public function __construct( WPML_TM_ATE_API $ateApi, WPML_TM_ATE_Jobs $ateJobs ) {
|
||||
$this->ateApi = $ateApi;
|
||||
$this->ateJobs = $ateJobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
*
|
||||
* @return Job|false
|
||||
* @throws Exception
|
||||
*/
|
||||
public function process( Job $job ) {
|
||||
$xliffContent = $this->ateApi->get_remote_xliff_content( $job->url );
|
||||
$wpmlJobId = $this->ateJobs->apply( $xliffContent );
|
||||
|
||||
if ( $wpmlJobId ) {
|
||||
$processedJob = clone $job;
|
||||
$processedJob->wpmlJobId = $wpmlJobId;
|
||||
|
||||
ReturnedJobsQueue::remove( $wpmlJobId );
|
||||
|
||||
return $processedJob;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\ATE\Download;
|
||||
|
||||
class Job {
|
||||
|
||||
/** @var int $ateJobId */
|
||||
public $ateJobId;
|
||||
|
||||
/** @var string $url */
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* This property is not part of the database data,
|
||||
* but it can be added when the job is downloaded
|
||||
* to provide more information to the UI.
|
||||
*
|
||||
* @var int $wpmlJobId
|
||||
*/
|
||||
public $wpmlJobId;
|
||||
|
||||
/**
|
||||
* @param \stdClass $item
|
||||
*
|
||||
* @return Job
|
||||
*/
|
||||
public static function fromAteResponse( \stdClass $item ) {
|
||||
$job = new self();
|
||||
$job->ateJobId = $item->ate_id;
|
||||
$job->url = $item->download_link;
|
||||
|
||||
return $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $row
|
||||
*
|
||||
* @return Job
|
||||
*/
|
||||
public static function fromDb( \stdClass $row ) {
|
||||
$job = new self();
|
||||
$job->ateJobId = $row->editor_job_id;
|
||||
$job->url = $row->download_url;
|
||||
|
||||
return $job;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\ATE\Download;
|
||||
|
||||
use Exception;
|
||||
use WPML\Collect\Support\Collection;
|
||||
use WPML\TM\ATE\Log\Entry;
|
||||
use WPML\TM\ATE\Log\ErrorEvents;
|
||||
use WPML_TM_ATE_API;
|
||||
|
||||
class Process {
|
||||
|
||||
/** @var Queue $queue */
|
||||
private $queue;
|
||||
|
||||
/** @var Consumer $consumer */
|
||||
private $consumer;
|
||||
|
||||
/** @var WPML_TM_ATE_API $ateApi */
|
||||
private $ateApi;
|
||||
|
||||
public function __construct( Queue $queue, Consumer $consumer, WPML_TM_ATE_API $ateApi ) {
|
||||
$this->queue = $queue;
|
||||
$this->consumer = $consumer;
|
||||
$this->ateApi = $ateApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $quantity
|
||||
*
|
||||
* @return Result
|
||||
*/
|
||||
public function run( $quantity = 5 ) {
|
||||
$result = new Result();
|
||||
$job = $processedJob = null;
|
||||
|
||||
do {
|
||||
try {
|
||||
$job = $this->queue->getFirst();
|
||||
|
||||
if ( $job ) {
|
||||
$this->queue->remove( $job );
|
||||
$processedJob = $this->consumer->process( $job );
|
||||
|
||||
if ( ! $processedJob ) {
|
||||
throw new Exception( 'The translation job could not be applied.' );
|
||||
}
|
||||
|
||||
$result->processedJobs->push( $processedJob );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$this->logException( $e, $processedJob ?: $job );
|
||||
}
|
||||
|
||||
$processedJob = null;
|
||||
$quantity--;
|
||||
} while ( $quantity && $job );
|
||||
|
||||
$this->acknowledgeAte( $result->processedJobs );
|
||||
|
||||
$result->downloadQueueSize = $this->queue->count();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function acknowledgeAte( Collection $processedJobs ) {
|
||||
if ( $processedJobs->count() ) {
|
||||
$this->ateApi->confirm_received_job( $processedJobs->pluck( 'ateJobId' )->toArray() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $e
|
||||
* @param Job|null $job
|
||||
*/
|
||||
private function logException( Exception $e, Job $job = null ) {
|
||||
$entry = new Entry();
|
||||
$entry->description = $e->getMessage();
|
||||
|
||||
if ( $job ) {
|
||||
$entry->ateJobId = $job->ateJobId;
|
||||
$entry->wpmlJobId = $job->wpmlJobId;
|
||||
$entry->extraData = [ 'downloadUrl' => $job->url ];
|
||||
}
|
||||
|
||||
if ( $e instanceof \Requests_Exception ) {
|
||||
$entry->event = ErrorEvents::SERVER_XLIFF;
|
||||
} else {
|
||||
$entry->event = ErrorEvents::JOB_DOWNLOAD;
|
||||
}
|
||||
|
||||
wpml_tm_ate_ams_log( $entry );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\ATE\Download;
|
||||
|
||||
use WPML\Collect\Support\Collection;
|
||||
use WPML\TM\Upgrade\Commands\CreateAteDownloadQueueTable;
|
||||
|
||||
class Queue {
|
||||
|
||||
/** @var \wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
public function __construct( \wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $jobs A collection of `Job`
|
||||
*/
|
||||
public function push( Collection $jobs ) {
|
||||
if ( ! $jobs->count() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prepare = function( Job $job ) {
|
||||
return $this->wpdb->prepare( '(%d,%s)', $job->ateJobId, $job->url );
|
||||
};
|
||||
|
||||
$columns = '(editor_job_id, download_url)';
|
||||
$values = $jobs->map( $prepare )->implode( ',' );
|
||||
|
||||
$this->wpdb->query(
|
||||
"INSERT IGNORE INTO {$this->getTableName()} {$columns} VALUES {$values}"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEditorJobIds() {
|
||||
return wpml_collect( $this->wpdb->get_col( "SELECT editor_job_id FROM {$this->getTableName()}" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count() {
|
||||
return (int) $this->wpdb->get_var( "SELECT COUNT(*) FROM {$this->getTableName()}" );
|
||||
}
|
||||
|
||||
/** @return Job|null */
|
||||
public function getFirst() {
|
||||
$job = null;
|
||||
|
||||
$this->wpdb->query( 'START TRANSACTION' );
|
||||
|
||||
$row = $this->getFirstUnlockedRow();
|
||||
|
||||
if ( $row ) {
|
||||
$job = Job::fromDb( $row );
|
||||
$this->lockJob( $job );
|
||||
}
|
||||
|
||||
$this->wpdb->query( 'COMMIT' );
|
||||
|
||||
return $job;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \stdClass|null
|
||||
*/
|
||||
private function getFirstUnlockedRow() {
|
||||
$oldLockTimestamp = time() - self::getLockExpiration();
|
||||
|
||||
return $this->wpdb->get_row(
|
||||
$this->wpdb->prepare(
|
||||
"SELECT * FROM {$this->getTableName()}
|
||||
WHERE lock_timestamp IS NULL OR lock_timestamp < %d
|
||||
LIMIT 1
|
||||
FOR UPDATE",
|
||||
$oldLockTimestamp
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function lockJob( Job $job ) {
|
||||
$this->wpdb->query(
|
||||
$this->wpdb->prepare(
|
||||
"UPDATE {$this->getTableName()} SET lock_timestamp=%d WHERE editor_job_id=%d",
|
||||
time(),
|
||||
$job->ateJobId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function remove( Job $job ) {
|
||||
$this->wpdb->delete(
|
||||
$this->getTableName(),
|
||||
[ 'editor_job_id' => $job->ateJobId ],
|
||||
[ '%d' ]
|
||||
);
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function getTableName() {
|
||||
return $this->wpdb->prefix . CreateAteDownloadQueueTable::TABLE_NAME;
|
||||
}
|
||||
|
||||
/** @return int */
|
||||
public static function getLockExpiration() {
|
||||
return 3 * MINUTE_IN_SECONDS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
|
||||
namespace WPML\TM\ATE\Download;
|
||||
|
||||
use WPML\Collect\Support\Collection;
|
||||
|
||||
class Result {
|
||||
|
||||
/** @var Collection $processedJobs */
|
||||
public $processedJobs;
|
||||
|
||||
/** @var int $downloadQueueSize */
|
||||
public $downloadQueueSize = 0;
|
||||
|
||||
public function __construct() {
|
||||
$this->processedJobs = wpml_collect( [] );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user