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,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();

View File

@@ -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 );
}
}

View File

@@ -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() );
}
}

View File

@@ -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';
}
}

View File

@@ -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 );
}
}

View File

@@ -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()
);
}
}

View File

@@ -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
)
);
}
}

View File

@@ -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,
) );
}
}

View File

@@ -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 ) );
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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 ) );
}
}

View File

@@ -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 ) );
}
}