first commit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\ST\DB\Mappers;
|
||||
|
||||
use WPML\FP\Curryable;
|
||||
|
||||
/**
|
||||
* Class DomainsRepository
|
||||
* @package WPML\ST\DB\Mappers
|
||||
*
|
||||
* @method static callable|array getByStringIds( ...$stringIds ) - Curried :: int[]->string[]
|
||||
*
|
||||
*/
|
||||
class DomainsRepository {
|
||||
use Curryable;
|
||||
|
||||
public static function init() {
|
||||
self::curryN( 'getByStringIds', 1, function ( array $stringIds ) {
|
||||
global $wpdb;
|
||||
|
||||
$sql = "SELECT DISTINCT `context` FROM {$wpdb->prefix}icl_strings WHERE id IN (" . wpml_prepare_in( $stringIds ) . ")";
|
||||
|
||||
return $wpdb->get_col( $sql );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
DomainsRepository::init();
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\ST\DB\Mappers;
|
||||
|
||||
use function WPML\Container\make;
|
||||
use function WPML\FP\partial;
|
||||
|
||||
class Hooks implements \IWPML_Action, \IWPML_Backend_Action, \IWPML_Frontend_Action {
|
||||
public function add_hooks() {
|
||||
$getStringById = [ make( \WPML_ST_DB_Mappers_Strings::class ), 'getById' ];
|
||||
$moveStringToDomain = partial( [ Update::class, 'moveStringToDomain' ], $getStringById );
|
||||
add_action( 'wpml_st_move_string_to_domain', $moveStringToDomain, 10, 2 );
|
||||
|
||||
add_action( 'wpml_st_move_all_strings_to_new_domain', [ Update::class, 'moveAllStringsToNewDomain' ], 10, 2 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\ST\DB\Mappers;
|
||||
|
||||
use function WPML\FP\curryN;
|
||||
|
||||
class StringTranslations {
|
||||
/**
|
||||
* @param \wpdb $wpdb
|
||||
* @param int $stringId
|
||||
* @param string $language
|
||||
*
|
||||
* @return callable|bool
|
||||
*/
|
||||
public static function hasTranslation( $wpdb = null, $stringId = null, $language = null ) {
|
||||
$has = function ( \wpdb $wpdb, $stringId, $language ) {
|
||||
$sql = "SELECT COUNT(id) FROM {$wpdb->prefix}icl_string_translations WHERE string_id = %d AND language = %s";
|
||||
|
||||
return $wpdb->get_var( $wpdb->prepare( $sql, $stringId, $language ) ) > 0;
|
||||
};
|
||||
|
||||
return call_user_func_array( curryN( 3, $has ), func_get_args() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\ST\DB\Mappers;
|
||||
|
||||
use \wpdb;
|
||||
use \WPML_DB_Chunk;
|
||||
|
||||
class StringsRetrieve {
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var WPML_DB_Chunk $chunk_retrieve */
|
||||
private $chunk_retrieve;
|
||||
|
||||
public function __construct( wpdb $wpdb, WPML_DB_Chunk $chunk_retrieve ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->chunk_retrieve = $chunk_retrieve;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language
|
||||
* @param string $domain
|
||||
* @param bool $modified_mo_only
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get( $language, $domain, $modified_mo_only = false ) {
|
||||
$args = [ $language, $language, $domain ];
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
s.id,
|
||||
st.status,
|
||||
s.domain_name_context_md5 AS ctx ,
|
||||
st.value AS translated,
|
||||
st.mo_string AS mo_string,
|
||||
s.value AS original,
|
||||
s.gettext_context,
|
||||
s.name
|
||||
FROM {$this->wpdb->prefix}icl_strings s
|
||||
" . $this->getStringTranslationJoin() . '
|
||||
' . $this->getDomainWhere();
|
||||
|
||||
if ( $modified_mo_only ) {
|
||||
$query .= $this->getModifiedMOOnlyWhere();
|
||||
}
|
||||
|
||||
$total_strings = $this->get_number_of_strings_in_domain( $language, $domain, $modified_mo_only );
|
||||
|
||||
return $this->chunk_retrieve->retrieve( $query, $args, $total_strings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language
|
||||
* @param string $domain
|
||||
* @param bool $modified_mo_only
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function get_number_of_strings_in_domain( $language, $domain, $modified_mo_only ) {
|
||||
$tables = "SELECT COUNT(s.id) FROM {$this->wpdb->prefix}icl_strings AS s";
|
||||
$where = $this->wpdb->prepare( $this->getDomainWhere(), [ $domain ] );
|
||||
|
||||
if ( $modified_mo_only ) {
|
||||
$tables .= $this->wpdb->prepare( $this->getStringTranslationJoin(), [ $language, $language ] );
|
||||
$where .= $this->getModifiedMOOnlyWhere();
|
||||
}
|
||||
|
||||
return (int) $this->wpdb->get_var( $tables . $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getStringTranslationJoin() {
|
||||
return " LEFT JOIN {$this->wpdb->prefix}icl_string_translations AS st
|
||||
ON s.id = st.string_id
|
||||
AND st.language = %s
|
||||
AND s.language != %s";
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function getDomainWhere() {
|
||||
return ' WHERE UPPER(context) = UPPER(%s)';
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function getModifiedMOOnlyWhere() {
|
||||
return ' AND st.status IN (' .
|
||||
wpml_prepare_in( [ ICL_TM_COMPLETE, ICL_TM_NEEDS_UPDATE ], '%d' ) .
|
||||
') AND st.value IS NOT NULL';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\ST\DB\Mappers;
|
||||
|
||||
class Update {
|
||||
/**
|
||||
* @param callable $getStringById
|
||||
* @param int $stringId
|
||||
* @param string $domain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function moveStringToDomain( callable $getStringById, $stringId, $domain ) {
|
||||
global $wpdb;
|
||||
|
||||
$string = $getStringById( $stringId );
|
||||
if ( $string ) {
|
||||
$wpdb->update( $wpdb->prefix . 'icl_strings', [ 'context' => $domain ], [ 'id' => $stringId ] );
|
||||
self::regenerateMOFiles( $string->context, $domain );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oldDomain
|
||||
* @param string $newDomain
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function moveAllStringsToNewDomain( $oldDomain, $newDomain ) {
|
||||
global $wpdb;
|
||||
|
||||
$affected = (int) $wpdb->update(
|
||||
$wpdb->prefix . 'icl_strings',
|
||||
[ 'context' => $newDomain ],
|
||||
[ 'context' => $oldDomain ]
|
||||
);
|
||||
|
||||
if ( $affected ) {
|
||||
self::regenerateMOFiles( $oldDomain, $newDomain );
|
||||
}
|
||||
|
||||
return $affected;
|
||||
}
|
||||
|
||||
private static function regenerateMOFiles( $oldDomain, $newDomain ) {
|
||||
do_action( 'wpml_st_refresh_domain', $oldDomain );
|
||||
do_action( 'wpml_st_refresh_domain', $newDomain );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Bulk_Strings_Insert_Exception extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class WPML_ST_Bulk_Strings_Insert {
|
||||
/** @var wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var int */
|
||||
private $chunk_size = 1000;
|
||||
|
||||
/**
|
||||
* @param wpdb $wpdb
|
||||
*/
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $chunk_size
|
||||
*/
|
||||
public function set_chunk_size( $chunk_size ) {
|
||||
$this->chunk_size = $chunk_size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WPML_ST_Models_String[] $strings
|
||||
*/
|
||||
public function insert_strings( array $strings ) {
|
||||
foreach ( array_chunk( $strings, $this->chunk_size ) as $chunk ) {
|
||||
|
||||
$query = "INSERT IGNORE INTO {$this->wpdb->prefix}icl_strings "
|
||||
. '(`language`, `context`, `gettext_context`, `domain_name_context_md5`, `name`, `value`, `status`) VALUES ';
|
||||
|
||||
$query .= implode( ',', array_map( array( $this, 'build_string_row' ), $chunk ) );
|
||||
|
||||
$this->wpdb->suppress_errors = true;
|
||||
$this->wpdb->query( $query );
|
||||
$this->wpdb->suppress_errors = false;
|
||||
if ( $this->wpdb->last_error ) {
|
||||
throw new WPML_ST_Bulk_Strings_Insert_Exception( 'Deadlock with bulk insert' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_ST_Models_String_Translation[] $translations
|
||||
*/
|
||||
public function insert_string_translations( array $translations ) {
|
||||
foreach ( array_chunk( $translations, $this->chunk_size ) as $chunk ) {
|
||||
$query = "INSERT IGNORE INTO {$this->wpdb->prefix}icl_string_translations "
|
||||
. '(`string_id`, `language`, `status`, `mo_string`) VALUES ';
|
||||
|
||||
$query .= implode( ',', array_map( array( $this, 'build_translation_row' ), $chunk ) );
|
||||
|
||||
$query .= ' ON DUPLICATE KEY UPDATE `mo_string`=VALUES(`mo_string`)';
|
||||
|
||||
$this->wpdb->suppress_errors = true;
|
||||
$this->wpdb->query( $query );
|
||||
$this->wpdb->suppress_errors = false;
|
||||
if ( $this->wpdb->last_error ) {
|
||||
throw new WPML_ST_Bulk_Strings_Insert_Exception( 'Deadlock with bulk insert' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_ST_Models_String $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_string_row( WPML_ST_Models_String $string ) {
|
||||
return $this->wpdb->prepare(
|
||||
'(%s, %s, %s, %s, %s, %s, %d)',
|
||||
$string->get_language(),
|
||||
$string->get_domain(),
|
||||
$string->get_context(),
|
||||
$string->get_domain_name_context_md5(),
|
||||
$string->get_name(),
|
||||
$string->get_value(),
|
||||
$string->get_status()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_ST_Models_String_Translation $translation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_translation_row( WPML_ST_Models_String_Translation $translation ) {
|
||||
return $this->wpdb->prepare(
|
||||
'(%d, %s, %d, %s)',
|
||||
$translation->get_string_id(),
|
||||
$translation->get_language(),
|
||||
$translation->get_status(),
|
||||
$translation->get_mo_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Bulk_Update_Strings_Status {
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var array $active_lang_codes */
|
||||
private $active_lang_codes;
|
||||
|
||||
public function __construct( wpdb $wpdb, array $active_lang_codes ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->active_lang_codes = $active_lang_codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This bulk process was transposed from PHP code
|
||||
*
|
||||
* @see WPML_ST_String::update_status
|
||||
*
|
||||
* Important: The order we call each method is important because it reflects
|
||||
* the order of the conditions in WPML_ST_String::update_status. The updated IDs
|
||||
* will not be updated anymore in the subsequent calls.
|
||||
*
|
||||
* @return array updated IDs
|
||||
*/
|
||||
public function run() {
|
||||
$updated_ids = $this->update_strings_with_no_translation();
|
||||
$updated_ids = $this->update_strings_with_all_translations_not_translated( $updated_ids );
|
||||
$updated_ids = $this->update_strings_with_one_translation_waiting_for_translator( $updated_ids );
|
||||
$updated_ids = $this->update_strings_with_one_translation_needs_update( $updated_ids );
|
||||
$updated_ids = $this->update_strings_with_less_translations_than_langs_and_one_translation_completed( $updated_ids );
|
||||
$updated_ids = $this->update_strings_with_less_translations_than_langs_and_no_translation_completed( $updated_ids );
|
||||
$updated_ids = $this->update_remaining_strings_with_one_not_translated( $updated_ids );
|
||||
$updated_ids = $this->update_remaining_strings( $updated_ids );
|
||||
|
||||
return $updated_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_no_translation() {
|
||||
$ids = $this->wpdb->get_col(
|
||||
"SELECT DISTINCT s.id FROM {$this->wpdb->prefix}icl_strings AS s
|
||||
LEFT JOIN {$this->wpdb->prefix}icl_string_translations AS st ON st.string_id = s.id
|
||||
WHERE st.string_id IS NULL"
|
||||
);
|
||||
|
||||
$this->update_strings_status( $ids, ICL_TM_NOT_TRANSLATED );
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_all_translations_not_translated( array $updated_ids ) {
|
||||
$subquery_not_exists = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( " AND (st.status != %d OR (st.mo_string != '' AND st.mo_string IS NOT NULL))", ICL_TM_NOT_TRANSLATED );
|
||||
|
||||
$ids = $this->wpdb->get_col(
|
||||
"SELECT DISTINCT s.id FROM {$this->wpdb->prefix}icl_strings AS s
|
||||
WHERE NOT EXISTS(" . $subquery_not_exists . ')'
|
||||
. $this->get_and_not_in_updated_snippet( $updated_ids )
|
||||
);
|
||||
|
||||
$this->update_strings_status( $ids, ICL_TM_NOT_TRANSLATED );
|
||||
|
||||
return array_merge( $updated_ids, $ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_one_translation_waiting_for_translator( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( ' AND st.status = %d', ICL_TM_WAITING_FOR_TRANSLATOR );
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_TM_WAITING_FOR_TRANSLATOR );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_one_translation_needs_update( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( ' AND st.status = %d', ICL_TM_NEEDS_UPDATE );
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_TM_NEEDS_UPDATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_less_translations_than_langs_and_one_translation_completed( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( " AND (st.status = %d OR (st.mo_string != '' AND st.mo_string IS NOT NULL))", ICL_TM_COMPLETE )
|
||||
. $this->get_and_translations_less_than_secondary_languages_snippet();
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_STRING_TRANSLATION_PARTIAL );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_strings_with_less_translations_than_langs_and_no_translation_completed( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( ' AND st.status != %d', ICL_TM_COMPLETE )
|
||||
. $this->get_and_translations_less_than_secondary_languages_snippet();
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_TM_NOT_TRANSLATED );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults to ICL_STRING_TRANSLATION_PARTIAL if not caught before
|
||||
*
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_remaining_strings_with_one_not_translated( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet()
|
||||
. $this->wpdb->prepare( " AND st.status = %d AND (st.mo_string = '' OR st.mo_string IS NULL)", ICL_TM_NOT_TRANSLATED );
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_STRING_TRANSLATION_PARTIAL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults to ICL_TM_COMPLETE if not caught before
|
||||
*
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_remaining_strings( array $updated_ids ) {
|
||||
$subquery = $this->get_translations_snippet();
|
||||
|
||||
return $this->update_string_ids_if_subquery_exists( $subquery, $updated_ids, ICL_TM_COMPLETE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subquery
|
||||
* @param array $updated_ids
|
||||
* @param int $new_status
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_string_ids_if_subquery_exists( $subquery, array $updated_ids, $new_status ) {
|
||||
$ids = $this->wpdb->get_col(
|
||||
"SELECT DISTINCT s.id FROM {$this->wpdb->prefix}icl_strings AS s
|
||||
WHERE EXISTS(" . $subquery . ')'
|
||||
. $this->get_and_not_in_updated_snippet( $updated_ids )
|
||||
);
|
||||
|
||||
$this->update_strings_status( $ids, $new_status );
|
||||
|
||||
return array_merge( $updated_ids, $ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* Subquery for the string translations
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_translations_snippet() {
|
||||
return "SELECT DISTINCT st.string_id
|
||||
FROM {$this->wpdb->prefix}icl_string_translations AS st
|
||||
WHERE st.string_id = s.id
|
||||
AND st.language != s.language";
|
||||
}
|
||||
|
||||
/**
|
||||
* Subquery where translations are less than the number of secondary languages:
|
||||
* - the string translation language must be different than the string language
|
||||
* - the string translation language must be part of the active languages
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_and_translations_less_than_secondary_languages_snippet() {
|
||||
$secondary_languages_count = count( $this->active_lang_codes ) - 1;
|
||||
|
||||
return $this->wpdb->prepare(
|
||||
" AND (
|
||||
SELECT COUNT( st2.id )
|
||||
FROM {$this->wpdb->prefix}icl_string_translations AS st2
|
||||
WHERE st2.string_id = s.id
|
||||
AND st2.language != s.language
|
||||
AND st2.language IN(" . wpml_prepare_in( $this->active_lang_codes ) . ')
|
||||
) < %d',
|
||||
$secondary_languages_count
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $updated_ids
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_and_not_in_updated_snippet( array $updated_ids ) {
|
||||
return ' AND s.id NOT IN(' . wpml_prepare_in( $updated_ids ) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ids
|
||||
* @param int $status
|
||||
*/
|
||||
private function update_strings_status( array $ids, $status ) {
|
||||
if ( ! $ids ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->wpdb->query(
|
||||
$this->wpdb->prepare(
|
||||
"UPDATE {$this->wpdb->prefix}icl_strings SET status = %d WHERE id IN(" . wpml_prepare_in( $ids ) . ')',
|
||||
$status
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_DB_Mappers_String_Positions {
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
|
||||
/**
|
||||
* @param wpdb $wpdb
|
||||
*/
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param int $kind
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_count_of_positions_by_string_and_kind( $string_id, $kind ) {
|
||||
$query = "
|
||||
SELECT COUNT(id)
|
||||
FROM {$this->wpdb->prefix}icl_string_positions
|
||||
WHERE string_id = %d AND kind = %d
|
||||
";
|
||||
|
||||
return (int) $this->wpdb->get_var( $this->wpdb->prepare( $query, $string_id, $kind ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param int $kind
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_positions_by_string_and_kind( $string_id, $kind ) {
|
||||
$query = "
|
||||
SELECT position_in_page
|
||||
FROM {$this->wpdb->prefix}icl_string_positions
|
||||
WHERE string_id = %d AND kind = %d
|
||||
";
|
||||
|
||||
return $this->wpdb->get_col( $this->wpdb->prepare( $query, $string_id, $kind ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param string $position
|
||||
* @param int $kind
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_string_tracked( $string_id, $position, $kind ) {
|
||||
$query = "
|
||||
SELECT id
|
||||
FROM {$this->wpdb->prefix}icl_string_positions
|
||||
WHERE string_id=%d AND position_in_page=%s AND kind=%s
|
||||
";
|
||||
|
||||
return (bool) $this->wpdb->get_var( $this->wpdb->prepare( $query, $string_id, $position, $kind ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param string $position
|
||||
* @param int $kind
|
||||
*/
|
||||
public function insert( $string_id, $position, $kind ) {
|
||||
$this->wpdb->insert( $this->wpdb->prefix . 'icl_string_positions', array(
|
||||
'string_id' => $string_id,
|
||||
'kind' => $kind,
|
||||
'position_in_page' => $position,
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_DB_Mappers_Strings {
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
|
||||
/**
|
||||
* @param wpdb $wpdb
|
||||
*/
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $context
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_by_context( $context ) {
|
||||
$where = strpos( $context, '%' ) === false ? '=' : 'LIKE';
|
||||
$query = "
|
||||
SELECT * FROM {$this->wpdb->prefix}icl_strings
|
||||
WHERE context {$where} %s
|
||||
";
|
||||
|
||||
$query = $this->wpdb->prepare( $query, esc_sql( $context ) );
|
||||
|
||||
return $this->wpdb->get_results( $query, ARRAY_A );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single string row by its domain and value
|
||||
*
|
||||
* @param string $domain
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByDomainAndValue( $domain, $value ) {
|
||||
$sql = "SELECT * FROM {$this->wpdb->prefix}icl_strings WHERE `context` = %s and `value` = %s";
|
||||
|
||||
return $this->wpdb->get_row( $this->wpdb->prepare( $sql, $domain, $value ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single string row by its id
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getById( $id ) {
|
||||
$sql = "SELECT * FROM {$this->wpdb->prefix}icl_strings WHERE id = %d";
|
||||
|
||||
return $this->wpdb->get_row( $this->wpdb->prepare( $sql, $id ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Models_String_Translation {
|
||||
/** @var int */
|
||||
private $string_id;
|
||||
|
||||
/** @var string */
|
||||
private $language;
|
||||
|
||||
/** @var int */
|
||||
private $status;
|
||||
|
||||
/** @var string */
|
||||
private $value;
|
||||
|
||||
/** @var string */
|
||||
private $mo_string;
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param string $language
|
||||
* @param int $status
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct( $string_id, $language, $status, $value, $mo_string ) {
|
||||
$this->string_id = (int) $string_id;
|
||||
$this->language = (string) $language;
|
||||
$this->status = (int) $status;
|
||||
$this->value = (string) $value;
|
||||
$this->mo_string = (string) $mo_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_string_id() {
|
||||
return $this->string_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_language() {
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_status() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_value() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_mo_string() {
|
||||
return $this->mo_string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Models_String {
|
||||
/** @var string */
|
||||
private $language;
|
||||
|
||||
/** @var string */
|
||||
private $domain;
|
||||
|
||||
/** @var string */
|
||||
private $context;
|
||||
|
||||
/** @var string */
|
||||
private $value;
|
||||
|
||||
/** @var int */
|
||||
private $status;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var string */
|
||||
private $domain_name_context_md5;
|
||||
|
||||
/**
|
||||
* @param string $language
|
||||
* @param string $domain
|
||||
* @param string $context
|
||||
* @param string $value
|
||||
* @param int $status
|
||||
* @param string|null $name
|
||||
*/
|
||||
public function __construct( $language, $domain, $context, $value, $status, $name = null ) {
|
||||
$this->language = (string) $language;
|
||||
$this->domain = (string) $domain;
|
||||
$this->context = (string) $context;
|
||||
$this->value = (string) $value;
|
||||
$this->status = (int) $status;
|
||||
|
||||
if ( ! $name ) {
|
||||
$name = md5( $value );
|
||||
}
|
||||
$this->name = (string) $name;
|
||||
|
||||
$this->domain_name_context_md5 = md5( $domain . $name . $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_language() {
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_domain() {
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_context() {
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_value() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_status() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_domain_name_context_md5() {
|
||||
return $this->domain_name_context_md5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Word_Count_Package_Records {
|
||||
|
||||
/** @var wpdb */
|
||||
private $wpdb;
|
||||
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_all_package_ids() {
|
||||
return array_map(
|
||||
'intval',
|
||||
$this->wpdb->get_col( "SELECT ID FROM {$this->wpdb->prefix}icl_string_packages" )
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_packages_ids_without_word_count() {
|
||||
return array_map(
|
||||
'intval',
|
||||
$this->wpdb->get_col(
|
||||
"SELECT ID FROM {$this->wpdb->prefix}icl_string_packages WHERE word_count IS NULL"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_word_counts( $post_id ) {
|
||||
return $this->wpdb->get_col(
|
||||
$this->wpdb->prepare(
|
||||
"SELECT word_count FROM {$this->wpdb->prefix}icl_string_packages WHERE post_id = %d",
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
* @param string $word_count
|
||||
*/
|
||||
public function set_word_count( $package_id, $word_count ) {
|
||||
$this->wpdb->update(
|
||||
$this->wpdb->prefix . 'icl_string_packages',
|
||||
array( 'word_count' => $word_count ),
|
||||
array( 'ID' => $package_id )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_word_count( $package_id ) {
|
||||
return $this->wpdb->get_var(
|
||||
$this->wpdb->prepare(
|
||||
"SELECT word_count FROM {$this->wpdb->prefix}icl_string_packages WHERE ID = %d",
|
||||
$package_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function reset_all( array $package_kinds ) {
|
||||
if ( ! $package_kinds ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$query = "UPDATE {$this->wpdb->prefix}icl_string_packages SET word_count = NULL
|
||||
WHERE kind_slug IN(" . wpml_prepare_in( $package_kinds ) . ')';
|
||||
|
||||
$this->wpdb->query( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $kinds
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids_from_kind_slugs( array $kinds ) {
|
||||
if ( ! $kinds ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = "SELECT ID FROM {$this->wpdb->prefix}icl_string_packages
|
||||
WHERE kind_slug IN(" . wpml_prepare_in( $kinds ) . ')';
|
||||
|
||||
return array_map( 'intval', $this->wpdb->get_col( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $post_types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids_from_post_types( array $post_types ) {
|
||||
if ( ! $post_types ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = "SELECT sp.ID FROM {$this->wpdb->prefix}icl_string_packages AS sp
|
||||
LEFT JOIN {$this->wpdb->posts} AS p
|
||||
ON p.ID = sp.post_id
|
||||
WHERE p.post_type IN(" . wpml_prepare_in( $post_types ) . ')';
|
||||
|
||||
return array_map( 'intval', $this->wpdb->get_col( $query ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kind_slug
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count_items_by_kind_not_part_of_posts( $kind_slug ) {
|
||||
$query = "SELECT COUNT(*) FROM {$this->wpdb->prefix}icl_string_packages
|
||||
WHERE kind_slug = %s AND post_id IS NULL";
|
||||
|
||||
return (int) $this->wpdb->get_var( $this->wpdb->prepare( $query, $kind_slug ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kind_slug
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count_word_counts_by_kind( $kind_slug ) {
|
||||
$query = "SELECT COUNT(*) FROM {$this->wpdb->prefix}icl_string_packages
|
||||
WHERE kind_slug = %s AND word_count IS NOT NULL
|
||||
AND post_id IS NULL";
|
||||
|
||||
return (int) $this->wpdb->get_var( $this->wpdb->prepare( $query, $kind_slug ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kind_slug
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_word_counts_by_kind( $kind_slug ) {
|
||||
$query = "SELECT word_count FROM {$this->wpdb->prefix}icl_string_packages
|
||||
WHERE kind_slug = %s";
|
||||
|
||||
return $this->wpdb->get_col( $this->wpdb->prepare( $query, $kind_slug ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Word_Count_String_Records {
|
||||
|
||||
const CACHE_GROUP = __CLASS__;
|
||||
|
||||
/** @var wpdb */
|
||||
private $wpdb;
|
||||
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/** @return int */
|
||||
public function get_total_words() {
|
||||
return (int) $this->wpdb->get_var( "SELECT SUM(word_count) FROM {$this->wpdb->prefix}icl_strings" );
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_all_values_without_word_count() {
|
||||
$query = "
|
||||
SELECT id, value FROM {$this->wpdb->prefix}icl_strings
|
||||
WHERE word_count IS NULL
|
||||
";
|
||||
|
||||
return $this->wpdb->get_results( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $lang
|
||||
* @param null|string $package_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_words_to_translate_per_lang( $lang, $package_id = null ) {
|
||||
$key = $lang . ':' . $package_id;
|
||||
$found = false;
|
||||
$words = WPML_Non_Persistent_Cache::get( $key, self::CACHE_GROUP, $found );
|
||||
if ( ! $found ) {
|
||||
$query = "
|
||||
SELECT SUM(word_count) FROM {$this->wpdb->prefix}icl_strings AS s
|
||||
LEFT JOIN {$this->wpdb->prefix}icl_string_translations AS st
|
||||
ON st.string_id = s.id AND st.language = %s
|
||||
WHERE (st.status <> %d OR st.status IS NULL)
|
||||
";
|
||||
|
||||
$prepare_args = [
|
||||
$lang,
|
||||
ICL_STRING_TRANSLATION_COMPLETE,
|
||||
];
|
||||
|
||||
if ( $package_id ) {
|
||||
$query .= ' AND s.string_package_id = %d';
|
||||
|
||||
$prepare_args[] = $package_id;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
$words = (int) $this->wpdb->get_var( $this->wpdb->prepare( $query, $prepare_args ) );
|
||||
WPML_Non_Persistent_Cache::set( $key, $words, self::CACHE_GROUP );
|
||||
}
|
||||
|
||||
return $words;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function get_value_and_language( $string_id ) {
|
||||
return $this->wpdb->get_row(
|
||||
$this->wpdb->prepare(
|
||||
"SELECT value, language FROM {$this->wpdb->prefix}icl_strings WHERE id = %d",
|
||||
$string_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param int $word_count
|
||||
*/
|
||||
public function set_word_count( $string_id, $word_count ) {
|
||||
$this->wpdb->update(
|
||||
$this->wpdb->prefix . 'icl_strings',
|
||||
array( 'word_count' => $word_count ),
|
||||
array( 'id' => $string_id )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_word_count( $string_id ) {
|
||||
return (int) $this->wpdb->get_var(
|
||||
$this->wpdb->prepare(
|
||||
"SELECT word_count FROM {$this->wpdb->prefix}icl_strings WHERE ID = %d",
|
||||
$string_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function reset_all() {
|
||||
$this->wpdb->query( "UPDATE {$this->wpdb->prefix}icl_strings SET word_count = NULL" );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $package_ids
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids_from_package_ids( array $package_ids ) {
|
||||
if ( ! $package_ids ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = "SELECT id FROM {$this->wpdb->prefix}icl_strings
|
||||
WHERE string_package_id IN(" . wpml_prepare_in( $package_ids ) . ')';
|
||||
|
||||
return array_map( 'intval', $this->wpdb->get_col( $query ) );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user