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,33 @@
<?php
class WPML_Initialize_Language_For_Post_Type {
private $wpdb;
public function __construct( wpdb $wpdb ) {
$this->wpdb = $wpdb;
}
public function run( $post_type, $default_language ) {
do {
$trid_max = (int) $this->wpdb->get_var( "SELECT MAX(trid) FROM {$this->wpdb->prefix}icl_translations" ) + 1;
$sql = "INSERT IGNORE INTO {$this->wpdb->prefix}icl_translations (`element_type`, `element_id`, `trid`, `language_code`)" . PHP_EOL;
$sql .= "SELECT CONCAT('post_' , p.post_type) as element_type, p.ID as element_id, %d + p.ID as trid, %s as language_code" . PHP_EOL;
$sql .= "FROM {$this->wpdb->posts} p" . PHP_EOL;
$sql .= "LEFT OUTER JOIN {$this->wpdb->prefix}icl_translations t" . PHP_EOL;
$sql .= "ON t.element_id = p.ID AND t.element_type = CONCAT('post_', p.post_type)" . PHP_EOL;
$sql .= "WHERE p.post_type = %s AND t.translation_id IS NULL" . PHP_EOL;
$sql .= "LIMIT 500";
$sql_prepared = $this->wpdb->prepare( $sql, array( $trid_max, $default_language, $post_type ) );
$results = $this->wpdb->query( $sql_prepared );
} while ( $results && ! $this->wpdb->last_error );
do_action( 'wpml_translation_update', [
'type' => 'initialize_language_for_post_type',
'post_type' => $post_type,
'context' => 'post',
] );
return $results === 0 && ! $this->wpdb->last_error;
}
}

View File

@@ -0,0 +1,97 @@
<?php
class WPML_TM_ICL_Translate_Job {
private $table = 'icl_translate_job';
private $job_id = 0;
/** @var WPML_TM_Records $tm_records */
private $tm_records;
/**
* WPML_TM_ICL_Translation_Status constructor.
*
* @param WPML_TM_Records $tm_records
* @param int $job_id
*/
public function __construct( WPML_TM_Records $tm_records, $job_id ) {
$this->tm_records = $tm_records;
$job_id = (int) $job_id;
if ( $job_id > 0 ) {
$this->job_id = $job_id;
} else {
throw new InvalidArgumentException( 'Invalid Job ID: ' . $job_id );
}
}
/**
* @return int
*/
public function translator_id() {
return $this->tm_records->icl_translation_status_by_rid( $this->rid() )
->translator_id();
}
/**
* @return string|int
*/
public function service() {
return $this->tm_records->icl_translation_status_by_rid( $this->rid() )
->service();
}
/**
* @param array $args in the same format used by \wpdb::update()
*
* @return $this
*/
public function update( $args ) {
$wpdb = $this->tm_records->wpdb();
$wpdb->update(
$wpdb->prefix . $this->table,
$args,
array( 'job_id' => $this->job_id )
);
return $this;
}
/**
* @return bool true if this job is the most recent job for the element it
* belongs to and hence may be updated.
*/
public function is_open() {
$wpdb = $this->tm_records->wpdb();
return $this->job_id === (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT MAX(job_id)
FROM {$wpdb->prefix}{$this->table}
WHERE rid = %d",
$this->rid()
)
);
}
public function rid() {
return $this->get_job_column( 'rid' );
}
public function editor() {
return $this->get_job_column( 'editor' );
}
private function get_job_column( $column ) {
if ( ! trim( $column ) ) {
return null;
}
$wpdb = $this->tm_records->wpdb();
$query = ' SELECT ' . $column . " FROM {$wpdb->prefix}{$this->table} WHERE job_id = %d LIMIT 1";
$prepare = $wpdb->prepare( $query, $this->job_id );
return $wpdb->get_var( $prepare );
}
}

View File

