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

269 lines
8.3 KiB
PHP

<?php
require_once WPML_TM_PATH . '/inc/translation-jobs/jobs/wpml-element-translation-job.class.php';
require_once WPML_TM_PATH . '/inc/translation-jobs/jobs/wpml-external-translation-job.class.php';
require_once WPML_TM_PATH . '/inc/translation-jobs/jobs/wpml-post-translation-job.class.php';
require_once WPML_TM_PATH . '/inc/translation-jobs/jobs/wpml-string-translation-job.class.php';
class WPML_Translation_Jobs_Collection extends WPML_Abstract_Job_Collection {
/** @var WPML_Translation_Batch[] $translation_batches */
private $translation_batches = array();
private $count = 0;
private $first_count;
private $last_count;
private $before_count = 0;
private $after_count = 0;
/** @var array $filter */
private $filter;
/** @var string $jobs_union_table_sql */
private $jobs_union_table_sql;
/**
* @param wpdb $wpdb
* @param array $icl_translation_filter
*/
public function __construct( &$wpdb, $icl_translation_filter ) {
parent::__construct( $wpdb );
$this->filter = $icl_translation_filter;
}
/**
* @param int $page
* @param int $per_page
*
* @return array
*/
public function get_paginated_batches( $page, $per_page ) {
$this->load_translation_jobs( $page, $per_page );
$metrics = array();
$batches = array();
if ( $this->translation_batches ) {
krsort( $this->translation_batches );
foreach ( $this->translation_batches as $id => $batch ) {
$metrics[ $id ] = $batch->get_batch_meta_array();
$batches[ $id ] = $batch;
}
}
$first_batch_metric = array_shift( $metrics );
$first_batch_metric['display_from'] = $this->before_count + 1;
$first_batch_metric['item_count'] = $this->first_count;
array_unshift( $metrics, $first_batch_metric );
$last_batch_metric = array_pop( $metrics );
$last_batch_metric['display_to'] = $this->last_count - $this->after_count;
$last_batch_metric['item_count'] = $this->last_count;
$metrics[] = $last_batch_metric;
return array(
'batches' => $batches,
'metrics' => $metrics,
);
}
/**
* Returns the number of jobs that meet the filter \WPML_Translation_Jobs_Collection::$filter in the database
*
* @return int
*/
public function get_count() {
return $this->count;
}
/**
* @param WPML_Translation_Job $job
*/
public function add_job( $job ) {
$batch_id = $job->get_batch_id();
$batch = array_key_exists( $batch_id, $this->translation_batches )
? $this->translation_batches[ $batch_id ] : new WPML_Translation_Batch( $this->wpdb, $batch_id );
$batch->add_job( $job );
$this->translation_batches[ $batch->get_id() ] = $batch;
}
private function load_translation_jobs( $page, $per_page ) {
$this->translation_batches = array();
list( $jobs, $count, $before_count, $after_count, $first_count, $last_count ) = $this->get_jobs_table(
$this->filter,
array(
'page' => $page,
'per_page' => $per_page,
)
);
$this->count = $count;
$this->after_count = $after_count;
$this->before_count = $before_count;
$this->first_count = $first_count;
$this->last_count = $last_count;
if ( is_array( $jobs ) ) {
foreach ( $jobs as $job ) {
$this->add_job( $job );
}
}
}
/**
* @param array $args
* @param array $pagination_args
*
* @return array
*/
private function get_jobs_table( array $args = array(), array $pagination_args = array(
'page' => 1,
'per_page' => 10,
) ) {
list( $data, $found_rows ) = $this->get_jobs_in_db( $args, $pagination_args );
if ( $data ) {
$result = $this->calculate_batch_counts( $data, $found_rows, $pagination_args );
} else {
$result = $this->get_default_batch_counts( $found_rows );
}
return $result;
}
/**
* @param int $found_rows
*
* @return array
*/
private function get_default_batch_counts( $found_rows ) {
return array( array(), $found_rows, 0, 0, 0, 0 );
}
private function get_jobs_in_db( array $args = array(), array $pagination_args = null ) {
$where_jobs = $this->build_where_clause( $args );
$jobs_table_union = $this->get_jobs_union_table_sql( $where_jobs, $args );
$only_ids_query = 'SELECT SQL_CALC_FOUND_ROWS ';
$only_ids_query .= 'jobs.job_id, jobs.translator_id, jobs.job_id, jobs.batch_id, jobs.element_type_prefix ';
$only_ids_query .= 'FROM ' . $jobs_table_union . ' ';
if ( $pagination_args ) {
$only_ids_query .= 'LIMIT %d, %d';
$prepare_args[] = max( ( $pagination_args['page'] - 1 ), 0 ) * $pagination_args['per_page'];
$prepare_args[] = $pagination_args['per_page'];
$only_ids_query = $this->wpdb->prepare( $only_ids_query, $prepare_args );
}
$data = $this->wpdb->get_results( $only_ids_query );
$found_rows = (int) $this->wpdb->get_var( 'SELECT FOUND_ROWS()' );
return array( $data, $found_rows );
}
public function get_jobs( array $args = array() ) {
list( $jobs_in_db, $found_rows ) = $this->get_jobs_in_db( $args );
$this->count = $found_rows;
return $this->plain_objects_to_job_instances( $jobs_in_db );
}
/**
* @param array $data
* @param int $count
* @param array $pagination_args
*
* @return array
*/
private function calculate_batch_counts( $data, $count, $pagination_args ) {
$first_job = reset( $data );
$last_job = end( $data );
$first_batch = $first_job->batch_id;
$last_batch = $last_job->batch_id;
$count_select_from_snippet = 'SELECT COUNT(jdata.job_id) FROM (SELECT job_id, batch_id FROM ' . $this->jobs_union_table_sql;
$count_where_snippet = ' ) AS jdata WHERE jdata.batch_id = %d';
$before_count_query = $count_select_from_snippet . ' LIMIT %d' . $count_where_snippet;
$page = $pagination_args['page'];
$per_page = $pagination_args['per_page'];
$count_before = $page > 1 ? $this->wpdb->get_var(
$this->wpdb->prepare(
$before_count_query,
array(
( $page - 1 ) * $per_page,
$first_batch,
)
)
) : 0;
$count_first = $this->wpdb->get_var(
$this->wpdb->prepare(
$before_count_query,
array( PHP_INT_MAX, $first_batch )
)
);
$after_count_query = $count_select_from_snippet . ' LIMIT %d, %d' . $count_where_snippet;
$count_after = $page * $per_page > $count ? 0 : $this->wpdb->get_var(
$this->wpdb->prepare(
$after_count_query,
array(
$page * $per_page,
PHP_INT_MAX,
$last_batch,
)
)
);
$count_last = $this->wpdb->get_var(
$this->wpdb->prepare(
$after_count_query,
array( 0, PHP_INT_MAX, $last_batch )
)
);
return array(
$this->plain_objects_to_job_instances( $data ),
$count,
$count_before,
$count_after,
$count_first,
$count_last,
);
}
private function get_jobs_union_table_sql( $where_jobs, $args ) {
$union_sql = '';
$sql_statements = array();
if ( $where_jobs ) {
$sql_statements[] = "SELECT s.translator_id,
j.job_id,
IF(p.post_type IS NOT NULL, 'post', 'package') AS element_type_prefix,
p.post_type AS post_type,
s.batch_id
FROM {$this->wpdb->prefix}icl_translation_status s
JOIN {$this->wpdb->prefix}icl_translations t
ON t.translation_id = s.translation_id
JOIN {$this->wpdb->prefix}icl_translate_job j
ON j.rid = s.rid
AND j.revision IS NULL
JOIN {$this->wpdb->prefix}icl_translations o
ON o.trid = t.trid
AND o.language_code = t.source_language_code
JOIN " . apply_filters( 'wpml_post_translation_original_table', $this->wpdb->posts ) . " p
ON o.element_id = p.ID
AND ( o.element_type = CONCAT('post_', p.post_type) OR p.post_type IS NULL )
JOIN {$this->wpdb->prefix}icl_translate tr_rows
ON tr_rows.job_id = j.job_id
AND tr_rows.field_type = 'original_id'
AND tr_rows.field_data = o.element_id
WHERE " . $where_jobs;
}
$sql_statements = apply_filters( 'wpml_tm_jobs_union_table_sql', $sql_statements, $args );
if ( count( $sql_statements ) > 0 ) {
$union_sql = '(' . implode( "\nUNION ALL\n", $sql_statements ) . ") jobs
INNER JOIN {$this->wpdb->prefix}icl_translation_batches b
ON b.id = jobs.batch_id
ORDER BY jobs.batch_id DESC, jobs.element_type_prefix, jobs.job_id DESC";
}
$this->jobs_union_table_sql = $union_sql;
return $union_sql;
}
}