158 lines
4.0 KiB
PHP
158 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace WPML\ST\TranslationFile;
|
|
|
|
use WPML\Collect\Support\Collection;
|
|
use WPML\ST\TranslateWpmlString;
|
|
|
|
class StringsRetrieve {
|
|
|
|
// We need to store the strings by key that is a combination of original and gettext context
|
|
// The join needs to be something that is unlikely to be in either so we can split later.
|
|
const KEY_JOIN = '::JOIN::';
|
|
|
|
/** @var \WPML\ST\DB\Mappers\StringsRetrieve */
|
|
private $string_retrieve;
|
|
|
|
/**
|
|
* @param \WPML\ST\DB\Mappers\StringsRetrieve $string_retrieve
|
|
*/
|
|
public function __construct( \WPML\ST\DB\Mappers\StringsRetrieve $string_retrieve ) {
|
|
$this->string_retrieve = $string_retrieve;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $domain
|
|
* @param string $language
|
|
* @param bool $modified_mo_only
|
|
*
|
|
* @return StringEntity[]
|
|
*/
|
|
public function get( $domain, $language, $modified_mo_only ) {
|
|
return $this->loadFromDb( $language, $domain, $modified_mo_only )
|
|
->filter(
|
|
function ( $string ) {
|
|
return (bool) $string['translation'];
|
|
}
|
|
)
|
|
->mapToGroups(
|
|
function ( array $string ) {
|
|
return $this->groupPluralFormsOfSameString( $string );
|
|
}
|
|
)
|
|
->map(
|
|
function ( Collection $strings, $key ) {
|
|
return $this->buildStringEntity( $strings, $key );
|
|
}
|
|
)
|
|
->values()
|
|
->toArray();
|
|
}
|
|
|
|
/**
|
|
* @param string $language
|
|
* @param string $domain
|
|
* @param bool $modified_mo_only
|
|
*
|
|
* @return Collection
|
|
*/
|
|
private function loadFromDb( $language, $domain, $modified_mo_only = false ) {
|
|
$result = \wpml_collect( $this->string_retrieve->get( $language, $domain, $modified_mo_only ) );
|
|
|
|
return $result->map(
|
|
function ( $row ) {
|
|
return $this->parseResult( $row );
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $row_data
|
|
*
|
|
* @return array
|
|
*/
|
|
private function parseResult( array $row_data ) {
|
|
return [
|
|
'id' => $row_data['id'],
|
|
'original' => $row_data['original'],
|
|
'context' => $row_data['gettext_context'],
|
|
'translation' => self::parseTranslation( $row_data ),
|
|
'name' => $row_data['name'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array $row_data
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public static function parseTranslation( array $row_data ) {
|
|
$value = null;
|
|
|
|
$has_translation = ! empty( $row_data['translated'] ) && in_array( $row_data['status'], [ ICL_TM_COMPLETE, ICL_TM_NEEDS_UPDATE ] );
|
|
if ( $has_translation ) {
|
|
$value = $row_data['translated'];
|
|
} elseif ( ! empty( $row_data['mo_string'] ) ) {
|
|
$value = $row_data['mo_string'];
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* @param array $string
|
|
*
|
|
* @return array
|
|
*/
|
|
private function groupPluralFormsOfSameString( array $string ) {
|
|
$groupKey = $this->getPluralGroupKey( $string );
|
|
$pattern = '/^(.+) \[plural ([0-9]+)\]$/';
|
|
|
|
if ( preg_match( $pattern, $string['original'], $matches ) ) {
|
|
$string['original'] = $matches[1];
|
|
$string['index'] = $matches[2];
|
|
} else {
|
|
$string['index'] = null;
|
|
}
|
|
|
|
return [
|
|
$string['original'] . self::KEY_JOIN . $string['context'] . self::KEY_JOIN . $groupKey => $string,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Inside a domain, we can have several occurrences of strings
|
|
* with the same original, but with different names.
|
|
* In this situation, we should not try to group plurals.
|
|
*
|
|
* @param array $string
|
|
*
|
|
* @return mixed|string
|
|
*/
|
|
private function getPluralGroupKey( array $string ) {
|
|
$cannotBelongToPluralGroup = TranslateWpmlString::canTranslateWithMO( $string['original'], $string['name'] );
|
|
|
|
if ( $cannotBelongToPluralGroup ) {
|
|
return $string['name'];
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @param Collection $strings
|
|
* @param string $key
|
|
*
|
|
* @return StringEntity
|
|
*/
|
|
private function buildStringEntity( Collection $strings, $key ) {
|
|
$translations = $strings->sortBy( 'index' )->pluck( 'translation' )->toArray();
|
|
list( $original, $context ) = explode( self::KEY_JOIN, $key );
|
|
$stringEntity = new StringEntity( $original, $translations, $context );
|
|
$stringEntity->set_name( $strings->first()['name'] );
|
|
|
|
return $stringEntity;
|
|
}
|
|
}
|