@@ -0,0 +1,200 @@
<?php
use WPML\FP\Lst;
use WPML\FP\Maybe;
use WPML\FP\Just;
use WPML\FP\Nothing;
use function WPML\Container\make;
use WPML\Element\API\TranslationsRepository;
class WPML_TM_ICL_Translation_Status {
/** @var wpdb $wpdb */
public $wpdb;
private $tm_records;
private $table = 'icl_translation_status';
private $translation_id = 0;
private $rid = 0;
private $status_result;
/**
* WPML_TM_ICL_Translation_Status constructor.
*
* @param wpdb $wpdb
* @param WPML_TM_Records $tm_records
* @param int $id
* @param string $type
*/
public function __construct( wpdb $wpdb, WPML_TM_Records $tm_records, $id, $type = 'translation_id' ) {
$this->wpdb = $wpdb;
$this->tm_records = $tm_records;
if ( $id > 0 && Lst::includes( $type, [ 'translation_id', 'rid' ] ) ) {
$this->{$type} = $id;
} else {
throw new InvalidArgumentException( 'Unknown column: ' . $type . ' or invalid id: ' . $id );
}
}
/**
* @param array $args in the same format used by \wpdb::update()
*
* @return $this
*/
public function update( $args ) {
$this->wpdb->update(
$this->wpdb->prefix . $this->table,
$args,
$this->get_args()
);
$this->status_result = null;
return $this;
}
/**
* Wrapper for \wpdb::delete()
*/
public function delete() {
$this->wpdb->delete(
$this->wpdb->prefix . $this->table,
$this->get_args()
);
}
/**
* @return int
*/
public function rid() {
return (int) $this->wpdb->get_var(
"SELECT rid
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
/**
* @return int
*/
public function status() {
if ( $this->status_result === null ) {
$status = $this->tm_records->get_preloaded_translation_status( $this->translation_id, $this->rid );
if ( $status ) {
$this->status_result = (int) $status->status;
} else {
if ( $this->translation_id ) {
$job = TranslationsRepository::getByTranslationId( $this->translation_id );
if ( $job ) {
$this->status_result = \WPML\FP\Obj::prop( 'status', $job );
return $this->status_result;
}
}
$this->status_result = (int) $this->wpdb->get_var(
"SELECT status
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
}
return (int) $this->status_result;
}
/**
* @return Just|Nothing
*/
public function previous() {
return Maybe::fromNullable( $this->wpdb->get_var(
"SELECT _prevstate
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
) )->map( 'unserialize' );
}
/**
* @return string
*/
public function md5() {
return $this->wpdb->get_var(
"SELECT md5
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
/**
* @return int
*/
public function translation_id() {
return (int) $this->wpdb->get_var(
"SELECT translation_id
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
public function trid() {
return $this->tm_records->icl_translations_by_translation_id( $this->translation_id() )->trid();
}
public function element_id() {
return $this->tm_records->icl_translations_by_translation_id( $this->translation_id() )->element_id();
}
/**
* @return int
*/
public function translator_id() {
return (int) $this->wpdb->get_var(
"SELECT translator_id
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
/**
* @return string|int
*/
public function service() {
return (int) $this->wpdb->get_var(
"SELECT translation_service
FROM {$this->wpdb->prefix}{$this->table} "
. $this->get_where()
);
}
private function get_where() {
return ' WHERE ' .
( $this->translation_id
? $this->wpdb->prepare( ' translation_id = %d ', $this->translation_id )
: $this->wpdb->prepare( ' rid = %d ', $this->rid ) );
}
private function get_args() {
return $this->translation_id
? array( 'translation_id' => $this->translation_id )
: array( 'rid' => $this->rid );
}
/**
* @param $id
*
* @return \WPML_TM_ICL_Translation_Status
* @throws \WPML\Auryn\InjectionException
*/
public static function makeByRid( $id ) {
return make( self::class, [ ':id' => $id, ':type' => 'rid' ] );
}
}

View File

@@ -0,0 +1,196 @@
<?php
class WPML_TM_ICL_Translations extends WPML_TM_Record_User {
private $table = 'icl_translations';
private $fields = array();
private $related = array();
/** @var wpdb $wpdb */
private $wpdb;
private $translation_id = 0;
/** @var WPML_Frontend_Post_Actions | WPML_Admin_Post_Actions $post_translations */
private $post_translations;
/** @var WPML_Term_Translation $term_translations */
private $term_translations;
/**
* WPML_TM_ICL_Translations constructor.
*
* @throws InvalidArgumentException if given data does not correspond to a
* record in icl_translations
*
* @param WPML_TM_Records $tm_records
* @param int|array $id
* @param string $type translation id, trid_lang or id_prefix for now
*/
public function __construct( &$tm_records, $id, $type = 'translation_id' ) {
$this->wpdb = $tm_records->wpdb();
$this->post_translations = $tm_records->get_post_translations();
$this->term_translations = $tm_records->get_term_translations();
parent::__construct( $tm_records );
if ( $id > 0 && $type === 'translation_id' ) {
$this->{$type} = $id;
} elseif ( $type === 'id_type_prefix' && isset( $id['element_id'] ) && isset( $id['type_prefix'] ) ) {
$this->build_from_element_id( $id );
} elseif ( $type === 'trid_lang' && isset( $id['trid'] ) && isset( $id['language_code'] ) ) {
$this->build_from_trid( $id );
} else {
throw new InvalidArgumentException( 'Unknown column: ' . $type . ' or invalid id: ' . serialize( $id ) );
}
}
private function build_from_element_id( $id ) {
if ( 'post' === $id['type_prefix'] ) {
$this->translation_id = $this->post_translations->get_translation_id( $id['element_id'] );
}
if ( 'term' === $id['type_prefix'] ) {
$this->translation_id = $this->term_translations->get_translation_id( $id['element_id'] );
}
if ( ! $this->translation_id ) {
$this->select_translation_id(
' element_id = %d AND element_type LIKE %s ',
array( $id['element_id'], $id['type_prefix'] . '%' )
);
}
}
private function build_from_trid( $id ) {
$this->select_translation_id(
' trid = %d AND language_code = %s ',
array( $id['trid'], $id['language_code'] )
);
}
/**
* @return WPML_TM_ICL_Translations[]
*/
public function translations() {
if ( false === (bool) $this->related ) {
$trid = $this->trid();
$found = false;
$cache = new WPML_WP_Cache( 'WPML_TM_ICL_Translations::translations' );
$translation_ids = $cache->get( $trid, $found );
if ( ! $found ) {
$translation_ids = $this->wpdb->get_results(
"SELECT translation_id, language_code
FROM {$this->wpdb->prefix}{$this->table}
WHERE trid = " . $trid
);
$cache->set( $trid, $translation_ids );
}
foreach ( $translation_ids as $row ) {
$this->related[ $row->language_code ] = $this->tm_records
->icl_translations_by_translation_id( $row->translation_id );
}
}
return $this->related;
}
private function select_by( $function, $field ) {
$result = call_user_func( array( $this->post_translations, $function ), $this->translation_id );
$result = $result ? $result : call_user_func( array( $this->term_translations, $function ), $this->translation_id );
$result = $result ? $result : $this->select_field( $field );
return $result;
}
/**
* @return null|int
*/
public function trid() {
return $this->select_by( 'get_trid_from_translation_id', 'trid' );
}
/**
* @return int
*/
public function translation_id() {
return $this->translation_id;
}
/**
* @return null|int
*/
public function element_id() {
return $this->select_by( 'get_element_from_translation_id', 'element_id' );
}
/**
* @return string|null
*/
public function language_code() {
return $this->select_field( 'language_code' );
}
/**
* @return string|null
*/
public function source_language_code() {
$lang = $this->post_translations->get_source_lang_from_translation_id( $this->translation_id );
$lang = $lang['found'] ? $lang : $this->term_translations->get_source_lang_from_translation_id( $this->translation_id );
$lang = $lang['found'] ? $lang['code'] : $this->select_field( 'source_language_code' );
return $lang;
}
/**
*
* @return $this
*/
public function delete() {
$this->tm_records
->icl_translation_status_by_translation_id( $this->translation_id )
->delete();
$this->wpdb->delete(
$this->wpdb->prefix . $this->table,
$this->get_args()
);
return $this;
}
private function select_field( $field ) {
$this->fields[ $field ] = isset( $this->fields[ $field ] ) ? $this->fields[ $field ] : $this->wpdb->get_var(
$this->wpdb->prepare(
" SELECT {$field}
FROM {$this->wpdb->prefix}{$this->table}
WHERE translation_id = %d
LIMIT 1",
$this->translation_id
)
);
return $this->fields[ $field ];
}
private function get_args() {
return array( 'translation_id' => $this->translation_id );
}
private function select_translation_id( $where, $prepare_args ) {
$this->translation_id = $this->wpdb->get_var(
"SELECT translation_id FROM {$this->wpdb->prefix}{$this->table}
WHERE" . $this->wpdb->prepare( $where, $prepare_args )
. ' LIMIT 1'
);
if ( ! $this->translation_id ) {
throw new InvalidArgumentException( 'No translation entry found for query: ' . serialize( $where ) . serialize( $prepare_args ) );
}
}
}

View File

@@ -0,0 +1,187 @@
<?php
class WPML_TM_Records {
/** @var WPDB $wpdb */
public $wpdb;
/** @var array $cache */
private $cache = array(
'icl_translations' => array(),
'status' => array(),
);
private $preloaded_statuses = null;
/** @var WPML_Frontend_Post_Actions | WPML_Admin_Post_Actions $wpml_post_translations */
private $wpml_post_translations;
/** @var WPML_Term_Translation $wpml_term_translations */
private $wpml_term_translations;
public function __construct(
wpdb $wpdb,
WPML_Post_Translation $wpml_post_translations,
WPML_Term_Translation $wpml_term_translations
) {
$this->wpdb = $wpdb;
$this->wpml_post_translations = $wpml_post_translations;
$this->wpml_term_translations = $wpml_term_translations;
}
public function wpdb() {
return $this->wpdb;
}
public function get_new_wpml_wp_cache( $group = '' ) {
return new WPML_WP_Cache( $group );
}
public function get_post_translations() {
return $this->wpml_post_translations;
}
public function get_term_translations() {
return $this->wpml_term_translations;
}
/**
* @param int $translation_id
*
* @return WPML_TM_ICL_Translation_Status
*/
public function icl_translation_status_by_translation_id( $translation_id ) {
if ( ! isset( $this->cache['status'][ $translation_id ] ) ) {
$this->maybe_preload_translation_statuses();
$this->cache['status'][ $translation_id ] = new WPML_TM_ICL_Translation_Status( $this->wpdb, $this, $translation_id );
}
return $this->cache['status'][ $translation_id ];
}
private function maybe_preload_translation_statuses() {
if ( null === $this->preloaded_statuses ) {
$translation_ids = $this->wpml_post_translations->get_translations_ids();
if ( $translation_ids ) {
$translation_ids = implode( ',', $translation_ids );
$this->preloaded_statuses = $this->wpdb->get_results(
"SELECT *
FROM {$this->wpdb->prefix}icl_translation_status
WHERE translation_id in ({$translation_ids})"
);
} else {
$this->preloaded_statuses = array();
}
}
}
public function get_preloaded_translation_status( $translation_id, $rid ) {
$data = null;
if ( $this->preloaded_statuses ) {
foreach ( $this->preloaded_statuses as $status ) {
if ( $translation_id && $status->translation_id == $translation_id ) {
$data = $status;
break;
} elseif ( $rid && $status->translation_id == $rid ) {
$data = $status;
break;
}
}
}
return $data;
}
/**
* @param int $rid
*
* @return WPML_TM_ICL_Translation_Status
*/
public function icl_translation_status_by_rid( $rid ) {
return new WPML_TM_ICL_Translation_Status( $this->wpdb, $this, $rid, 'rid' );
}
/**
* @param int $job_id
*
* @return WPML_TM_ICL_Translate_Job
*/
public function icl_translate_job_by_job_id( $job_id ) {
return new WPML_TM_ICL_Translate_Job( $this, $job_id );
}
/**
* @param int $translation_id
*
* @return WPML_TM_ICL_Translations
*/
public function icl_translations_by_translation_id( $translation_id ) {
return new WPML_TM_ICL_Translations( $this, $translation_id );
}
/**
* @param int $element_id
* @param string $type_prefix
*
* @return WPML_TM_ICL_Translations
*/
public function icl_translations_by_element_id_and_type_prefix(
$element_id,
$type_prefix
) {
$key = md5( $element_id . $type_prefix );
if ( ! isset( $this->cache['icl_translations'][ $key ] ) ) {
$this->cache['icl_translations'][ $key ] = new WPML_TM_ICL_Translations(
$this,
array(
'element_id' => $element_id,
'type_prefix' => $type_prefix,
),
'id_type_prefix'
);
}
return $this->cache['icl_translations'][ $key ];
}
/**
* @param int $trid
* @param string $lang
*
* @return WPML_TM_ICL_Translations
*/
public function icl_translations_by_trid_and_lang( $trid, $lang ) {
$key = md5( $trid . $lang );
if ( ! isset( $this->cache['icl_translations'][ $key ] ) ) {
$this->cache['icl_translations'][ $key ] = new WPML_TM_ICL_Translations(
$this,
array(
'trid' => $trid,
'language_code' => $lang,
),
'trid_lang'
);
}
return $this->cache['icl_translations'][ $key ];
}
/**
* @param int $trid
*
* @return int[]
*/ public function get_element_ids_from_trid( $trid ) {
return $this->wpdb->get_col(
$this->wpdb->prepare(
"SELECT element_id
FROM {$this->wpdb->prefix}icl_translations
WHERE trid = %d",
$trid
)
);
}
}

View File

@@ -0,0 +1,23 @@
<?php
class WPML_TM_Update_Translation_Status {
/**
* @param int $job_id
* @param int $new_status
*/
public static function by_job_id( $job_id, $new_status ) {
/** @var stdClass $job */
$job = wpml_tm_load_job_factory()->get_translation_job( $job_id );
if ( $job ) {
$new_status = (int) $new_status;
$old_status = (int) $job->status;
if ( $new_status !== $old_status ) {
wpml_tm_get_records()
->icl_translation_status_by_translation_id( $job->translation_id )
->update( array( 'status' => $new_status ) );
}
}
}
}