first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,234 @@
<?php
namespace WPML\TM\Jobs\Query;
use wpdb;
use WPML_TM_Editors;
use WPML_TM_Jobs_Search_Params;
abstract class AbstractQuery implements Query {
/** @var wpdb */
protected $wpdb;
/** @var QueryBuilder */
protected $query_builder;
/** @var string */
protected $title_column = 'posts.post_title';
/** @var string */
protected $batch_name_column = 'batches.batch_name';
/**
* @param wpdb $wpdb
* @param QueryBuilder $query_builder
*/
public function __construct( wpdb $wpdb, QueryBuilder $query_builder ) {
$this->wpdb = $wpdb;
$this->query_builder = $query_builder;
}
public function get_data_query( WPML_TM_Jobs_Search_Params $params ) {
$hasCompletedTranslationSubquery = "
SELECT COUNT(job_id)
FROM {$this->wpdb->prefix}icl_translate_job as copmpleted_translation_job
WHERE copmpleted_translation_job.rid = translation_status.rid AND copmpleted_translation_job.translated = 1
";
$columns = array(
'translation_status.rid AS id',
"'" . $this->get_type() . "' AS type",
'translation_status.tp_id AS tp_id',
'batches.id AS local_batch_id',
'batches.tp_id AS tp_batch_id',
$this->batch_name_column,
'translation_status.status AS status',
'original_translations.element_id AS original_element_id',
'translations.source_language_code AS source_language',
'translations.language_code AS target_language',
'translation_status.translation_service AS translation_service',
'translation_status.timestamp AS sent_date',
'translate_job.deadline_date AS deadline_date',
'translate_job.completed_date AS completed_date',
"{$this->title_column} AS title",
'source_languages.english_name AS source_language_name',
'target_languages.english_name AS target_language_name',
'translate_job.translator_id AS translator_id',
'translate_job.job_id AS translate_job_id',
'translation_status.tp_revision AS revision',
'translation_status.ts_status AS ts_status',
'translation_status.needs_update AS needs_update',
'translate_job.editor AS editor',
"({$hasCompletedTranslationSubquery}) > 0 AS has_completed_translation",
'translate_job.editor_job_id AS editor_job_id',
);
return $this->build_query( $params, $columns );
}
public function get_count_query( WPML_TM_Jobs_Search_Params $params ) {
$columns = array( 'COUNT(translation_status.rid)' );
return $this->build_query( $params, $columns );
}
/**
* @param WPML_TM_Jobs_Search_Params $params
* @param array $columns
*
* @return string
*/
protected function build_query( WPML_TM_Jobs_Search_Params $params, array $columns ) {
if ( $this->check_job_type( $params ) ) {
return '';
}
$query_builder = clone $this->query_builder;
$query_builder->set_columns( $columns );
$query_builder->set_from( "{$this->wpdb->prefix}icl_translation_status translation_status" );
$this->define_joins( $query_builder );
$this->define_filters( $query_builder, $params );
$query_builder->set_limit( $params );
$query_builder->set_order( $params );
return $query_builder->build();
}
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return bool
*/
protected function check_job_type( WPML_TM_Jobs_Search_Params $params ) {
return $params->get_job_types() && ! in_array( $this->get_type(), $params->get_job_types(), true );
}
/**
* @return string
*/
abstract protected function get_type();
protected function define_joins( QueryBuilder $query_builder ) {
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_translations translations
ON translations.translation_id = translation_status.translation_id"
);
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_translations original_translations
ON original_translations.trid = translations.trid AND original_translations.language_code = translations.source_language_code"
);
$subquery = "
SELECT *
FROM {$this->wpdb->prefix}icl_translate_job as translate_job
WHERE job_id = (
SELECT MAX(job_id) AS job_id
FROM {$this->wpdb->prefix}icl_translate_job as sub_translate_job
WHERE sub_translate_job.rid = translate_job.rid
)
";
$query_builder->add_join( "INNER JOIN ({$subquery}) AS translate_job ON translate_job.rid = translation_status.rid" );
$this->add_resource_join( $query_builder );
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_languages source_languages
ON source_languages.code = translations.source_language_code"
);
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_languages target_languages
ON target_languages.code = translations.language_code"
);
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_translation_batches batches
ON batches.id = translation_status.batch_id"
);
}
abstract protected function add_resource_join( QueryBuilder $query_builder );
protected function define_filters( QueryBuilder $query_builder, WPML_TM_Jobs_Search_Params $params ) {
$this->set_status_filter( $query_builder, $params );
$query_builder = $this->set_scope_filter( $query_builder, $params );
$query_builder->set_multi_value_text_filter( $this->title_column, $params->get_title() );
$query_builder->set_multi_value_text_filter( $this->batch_name_column, $params->get_batch_name() );
$query_builder->set_source_language( 'translations.source_language_code', $params );
$query_builder->set_target_language( 'translations.language_code', $params );
$query_builder->set_translated_by_filter(
'translate_job.translator_id',
'translation_status.translation_service',
$params
);
if ( $params->get_sent() ) {
$query_builder->set_date_range( 'translation_status.timestamp', $params->get_sent() );
}
if ( $params->get_deadline() ) {
$query_builder->set_date_range( 'translate_job.deadline_date', $params->get_deadline() );
}
if ( $params->get_completed_date() ) {
$query_builder->set_date_range( 'translate_job.completed_date', $params->get_completed_date() );
}
$query_builder->set_numeric_value_filter( 'translation_status.rid', $params->get_local_job_ids() );
$query_builder->set_numeric_value_filter(
'original_translations.element_id',
$params->get_original_element_id()
);
$query_builder->set_tp_id_filter( 'translation_status.tp_id', $params );
}
private function set_status_filter(
QueryBuilder $query_builder,
WPML_TM_Jobs_Search_Params $params
) {
if ( $params->get_needs_update() ) {
$statuses = array_diff( $params->get_status(), [ ICL_TM_NEEDS_UPDATE ] );
if ( $params->get_needs_update()->is_needs_update_excluded() ) {
$query_builder->add_AND_where_condition( 'translation_status.needs_update != 1' );
if ( $statuses ) {
$query_builder->set_status_filter( 'translation_status.status', $params );
}
} else {
if ( $statuses ) {
$statuses = wpml_prepare_in( $params->get_status(), '%d' );
$statuses = sprintf( 'translation_status.status IN (%s)', $statuses );
$query_builder->add_AND_where_condition( "( translation_status.needs_update = 1 OR {$statuses} )" );
} else {
$query_builder->add_AND_where_condition( 'translation_status.needs_update = 1' );
}
}
} else {
$query_builder->set_status_filter( 'translation_status.status', $params );
}
}
private function set_scope_filter( QueryBuilder $query_builder, WPML_TM_Jobs_Search_Params $params ) {
switch ( $params->get_scope() ) {
case WPML_TM_Jobs_Search_Params::SCOPE_LOCAL:
$query_builder->add_AND_where_condition( "translation_status.translation_service = 'local'" );
break;
case WPML_TM_Jobs_Search_Params::SCOPE_REMOTE:
$query_builder->add_AND_where_condition( "translation_status.translation_service != 'local'" );
break;
case WPML_TM_Jobs_Search_Params::SCOPE_ATE:
$query_builder->add_AND_where_condition( "translation_status.translation_service = 'local'" );
$query_builder->add_AND_where_condition( $this->wpdb->prepare( 'translate_job.editor = %s', WPML_TM_Editors::ATE ) );
break;
}
return $query_builder;
}
}

