Files
doitinpoland.com/wp-content/plugins/sitepress-multilingual-cms/inc/translation-jobs/jobs/wpml-element-translation-job.class.php
2023-09-12 21:41:04 +02:00

394 lines
12 KiB
PHP

<?php
require_once WPML_TM_PATH . '/inc/translation-jobs/jobs/wpml-translation-job.class.php';
use WPML\FP\Obj;
abstract class WPML_Element_Translation_Job extends WPML_Translation_Job {
protected $original_del_text;
/** @var WPML_Translation_Job_Factory $job_factory */
protected $job_factory;
private $original_doc_id = false;
private $translation_id = false;
/**
* @param int $job_id
* @param null|int $batch_id
* @param null|TranslationManagement $tm_instance
* @param null|WPML_Translation_Job_Factory $job_factory
*/
function __construct( $job_id, $batch_id = null, &$tm_instance = null, $job_factory = null ) {
parent::__construct( $job_id, $batch_id, $tm_instance );
$this->original_del_text = __( 'The original has been deleted!', 'sitepress' );
$this->job_factory = $job_factory ?: wpml_tm_load_job_factory();
}
function get_type() {
return 'Post';
}
function to_array() {
$this->maybe_load_basic_data();
$data_array = $this->basic_data_to_array( $this->basic_data );
$data_array['id'] = Obj::prop('job_id', $this->basic_data);
$data_array['translation_id'] = Obj::prop('translation_id', $this->basic_data);
$data_array['status'] = $this->get_status();
$data_array['translation_edit_url'] = $this->get_url();
$data_array['original_url'] = $this->get_url( true );
$data_array['post_title'] = esc_html( $this->get_title() );
return $data_array;
}
function to_xliff_file() {
$xliff = new WPML_TM_Xliff_Writer( $this->job_factory );
return $xliff->get_job_xliff_file( $this->get_id() );
}
function get_original_element_id() {
if ( ! $this->original_doc_id ) {
$this->original_doc_id = $this->get_iclt_field( 'element_id', false );
}
return $this->original_doc_id;
}
function get_translation_id() {
if ( ! $this->translation_id ) {
$translation_id = $this->get_iclt_field( 'translation_id', true );
$this->translation_id = $translation_id;
} else {
$translation_id = $this->translation_id;
}
return $translation_id;
}
/**
* Saves the job data in this object to the database (e.g. to a post)
*
* @param bool $complete whether or not to set the status
* of the target element to complete
*/
public function save_to_element( $complete = false ) {
global $wpdb, $wpml_post_translations, $wpml_term_translations;
$wpml_tm_records = new WPML_TM_Records( $wpdb, $wpml_post_translations, $wpml_term_translations );
$save_data_action = new WPML_Save_Translation_Data_Action(
array(
'job_id' => $this->get_id(),
'complete' => $complete,
'fields' => array(),
),
$wpml_tm_records
);
$save_data_action->save_translation();
}
/**
* @return int
*/
function estimate_word_count() {
$fields = $this->get_original_fields();
$combined_string = join( ' ', $fields );
$calculator = new WPML_TM_Word_Calculator( new WPML_PHP_Functions() );
return $calculator->count_words( $combined_string, $this->get_source_language_code() );
}
function get_original_fields() {
global $wpdb;
$fields = $wpdb->get_results(
$wpdb->prepare(
"SELECT field_type, field_data, field_format
FROM {$wpdb->prefix}icl_translate
WHERE job_id = %d
AND field_translate = 1",
$this->get_id()
)
);
$res = array();
foreach ( $fields as $field ) {
$res[ $field->field_type ] = base64_decode( $field->field_data );
}
return $res;
}
public function cancel() {
global $wpdb;
$deleted = false;
$rid_query = "SELECT rid FROM {$wpdb->prefix}icl_translate_job WHERE job_id=%d";
$rid_prepare = $wpdb->prepare( $rid_query, array( $this->job_id ) );
$rid = $wpdb->get_var( $rid_prepare );
$translation_id_query = "SELECT translation_id FROM {$wpdb->prefix}icl_translation_status WHERE rid=%d";
$translation_id_prepare = $wpdb->prepare( $translation_id_query, array( $rid ) );
$translation_id = $wpdb->get_var( $translation_id_prepare );
if ( $rid ) {
$wpdb->delete( $wpdb->prefix . 'icl_translate_job', array( 'job_id' => $this->job_id ) );
$wpdb->delete( $wpdb->prefix . 'icl_translate', array( 'job_id' => $this->job_id ) );
$deleted = true;
}
if ( $translation_id ) {
$wpdb->delete( $wpdb->prefix . 'icl_translations', array( 'translation_id' => $translation_id ) );
if ( $rid ) {
$wpdb->delete(
$wpdb->prefix . 'icl_translation_status',
array(
'translation_id' => $translation_id,
'rid' => $rid,
)
);
}
}
return $deleted;
}
/**
* @param TranslationProxy_Project $project
* @param int $translator_id
* @param WPML_TM_CMS_ID $cms_id_helper
* @param TranslationManagement $tm_instance
* @param null|string $note
*
* @return array
*/
function send_to_tp( $project, $translator_id, &$cms_id_helper, &$tm_instance, $note = null ) {
global $wpdb;
$this->maybe_load_basic_data();
$file = $this->to_xliff_file();
$title = $this->get_title();
$cms_id = $cms_id_helper->cms_id_from_job_id( $this->get_id() );
$url = $this->get_url( true );
$word_count = $this->estimate_word_count();
$note = isset( $note ) ? $note : '';
$source_language = $this->get_source_language_code();
$target_language = $this->get_language_code();
$uuid = $this->get_uuid();
try {
$tp_job_id = $project->send_to_translation_batch_mode( $file, $title, $cms_id, $url, $source_language, $target_language, $word_count, $translator_id, $note, $uuid );
} catch ( Exception $err ) {
// The translation entry will be removed
$project->errors[] = $err;
$tp_job_id = 0;
}
$translation_id = $this->get_translation_id();
if ( $tp_job_id ) {
$tm_instance->update_translation_status(
array(
'translation_id' => $translation_id,
'translator_id' => $translator_id,
'status' => ICL_TM_IN_PROGRESS,
'needs_update' => 0,
)
);
} else {
$previous_state = $wpdb->get_var(
$wpdb->prepare(
" SELECT _prevstate
FROM {$wpdb->prefix}icl_translation_status
WHERE translation_id=%d
LIMIT 1",
$translation_id
)
);
if ( ! empty( $previous_state ) ) {
$previous_state = unserialize( $previous_state );
$data = array(
'status' => $previous_state['status'],
'translator_id' => $previous_state['translator_id'],
'needs_update' => $previous_state['needs_update'],
'md5' => $previous_state['md5'],
'translation_service' => $previous_state['translation_service'],
'translation_package' => $previous_state['translation_package'],
'timestamp' => $previous_state['timestamp'],
'links_fixed' => $previous_state['links_fixed'],
);
$data_where = array( 'translation_id' => $translation_id );
$wpdb->update( $wpdb->prefix . 'icl_translation_status', $data, $data_where );
} else {
$data = array(
'status' => ICL_TM_NOT_TRANSLATED,
'needs_update' => 0,
);
$data_where = array( 'translation_id' => $translation_id );
$wpdb->update( $wpdb->prefix . 'icl_translation_status', $data, $data_where );
}
$err = true;
}
return array( isset( $err ) ? $err : false, $project, $tp_job_id );
}
/**
* @param bool|false $original
*
* @return string
*/
abstract function get_url( $original = false );
/**
* @return WP_Post|WPML_Package|mixed
*/
abstract function get_original_document();
protected function load_status() {
$this->maybe_load_basic_data();
$status = ! empty( $this->basic_data->translated ) ? ICL_TM_COMPLETE : Obj::prop('status', $this->basic_data);
return TranslationManagement::get_job_status_string( $status, Obj::prop( 'needs_update', $this->basic_data ) );
}
/**
* @param int $job_id
*
* @return bool|stdClass|WPML_Element_Translation_Job
*/
protected function load_job_data( $job_id ) {
if ( $this->job_factory ) {
return $this->job_factory->get_translation_job( $job_id, false, 1 );
}
return false;
}
protected function save_updated_assignment() {
global $wpdb;
$job_id = $this->get_id();
$service = $this->get_translation_service();
list( $prev_translator_id, $rid ) = $wpdb->get_row( $wpdb->prepare( "SELECT translator_id, rid FROM {$wpdb->prefix}icl_translate_job WHERE job_id=%d", $job_id ), ARRAY_N );
$translator_id = $this->get_translator_id();
$assigned_correctly = $translator_id == $prev_translator_id;
$assigned_correctly = apply_filters( 'wpml_job_assigned_to_after_assignment', $assigned_correctly, $job_id, $translator_id, $service );
if ( $assigned_correctly ) {
return true;
}
$data = array(
'translator_id' => $translator_id,
'status' => ICL_TM_WAITING_FOR_TRANSLATOR,
'translation_service' => $service,
);
$data_where = array( 'rid' => $rid );
$wpdb->update( $wpdb->prefix . 'icl_translation_status', $data, $data_where );
$wpdb->update( $wpdb->prefix . 'icl_translate_job', array( 'translator_id' => $translator_id ), array( 'job_id' => $job_id ) );
return true;
}
/**
* Retrieves the batch ID for job elements using the
* `icl_translation_status` and `icl_translate_job` tables
*/
protected function load_batch_id() {
global $wpdb;
$this->batch_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT batch_id
FROM {$wpdb->prefix}icl_translation_status as ts
LEFT JOIN {$wpdb->prefix}icl_translate_job as tj ON tj.rid = ts.rid
WHERE tj.job_id = %d AND tj.revision IS NULL
LIMIT 1",
$this->job_id
)
);
}
private function get_iclt_field( $field_name, $translation ) {
global $wpdb;
$column_name = ( $translation === true ? 'i' : 'o' ) . '.' . $field_name;
$query = " SELECT {$column_name}
FROM {$wpdb->prefix}icl_translations o
JOIN {$wpdb->prefix}icl_translations i
ON i.trid = o.trid
AND i.source_language_code = o.language_code
JOIN {$wpdb->prefix}icl_translation_status s
ON s.translation_id = i.translation_id
JOIN {$wpdb->prefix}icl_translate_job j
ON j.rid = s.rid
WHERE j.job_id = %d
LIMIT 1";
$args = array( $this->get_id() );
$prepared_query = $wpdb->prepare( $query, $args );
return $wpdb->get_var( $prepared_query );
}
/**
* If the job does not have deadline date,
* we consider that the job was completed on time.
*
* @return bool
*/
public function is_completed_on_time() {
return $this->get_number_of_days_overdue() <= 0;
}
/**
* @return false|int Negative integer if the job was completed before the deadline, or positive either.
* False is the job has no deadline date
*/
public function get_number_of_days_overdue() {
$deadline = $this->get_deadline_date();
$completed = $this->get_completed_date();
if ( ! $deadline ) {
return false;
}
if ( ! $completed ) {
$completed = strtotime( 'now' );
} else {
$completed = strtotime( $completed );
}
$deadline = strtotime( $deadline );
return (int) floor( ( $completed - $deadline ) / DAY_IN_SECONDS );
}
/** @return string|null */
public function get_deadline_date() {
return $this->get_basic_data_property( 'deadline_date' );
}
/** @return string|null */
public function get_completed_date() {
return $this->get_basic_data_property( 'completed_date' );
}
/** @return string|null */
public function get_manager_id() {
return $this->get_basic_data_property( 'manager_id' );
}
/** @return string|null */
protected function get_title_from_db() {
return $this->get_basic_data_property( 'title' );
}
/** @return string|null */
protected function get_uuid() {
return $this->get_basic_data_property( 'uuid' );
}
}