View File

@@ -0,0 +1,185 @@
<?php
namespace WPML\TM\Jobs\Query;
use \InvalidArgumentException;
use \WPML_TM_Jobs_Search_Params;
use \RuntimeException;
class CompositeQuery implements Query {
const METHOD_UNION = 'union';
const METHOD_COUNT = 'count';
/**
* Job queries
*
* @var Query[]
*/
private $queries;
/**
* Limit query helper
*
* @var LimitQueryHelper
*/
private $limit_query_helper;
/**
* Order query helper
*
* @var OrderQueryHelper
*/
private $order_query_helper;
/**
* @param Query[] $queries Job queries.
* @param LimitQueryHelper $limit_helper Limit helper.
* @param OrderQueryHelper $order_helper Order helper.
*
* @throws InvalidArgumentException In case of error.
*/
public function __construct(
array $queries,
LimitQueryHelper $limit_helper,
OrderQueryHelper $order_helper
) {
$queries = array_filter( $queries, array( $this, 'is_query_valid' ) );
if ( empty( $queries ) ) {
throw new InvalidArgumentException( 'Collection of sub-queries is empty or contains only invalid elements' );
}
$this->queries = $queries;
$this->limit_query_helper = $limit_helper;
$this->order_query_helper = $order_helper;
}
/**
* Get data query
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*
* @throws InvalidArgumentException In case of error.
* @return string
*/
public function get_data_query( WPML_TM_Jobs_Search_Params $params ) {
if ( ! $params->get_job_types() ) {
// We are merging subqueries here, that's why LIMIT must be applied to final query.
$params_without_pagination_and_sorting = clone $params;
$params_without_pagination_and_sorting->set_limit( 0 )->set_offset( 0 );
$params_without_pagination_and_sorting->set_sorting( array() );
$query = $this->get_sql( $params_without_pagination_and_sorting, self::METHOD_UNION );
$order = $this->order_query_helper->get_order( $params );
if ( $order ) {
$query .= ' ' . $order;
}
$limit = $this->limit_query_helper->get_limit( $params );
if ( $limit ) {
$query .= ' ' . $limit;
}
return $query;
} else {
return $this->get_sql( $params, self::METHOD_UNION );
}
}
/**
* Get count query
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*
* @return int|string
*/
public function get_count_query( WPML_TM_Jobs_Search_Params $params ) {
$params_without_pagination_and_sorting = clone $params;
$params_without_pagination_and_sorting->set_limit( 0 )->set_offset( 0 );
$params_without_pagination_and_sorting->set_sorting( array() );
return $this->get_sql( $params_without_pagination_and_sorting, self::METHOD_COUNT );
}
/**
* Get SQL request string
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
* @param string $method Query method.
*
* @throws InvalidArgumentException In case of error.
* @throws RuntimeException In case of error.
* @return string
*/
private function get_sql( WPML_TM_Jobs_Search_Params $params, $method ) {
switch ( $method ) {
case self::METHOD_UNION:
$query_method = 'get_data_query';
break;
case self::METHOD_COUNT:
$query_method = 'get_count_query';
break;
default:
throw new InvalidArgumentException( 'Invalid method argument: ' . $method );
}
$parts = array();
foreach ( $this->queries as $query ) {
$query_string = $query->$query_method( $params );
if ( $query_string ) {
$parts[] = $query_string;
}
}
if ( ! $parts ) {
throw new RuntimeException( 'None of subqueries matches to specified search parameters' );
}
if ( 1 === count( $parts ) ) {
return current( $parts );
}
switch ( $method ) {
case self::METHOD_UNION:
return $this->get_union( $parts );
case self::METHOD_COUNT:
return $this->get_count( $parts );
}
return null;
}
/**
* Get union
*
* @param array $parts Query parts.
*
* @return string
*/
private function get_union( array $parts ) {
return '( ' . implode( ' ) UNION ( ', $parts ) . ' )';
}
/**
* Get count
*
* @param array $parts Query parts.
*
* @return string
*/
private function get_count( array $parts ) {
return 'SELECT ( ' . implode( ' ) + ( ', $parts ) . ' )';
}
/**
* Is query valid
*
* @param mixed $query SQL query.
*
* @return bool
*/
private function is_query_valid( $query ) {
return $query instanceof Query;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace WPML\TM\Jobs\Query;
use \WPML_TM_Jobs_Search_Params;
class LimitQueryHelper {
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return string
*/
public function get_limit( WPML_TM_Jobs_Search_Params $params ) {
$result = '';
if ( $params->get_limit() ) {
if ( $params->get_offset() ) {
$result = sprintf( 'LIMIT %d, %d', $params->get_offset(), $params->get_limit() );
} else {
$result = sprintf( 'LIMIT %d', $params->get_limit() );
}
}
return $result;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace WPML\TM\Jobs\Query;
use \WPML_TM_Jobs_Search_Params;
class OrderQueryHelper {
public function get_order( \WPML_TM_Jobs_Search_Params $params ) {
$orders = $this->map_sort_parameters( $params );
if ( $orders ) {
return 'ORDER BY ' . implode( ', ', $orders );
} else {
return '';
}
}
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return array
*/
private function map_sort_parameters( WPML_TM_Jobs_Search_Params $params ) {
$orders = array();
if ( $params->get_sorting() ) {
foreach ( $params->get_sorting() as $order ) {
if ( $order->get_column() === 'language' ) {
$orders[] = 'source_language_name ' . $order->get_direction();
$orders[] = 'target_language_name ' . $order->get_direction();
} else {
$orders[] = $order->get_column() . ' ' . $order->get_direction();
}
}
}
return $orders;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace WPML\TM\Jobs\Query;
use WPML_TM_Job_Entity;
class PackageQuery extends PostQuery {
/** @var string */
protected $title_column = 'string_packages.title';
protected function add_resource_join( QueryBuilder $query_builder ) {
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_string_packages string_packages
ON string_packages.ID = original_translations.element_id"
);
$query_builder->add_AND_where_condition( "original_translations.element_type LIKE 'package%'" );
}
protected function get_type() {
return WPML_TM_Job_Entity::PACKAGE_TYPE;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace WPML\TM\Jobs\Query;
use WPML_TM_Job_Entity;
class PostQuery extends AbstractQuery {
/**
* @param QueryBuilder $query_builder
*/
protected function add_resource_join( QueryBuilder $query_builder ) {
$query_builder->add_join( "INNER JOIN {$this->wpdb->prefix}posts posts ON posts.ID = original_translations.element_id" );
$query_builder->add_AND_where_condition( "original_translations.element_type LIKE 'post%'" );
}
protected function get_type() {
return WPML_TM_Job_Entity::POST_TYPE;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace WPML\TM\Jobs\Query;
use \WPML_TM_Jobs_Search_Params;
interface Query {
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return string
*/
public function get_data_query( WPML_TM_Jobs_Search_Params $params );
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return int
*/
public function get_count_query( WPML_TM_Jobs_Search_Params $params );
}

View File

@@ -0,0 +1,327 @@
<?php
namespace WPML\TM\Jobs\Query;
use \wpdb;
use \WPML_TM_Jobs_Search_Params;
use \WPML_TM_Jobs_Date_Range;
use \InvalidArgumentException;
class QueryBuilder {
/** @var wpdb */
private $wpdb;
/** @var LimitQueryHelper */
protected $limit_helper;
/** @var OrderQueryHelper */
protected $order_helper;
/** @var array */
private $columns = array();
/** @var string */
private $from;
/** @var array */
private $joins = array();
/** @var array */
private $where = array();
/** @var string */
private $order;
/** @var string */
private $limit;
/**
* @param LimitQueryHelper $limit_helper
* @param OrderQueryHelper $order_helper
*/
public function __construct(
LimitQueryHelper $limit_helper,
OrderQueryHelper $order_helper
) {
global $wpdb;
$this->wpdb = $wpdb;
$this->limit_helper = $limit_helper;
$this->order_helper = $order_helper;
}
/**
* @param array $columns
*
* @return self
*/
public function set_columns( array $columns ) {
$this->columns = $columns;
return $this;
}
/**
* @param $column
*
* @return self
*/
public function add_column( $column ) {
$this->columns[] = $column;
return $this;
}
/**
* @param string $from
*
* @return self
*/
public function set_from( $from ) {
$this->from = $from;
return $this;
}
/**
* @param $join
*
* @return self
*/
public function add_join( $join ) {
$this->joins[] = $join;
return $this;
}
/**
* @param $column
* @param WPML_TM_Jobs_Search_Params $params
*
* @return self
*/
public function set_status_filter( $column, WPML_TM_Jobs_Search_Params $params ) {
if ( $params->get_status() ) {
$statuses = wpml_prepare_in( $params->get_status(), '%d' );
$this->where[] = sprintf( $column . ' IN (%s)', $statuses );
}
return $this;
}
/**
* @param string $column
* @param array|null $values
*
* @return $this
*/
public function set_multi_value_text_filter( $column, $values ) {
if ( $values ) {
$where = \wpml_collect( $values )->map(
function ( $value ) use ( $column ) {
return $this->wpdb->prepare( "{$column} LIKE %s", '%' . $value . '%' );
}
)->toArray();
$this->where[] = '( ' . implode( ' OR ', $where ) . ' )';
}
return $this;
}
/**
* @param $column
* @param WPML_TM_Jobs_Search_Params $params
*
* @return $this
*/
public function set_source_language( $column, WPML_TM_Jobs_Search_Params $params ) {
if ( $params->get_source_language() ) {
$this->where[] = $this->wpdb->prepare( "{$column} = %s", $params->get_source_language() );
}
return $this;
}
/**
* @param $column
* @param WPML_TM_Jobs_Search_Params $params
*
* @return $this
*/
public function set_target_language( $column, WPML_TM_Jobs_Search_Params $params ) {
if ( $params->get_target_language() ) {
$this->where[] = sprintf(
'%s IN (%s)',
$column,
wpml_prepare_in( $params->get_target_language() )
);
}
return $this;
}
public function set_translated_by_filter(
$local_translator_column,
$translation_service_column,
WPML_TM_Jobs_Search_Params $params
) {
if ( $params->get_scope() !== WPML_TM_Jobs_Search_Params::SCOPE_ALL && $params->get_translated_by() ) {
if ( $params->get_scope() === WPML_TM_Jobs_Search_Params::SCOPE_LOCAL ) {
$this->where[] = $this->wpdb->prepare(
"{$local_translator_column} = %d",
$params->get_translated_by()
);
} else {
$this->where[] = $this->wpdb->prepare(
"{$translation_service_column} = %d",
$params->get_translated_by()
);
}
}
return $this;
}
/**
* @param string $column
* @param int|int[] $value
*
* @return $this
*/
public function set_numeric_value_filter( $column, $value ) {
if ( $value ) {
if ( is_array( $value ) ) {
$this->where[] = sprintf( "{$column} IN(%s)", wpml_prepare_in( $value, '%d' ) );
} else {
$this->where[] = sprintf( "{$column} = %d", $value );
}
}
return $this;
}
/**
* @param $column
* @param WPML_TM_Jobs_Search_Params $params
*
* @return $this
*/
public function set_tp_id_filter( $column, WPML_TM_Jobs_Search_Params $params ) {
if ( $params->get_tp_id() ) {
$where = array();
$tp_ids = $params->get_tp_id();
if ( in_array( null, $tp_ids, true ) ) {
$tp_ids = array_filter( $tp_ids );
$where[] = $column . ' IS NULL';
}
if ( $tp_ids ) {
$where[] = sprintf( $column . ' IN (%s)', wpml_prepare_in( $tp_ids ) );
}
$this->where[] = '( ' . implode( ' OR ', $where ) . ' )';
}
return $this;
}
/**
* @param string $column
* @param WPML_TM_Jobs_Date_Range $date_range
*
* @return self
*/
public function set_date_range( $column, WPML_TM_Jobs_Date_Range $date_range ) {
$sql_parts = array();
if ( $date_range->get_begin() ) {
$sql_parts[] = $this->wpdb->prepare( $column . ' >= %s', $date_range->get_begin()->format( 'Y-m-d' ) );
}
if ( $date_range->get_end() ) {
$sql_parts[] = $this->wpdb->prepare(
$column . ' <= %s',
$date_range->get_end()->format( 'Y-m-d 23:59:59' )
);
}
if ( $sql_parts ) {
$sql = '( ' . implode( ' AND ', $sql_parts ) . ' )';
if ( $date_range->is_include_null_date() ) {
$sql .= " OR $column IS NULL";
$sql = "( $sql )";
}
$this->where[] = $sql;
}
return $this;
}
/**
* @param string $where
*
* @return self
*/
public function add_AND_where_condition( $where ) {
$this->where[] = $where;
return $this;
}
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return self
*/
public function set_order( WPML_TM_Jobs_Search_Params $params ) {
$this->order = $this->order_helper->get_order( $params );
return $this;
}
/**
* @param WPML_TM_Jobs_Search_Params $params
*
* @return self
*/
public function set_limit( WPML_TM_Jobs_Search_Params $params ) {
$this->limit = $this->limit_helper->get_limit( $params );
return $this;
}
public function build() {
if ( ! $this->columns ) {
throw new InvalidArgumentException( 'You have to specify columns list' );
}
if ( ! $this->from ) {
throw new InvalidArgumentException( 'You have to specify FROM table' );
}
$sql = '
SELECT
%s
FROM %s
';
$sql = sprintf( $sql, implode( ', ', $this->columns ), $this->from );
if ( $this->joins ) {
$sql .= implode( ' ', $this->joins );
}
if ( $this->where ) {
$sql .= ' WHERE ' . implode( ' AND ', $this->where );
}
if ( $this->order ) {
$sql .= ' ' . $this->order;
}
if ( $this->limit ) {
$sql .= ' ' . $this->limit;
}
return $sql;
}
}

View File

@@ -0,0 +1,224 @@
<?php
/**
* WPML_TM_Jobs_String_Query class file
*
* @package wpml-translation-management
*/
namespace WPML\TM\Jobs\Query;
use \wpdb;
use \WPML_TM_Jobs_Search_Params;
use \WPML_TM_Job_Entity;
class StringQuery implements Query {
/**
* WP database instance
*
* @var wpdb
*/
protected $wpdb;
/**
* Query builder instance
*
* @var QueryBuilder
*/
protected $query_builder;
/** @var string */
protected $batch_name_column = 'batches.batch_name';
/**
* @param wpdb $wpdb WP database instance.
* @param QueryBuilder $query_builder Query builder instance.
*/
public function __construct( wpdb $wpdb, QueryBuilder $query_builder ) {
$this->wpdb = $wpdb;
$this->query_builder = $query_builder;
}
/**
* Get data query
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*
* @return string
*/
public function get_data_query( WPML_TM_Jobs_Search_Params $params ) {
$columns = array(
'string_translations.id as id',
'"' . WPML_TM_Job_Entity::STRING_TYPE . '" as type',
'string_status.rid as tp_id',
'batches.id as local_batch_id',
'batches.tp_id as tp_batch_id',
$this->batch_name_column,
'string_translations.status as status',
'strings.id as original_element_id',
'strings.language as source_language',
'string_translations.language as target_language',
'string_translations.translation_service as translation_service',
'string_status.timestamp as sent_date',
'NULL as deadline_date',
'NULL as completed_date',
'strings.value as title',
'source_languages.english_name as source_language_name',
'target_languages.english_name as target_language_name',
'string_translations.translator_id as translator_id',
'NULL as translate_job_id',
'core_status.tp_revision AS revision',
'core_status.ts_status AS ts_status',
'NULL AS needs_update',
'NULL AS editor',
'string_translations.status = ' . ICL_TM_COMPLETE . ' AS has_completed_translation',
'NULL AS editor_job_id',
);
return $this->build_query( $params, $columns );
}
/**
* Get count query
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*
* @return int|string
*/
public function get_count_query( WPML_TM_Jobs_Search_Params $params ) {
$columns = array( 'COUNT(string_translations.id)' );
return $this->build_query( $params, $columns );
}
/**
* Build query
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
* @param array $columns Database columns.
*
* @return string
*/
private function build_query( WPML_TM_Jobs_Search_Params $params, array $columns ) {
if ( $this->check_job_type( $params ) ) {
return '';
}
$query_builder = clone $this->query_builder;
$query_builder->set_columns( $columns );
$query_builder->set_from( "{$this->wpdb->prefix}icl_translation_batches AS translation_batches" );
$this->define_joins( $query_builder );
$this->define_filters( $query_builder, $params );
$query_builder->set_limit( $params );
$query_builder->set_order( $params );
return $query_builder->build();
}
/**
* Check job type.
*
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*
* @return bool
*/
protected function check_job_type( WPML_TM_Jobs_Search_Params $params ) {
return $params->get_job_types() && ! in_array( WPML_TM_Job_Entity::STRING_TYPE, $params->get_job_types(), true );
}
/**
* Define joins
*
* @param QueryBuilder $query_builder Query builder instance.
*/
private function define_joins( QueryBuilder $query_builder ) {
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_string_translations AS string_translations
ON string_translations.batch_id = translation_batches.id"
);
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_strings AS strings
ON strings.id = string_translations.string_id"
);
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_string_status AS string_status
ON string_status.string_translation_id = string_translations.id"
);
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_core_status AS core_status
ON core_status.rid = string_status.rid"
);
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_languages source_languages
ON source_languages.code = strings.language"
);
$query_builder->add_join(
"LEFT JOIN {$this->wpdb->prefix}icl_languages target_languages
ON target_languages.code = string_translations.language"
);
$query_builder->add_join(
"INNER JOIN {$this->wpdb->prefix}icl_translation_batches batches
ON batches.id = string_translations.batch_id"
);
}
/**
* Define filters
*
* @param QueryBuilder $query_builder Query builder instance.
* @param WPML_TM_Jobs_Search_Params $params Job search params.
*/
private function define_filters( QueryBuilder $query_builder, WPML_TM_Jobs_Search_Params $params ) {
$query_builder->set_status_filter( 'string_translations.status', $params );
$query_builder = $this->set_scope_filter( $query_builder, $params );
$query_builder->set_multi_value_text_filter( 'strings.value', $params->get_title() );
$query_builder->set_multi_value_text_filter( $this->batch_name_column, $params->get_batch_name() );
$query_builder->set_source_language( 'strings.language', $params );
$query_builder->set_target_language( 'string_translations.language', $params );
$query_builder->set_translated_by_filter(
'string_translations.translator_id',
'string_translations.translation_service',
$params
);
if ( $params->get_sent() ) {
$query_builder->set_date_range( 'string_status.timestamp', $params->get_sent() );
}
$query_builder->set_numeric_value_filter( 'string_translations.id', $params->get_first_local_job_id() );
$query_builder->set_numeric_value_filter( 'strings.id', $params->get_original_element_id() );
$query_builder->set_tp_id_filter( 'string_status.rid', $params );
if ( $params->get_deadline() ) {
$query_builder->add_AND_where_condition( '1 = 0' );
}
}
private function set_scope_filter( QueryBuilder $query_builder, WPML_TM_Jobs_Search_Params $params ) {
switch ( $params->get_scope() ) {
case WPML_TM_Jobs_Search_Params::SCOPE_LOCAL:
$query_builder->add_AND_where_condition( 'string_status.rid IS NULL' );
break;
case WPML_TM_Jobs_Search_Params::SCOPE_REMOTE:
$query_builder->add_AND_where_condition( 'string_status.rid IS NOT NULL' );
break;
case WPML_TM_Jobs_Search_Params::SCOPE_ATE:
// we do not have string ATE jobs yet
// @todo it must be changed when we add them
$query_builder->add_AND_where_condition( '1 != 1' );
break;
}
return $query_builder;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace WPML\TM\Jobs\Query;
use WPML_TM_Job_Entity;
class StringsBatchQuery extends AbstractQuery {
/** @var string */
protected $title_column = 'translation_batches.batch_name';
protected function add_resource_join( QueryBuilder $query_builder ) {
$query_builder->add_join( "INNER JOIN {$this->wpdb->prefix}icl_translation_batches translation_batches ON translation_batches.id = original_translations.element_id" );
$query_builder->add_AND_where_condition( "original_translations.element_type = 'st-batch_strings'" );
}
protected function get_type() {
return WPML_TM_Job_Entity::STRING_BATCH;
}
}