Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/batch-translation.tar
Назад
Hooks.php 0000644 00000004077 14721667024 0006361 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\FP\Fns; use WPML\FP\Obj; use WPML\LIB\WP\Hooks as WPHooks; use function WPML\FP\spreadArgs; class Hooks { public static function addHooks( callable $getBatchId, callable $setBatchRecord, callable $getBatchRecord, callable $getString ) { WPHooks::onFilter( 'wpml_tm_batch_factory_elements', 10, 2 ) ->then( spreadArgs( Convert::toBatchElements( $getBatchId, $setBatchRecord ) ) ); WPHooks::onFilter( 'wpml_tm_basket_items_types', 10, 1 ) ->then( spreadArgs( Obj::set( Obj::lensProp( 'st-batch' ), 'core' ) ) ); WPHooks::onFilter( 'wpml_is_external', 10, 2 ) ->then( spreadArgs( function ( $state, $type ) { return $state || ( is_object( $type ) && Obj::prop( 'post_type', $type ) === 'strings' ) || $type === 'st-batch'; } ) ); WPHooks::onFilter( 'wpml_get_translatable_item', 10, 3 ) ->then( spreadArgs( Strings::get( $getBatchRecord, $getString ) ) ); WPHooks::onAction( 'wpml_save_external', 10, 3 ) ->then( spreadArgs( StringTranslations::save() ) ); WPHooks::onFilter( 'wpml_tm_populate_prev_translation', 10, 3 ) ->then( spreadArgs( StringTranslations::addExisting() ) ); } public static function addStringTranslationStatusHooks( callable $updateTranslationStatus, callable $initializeTranslation ) { WPHooks::onAction( 'wpml_tm_added_translation_element', 10, 2 )->then( spreadArgs( $initializeTranslation ) ); WPHooks::onAction( 'wpml_tm_job_in_progress', 10, 2 )->then( spreadArgs( $updateTranslationStatus ) ); WPHooks::onAction( 'wpml_tm_job_cancelled', 10, 1 )->then( spreadArgs( StringTranslations::cancelTranslations() ) ); WPHooks::onAction( 'wpml_tm_jobs_cancelled', 10, 1 )->then( spreadArgs( function ( $jobs ) { /** * We need this check because if we pass only one job to the hook: * do_action( 'wpml_tm_jobs_cancelled', [ $job ] ) * then WordPress converts it to $job. */ if ( is_object( $jobs ) ) { $jobs = [ $jobs ]; } Fns::map( StringTranslations::cancelTranslations(), $jobs ); } ) ); } } Status.php 0000644 00000004661 14721667024 0006560 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\FP\Lst; use WPML\FP\Fns; use WPML\FP\Obj; class Status { public static function add( array $translations, $languages ) { global $wpdb; $batches = Records::findBatches( $wpdb, array_keys( $translations ) ); $statuses = self::getStatuses( $wpdb, $batches ); foreach ( $translations as $id => $string ) { foreach ( Obj::propOr( [], 'translations', $string ) as $lang => $data ) { $status = Obj::pathOr( null, [ $id, $lang ], $statuses ); if ( $status ) { $translations[ $id ]['translations'][ $lang ]['status'] = $status; } } } return $translations; } public static function getStatuses( \wpdb $wpdb, $batches ) { $batchIds = array_unique( array_values( $batches ) ); if ( $batchIds ) { $in = wpml_prepare_in( $batchIds, '%d' ); $trids = $wpdb->get_results( "SELECT element_id, trid FROM {$wpdb->prefix}icl_translations WHERE element_id IN ({$in}) AND element_type = 'st-batch_strings'" ); $keyByBatchId = Fns::converge( Lst::zipObj(), [ Lst::pluck( 'element_id' ), Lst::pluck( 'trid' ) ] ); $trids = $keyByBatchId( $trids ); $in = wpml_prepare_in( $trids, '%d' ); /** @var array $transIds */ $transIds = $wpdb->get_results( "SELECT translation_id, trid, language_code FROM {$wpdb->prefix}icl_translations WHERE trid IN ({$in}) AND source_language_code IS NOT NULL" ); $in = wpml_prepare_in( Lst::pluck( 'translation_id', $transIds ), '%d' ); $statuses = $wpdb->get_results( "SELECT status, translation_id FROM {$wpdb->prefix}icl_translation_status WHERE translation_id IN ({$in})" ); $keyByTranslationId = Fns::converge( Lst::zipObj(), [ Lst::pluck( 'translation_id' ), Lst::pluck( 'status' ), ] ); $statuses = $keyByTranslationId( $statuses ); $keyByTrid = Fns::converge( Lst::zipObj(), [ Lst::pluck( 'trid' ), Fns::identity() ] ); return wpml_collect( $batches ) ->map( Obj::prop( Fns::__, $trids ) ) ->map( Obj::prop( Fns::__, $keyByTrid( $transIds ) ) ) ->map( function ( $item ) use ( $statuses ) { return [ $item->language_code => Obj::prop( $item->translation_id, $statuses ) ]; } ) ->toArray(); } else { return []; } } public static function getStatusesOfBatch( \wpdb $wpdb, $batchId ) { $statuses = self::getStatuses( $wpdb, [ $batchId ] ); return count( $statuses ) ? current( $statuses ) : []; } } Strings.php 0000644 00000002203 14721667024 0006714 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\Collect\Support\Traits\Macroable; use WPML\FP\Fns; use function WPML\FP\curryN; /** * Class Strings * * @package WPML\ST\Batch\Translation * @method static callable|object get( ...$getBatchRecord, ...$getString, ...$item, ...$id, ...$type ) */ class Strings { use Macroable; public static function init() { self::macro( 'get', curryN( 5, function ( callable $getBatchRecord, callable $getString, $item, $id, $type ) { if ( $type === 'st-batch' || $type === Module::EXTERNAL_TYPE ) { $getBatchString = function ( $strings, $stringId ) use ( $getString ) { $strings[ Module::STRING_ID_PREFIX . $stringId ] = $getString( $stringId ); return $strings; }; return (object) [ 'post_id' => $id, 'ID' => $id, 'post_type' => 'strings', 'kind' => 'Strings', 'kind_slug' => 'Strings', 'external_type' => true, 'string_data' => Fns::reduce( $getBatchString, [], $getBatchRecord( $id ) ), ]; } return $item; } ) ); } } Strings::init(); Convert.php 0000644 00000003652 14721667024 0006714 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\Collect\Support\Traits\Macroable; use WPML\FP\Fns; use WPML\FP\Relation; use function WPML\FP\curryN; use function WPML\FP\invoke; use function WPML\FP\pipe; /** * Class Convert * * @package WPML\ST\Batch\Translation * @method static callable|array toBatchElements( ...$getBatchId, ...$setBatchRecord, ...$elements, ...$basketName ) :: ( string → int ) → ( int → int → string ) → [WPML_TM_Translation_Batch_Element] → string → [WPML_TM_Translation_Batch_Element] */ class Convert { use Macroable; public static function init() { self::macro( 'toBatchElements', curryN( 4, function ( $getBatchId, $setBatchRecord, $elements, $basketName ) { // $isString :: WPML_TM_Translation_Batch_Element → bool $isString = pipe( invoke( 'get_element_type' ), Relation::equals( 'string' ) ); list( $stringElements, $otherElements ) = wpml_collect( $elements )->partition( $isString ); $makeBatchPerLanguage = function ( \WPML_TM_Translation_Batch_Element $element ) use ( $getBatchId, $setBatchRecord, $basketName ) { $makeBatchElement = function ( $action, $lang ) use ( $element, $getBatchId, $setBatchRecord, $basketName ) { $batchId = $getBatchId( $basketName . '-' . $lang ); $setBatchRecord( $batchId, $element->get_element_id(), $element->get_source_lang() ); return Fns::makeN( 5, 'WPML_TM_Translation_Batch_Element', $batchId, 'st-batch', $element->get_source_lang(), [ $lang => $action ], [] ); }; return Fns::map( $makeBatchElement, $element->get_target_langs() ); }; $stringElements = $stringElements->map( $makeBatchPerLanguage ) ->flatten() ->unique( invoke( 'get_target_langs' ) ); return $otherElements->merge( $stringElements ) ->toArray(); } ) ); } } Convert::init(); Records.php 0000644 00000005137 14721667024 0006675 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\FP\Curryable; use WPML\FP\Fns; use WPML\FP\Lst; use function WPML\Container\make; use function WPML\FP\curryN; /** * @phpstan-type curried '__CURRIED_PLACEHOLDER__' * * @method static callable|void installSchema( ...$wpdb ) :: wpdb → void * @method static callable|void set( ...$wpdb, ...$batchId, ...$stringId ) :: wpdb → int → int → void * @method static callable|int[] findBatches( ...$wpdb, ...$stringId ) :: wpdb → int → int[] */ class Records { use Curryable; /** @var string */ public static $string_batch_sql_prototype = ' CREATE TABLE IF NOT EXISTS `%sicl_string_batches` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `string_id` bigint(20) unsigned NOT NULL, `batch_id` bigint(20) unsigned NOT NULL, PRIMARY KEY (`id`) ) '; /** * @param \wpdb|null $wpdb * @param int|curried $batchId * @return int|callable * * @phpstan-return ($batchId is not null ? int : callable) */ public static function get( \wpdb $wpdb = null, $batchId = null ) { return call_user_func_array( curryN( 2, function ( \wpdb $wpdb, $batchId ) { /** @var string $sql */ $sql = $wpdb->prepare( "SELECT string_id FROM {$wpdb->prefix}icl_string_batches WHERE batch_id = %d", $batchId ); return $wpdb->get_col( $sql ); } ), func_get_args() ); } } Records::curryN( 'installSchema', 1, function ( \wpdb $wpdb ) { $option = make( 'WPML\WP\OptionManager' ); if ( ! $option->get( 'ST', Records::class . '_schema_installed' ) ) { $wpdb->query( sprintf( Records::$string_batch_sql_prototype, $wpdb->prefix ) ); $option->set( 'ST', Records::class . '_schema_installed', true ); } } ); Records::curryN( 'set', 3, function ( \wpdb $wpdb, $batchId, $stringId ) { // TODO: ignore duplicates $wpdb->insert( "{$wpdb->prefix}icl_string_batches", [ 'batch_id' => $batchId, 'string_id' => $stringId, ], [ '%d', '%d' ] ); } ); Records::curryN( 'findBatch', 2, function ( \wpdb $wpdb, $stringId ) { /** @var string $sql */ $sql = $wpdb->prepare( "SELECT batch_id FROM {$wpdb->prefix}icl_string_batches WHERE string_id = %d", $stringId ); return $wpdb->get_var( $sql ); } ); Records::curryN( 'findBatches', 2, function ( \wpdb $wpdb, $stringIds ) { $in = wpml_prepare_in( $stringIds, '%d' ); $data = $wpdb->get_results( "SELECT batch_id, string_id FROM {$wpdb->prefix}icl_string_batches WHERE string_id IN ({$in})" ); $keyByStringId = Fns::converge( Lst::zipObj(), [ Lst::pluck( 'string_id' ), Lst::pluck( 'batch_id' ) ] ); return $keyByStringId( $data ); } ); Module.php 0000644 00000005157 14721667024 0006523 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\Collect\Support\Traits\Macroable; use WPML\FP\Fns; use function WPML\Container\make; use function WPML\FP\curryN; use function WPML\FP\partial; /** * Class Module * @package WPML\ST\Batch\Translation * * @phpstan-type curried '__CURRIED_PLACEHOLDER__' * * @method static callable getBatchId() :: ( string → int ) * @method static callable|void setBatchLanguage( ...$batchId, ...$sourceLang ) :: int → string → void */ class Module { use Macroable; const EXTERNAL_TYPE = 'st-batch_strings'; const STRING_ID_PREFIX = 'batch-string-'; public static function init() { global $sitepress, $wpdb; Records::installSchema( $wpdb ); self::macro( 'getBatchId', curryN( 1, function ( $batch ) { return \TranslationProxy_Batch::update_translation_batch( $batch ); } ) ); $setLanguage = curryN( 4, [ $sitepress, 'set_element_language_details' ] ); self::macro( 'setBatchLanguage', $setLanguage( Fns::__, self::EXTERNAL_TYPE, null, Fns::__ ) ); /** @var callable $initializeTranslation */ $initializeTranslation = StringTranslations::markTranslationsAsInProgress( partial( [ Status::class, 'getStatusesOfBatch' ], $wpdb ) ); /** @var callable $recordSetter */ $recordSetter = Records::set( $wpdb ); Hooks::addHooks( self::getBatchId(), self::batchStringsStorage( $recordSetter ), Records::get( $wpdb ), self::getString() ); Hooks::addStringTranslationStatusHooks( StringTranslations::updateStatus(), $initializeTranslation ); } /** * @param int $id * @return string|callable * @phpstan-return ($id is not null ? string : callable ) */ public static function getString( $id = null ) { return call_user_func_array( curryN( 1, function ( $id ) { return make( '\WPML_ST_String', [ ':string_id' => $id ] )->get_value(); } ), func_get_args() ); } /** * @param callable|curried $saveBatch * @param int|curried $batchId * @param int|curried $stringId * @param string|curried $sourceLang * @return void|callable * * @phpstan-param ?callable $saveBatch * @phpstan-param ?int $batchId * @phpstan-param ?int $stringId * @phpstan-param ?string $sourceLang * * @phpstan-return ( $sourceLang is not null ? void : callable ) * */ public static function batchStringsStorage( callable $saveBatch = null, $batchId = null, $stringId = null, $sourceLang = null ) { return call_user_func_array( curryN( 4, function ( callable $saveBatch, $batchId, $stringId, $sourceLang ) { self::setBatchLanguage( $batchId, $sourceLang ); $saveBatch( $batchId, $stringId ); } ), func_get_args() ); } } StringTranslations.php 0000644 00000020433 14721667024 0011140 0 ustar 00 <?php namespace WPML\ST\Batch\Translation; use WPML\Collect\Support\Traits\Macroable; use WPML\FP\Fns; use WPML\FP\Logic; use WPML\FP\Obj; use WPML\FP\Str; use WPML\FP\Wrapper; use WPML\Setup\Option; use WPML\ST\API\Fns as ST_API; use function WPML\Container\make; use function WPML\FP\curryN; use function WPML\FP\invoke; use function WPML\FP\pipe; use function WPML\FP\spreadArgs; /** * Class StringTranslations * * @package WPML\ST\Batch\Translation * * @phpstan-type curried '__CURRIED_PLACEHOLDER__' * * @method static callable|void save( ...$element_type_prefix, ...$job, ...$decoder ) :: string → object → ( string → string → string ) → void * @method static callable|void addExisting( ...$prevTranslations, ...$package, ...$lang ) :: [WPML_TM_Translated_Field] → object → string → [WPML_TM_Translated_Field] * @method static callable|bool isTranslated( ...$field ) :: object → bool * @method static callable|void markTranslationsAsInProgress( ...$getJobStatus, ...$hasTranslation, ...$addTranslation, ...$post, ...$element) :: callable -> callable -> callable -> WPML_TM_Translation_Batch_Element -> \stdClass -> void * @method static callable|void cancelTranslations(...$job) :: \WPML_TM_Job_Entity -> void */ class StringTranslations { use Macroable; public static function init() { self::macro( 'isTranslated', Obj::prop( 'field_translate' ) ); self::macro( 'isBatchField', curryN( 1, function( $field ) { return self::isBatchId( Obj::prop( 'field_type', $field ) ); } ) ); self::macro( 'save', curryN( 3, function ( $element_type_prefix, $job, callable $decoder ) { if ( $element_type_prefix === 'st-batch' ) { // $decodeField :: field → string $decodeField = pipe( Obj::props( [ 'field_data_translated', 'field_format' ] ), spreadArgs( $decoder ) ); // $getStringId :: field → int $getStringId = pipe( Obj::prop( 'field_type' ), self::decodeStringId() ); // $saveTranslation :: field → void $saveTranslation = Fns::converge( ST_API::saveTranslation( Fns::__, $job->language_code, Fns::__, ICL_TM_COMPLETE ), [ $getStringId, $decodeField ] ); /** @var callable $filterTranslatedAndBatchField */ $filterTranslatedAndBatchField = Logic::allPass( [ self::isTranslated(), self::isBatchField() ] ); Wrapper::of( $job->elements ) ->map( Fns::filter( $filterTranslatedAndBatchField ) ) ->map( Fns::each( $saveTranslation ) ); } } ) ); self::macro( 'cancelTranslations', curryN( 1, function ( $job ) { if ( $job instanceof \WPML_TM_Post_Job_Entity && $job->get_type() === 'st-batch_strings' ) { $language = $job->get_target_language(); // $getTranslations :: $stringId -> [stringId, translation] $getTranslations = function ( $stringId ) use ( $language ) { return [ 'string_id' => $stringId, 'translation' => Obj::pathOr( '', [ $language, 'value' ], ST_API::getTranslations( $stringId ) ), ]; }; // $cancelStatus :: [stringId, translation] -> int $cancelStatus = Logic::ifElse( Obj::prop( 'translation' ), Fns::always( ICL_TM_COMPLETE ), Fns::always( ICL_TM_NOT_TRANSLATED ) ); // $cancel :: [stringId, translation] -> void $cancel = Fns::converge( ST_API::updateStatus( Fns::__, $language, Fns::__ ), [ Obj::prop( 'string_id' ), $cancelStatus ] ); \wpml_collect( $job->get_elements() ) ->map( invoke( 'get_type' ) ) ->filter( Fns::unary( self::isBatchId() ) ) ->map( self::decodeStringId() ) ->map( $getTranslations ) ->map( Fns::tap( $cancel ) ); } } ) ); self::macro( 'addExisting', curryN( 3, function ( $prevTranslations, $package, $lang ) { // $getTranslation :: lang → { translate, ... } → int → { id, translation } | null $getTranslation = curryN( 3, function ( $lang, $data, $stringId ) { if ( $data['translate'] === 1 && self::isBatchId( $stringId ) ) { /** @var string $translation */ $translation = ST_API::getTranslation( self::decodeStringId( $stringId ), $lang ); return (object) [ 'id' => $stringId, 'translation' => base64_encode( is_null( $translation ) ? '' : $translation ), ]; } return null; } ); // $createField :: string → WPML_TM_Translated_Field $createField = function ( $translation ) { return make( 'WPML_TM_Translated_Field', [ '', '', $translation, false ] ); }; // $updatePrevious :: [a] → { id, translate } → [a] $updatePrevious = function ( $prev, $string ) { $prev[ $string->id ] = $string->translation; return $prev; }; // $hasTranslation :: { id, translation } | null → bool $hasTranslation = Obj::prop( 'translation' ); return Wrapper::of( $package['contents'] ) ->map( Fns::map( $getTranslation( $lang ) ) ) ->map( Fns::filter( $hasTranslation ) ) ->map( Fns::map( Obj::evolve( [ 'translation' => $createField ] ) ) ) ->map( Fns::reduce( $updatePrevious, $prevTranslations ) ) ->get(); } ) ); self::macro( 'markTranslationsAsInProgress', curryN( 3, function ( $getJobStatus, $element, $post ) { if ( $element instanceof \WPML_TM_Translation_Batch_Element && $element->get_element_type() === 'st-batch' ) { $statuses = \wpml_collect( $getJobStatus( $post->post_id ) ); $addTranslationWithStatus = function ( $stringId, $targetLanguage ) use ( $statuses ) { $status = Option::shouldTranslateEverything() ? ICL_TM_IN_PROGRESS : $statuses->get( $targetLanguage, ICL_STRING_TRANSLATION_NOT_TRANSLATED ); ST_API::updateStatus( $stringId, $targetLanguage, $status ); }; \wpml_collect( $post->string_data ) ->keys() ->map( Fns::unary( StringTranslations::decodeStringId() ) ) ->map( Fns::unary( 'intval' ) ) ->crossJoin( array_keys( $element->get_target_langs() ) ) ->map( Fns::tap( spreadArgs( $addTranslationWithStatus ) ) ); } } ) ); } /** * @param string $element_type_prefix * @param \stdClass $job * @return callable|void * @phpstan-return ( $job is not null ? void : callable ) */ public static function updateStatus( $element_type_prefix = null, $job = null ) { return call_user_func_array( curryN( 2, function ( $element_type_prefix, $job ) { if ( $element_type_prefix === 'st-batch' ) { // $getStringId :: field → int $getStringId = pipe( Obj::prop( 'field_type' ), self::decodeStringId() ); /** @var callable $updateStatus */ $updateStatus = ST_API::updateStatus( Fns::__, $job->language_code, ICL_TM_IN_PROGRESS ); \wpml_collect( $job->elements ) ->filter( self::isBatchField() ) ->map( $getStringId ) ->each( $updateStatus ); } } ), func_get_args() ); } /** * @param string $str * * @return callable|string * * @phpstan-template A1 of string|curried * @phpstan-param ?A1 $str * @phpstan-return ($str is not null ? string : callable(string=):string) */ public static function decodeStringId( $str = null ) { return call_user_func_array( curryN( 1, function( $str ) { return Str::replace( Module::STRING_ID_PREFIX, '', $str ); } ), func_get_args() ); } /** * @param string $str * * @return callable|bool * * @phpstan-template A1 of string|curried * @phpstan-param ?A1 $str * @phpstan-return ($str is not null ? bool : callable(string=):bool) */ public static function isBatchId( $str = null ) { return call_user_func_array( curryN( 1, function( $str ) { return Str::startsWith( Module::STRING_ID_PREFIX, $str ); } ), func_get_args() ); } /** * @param string $field * * @return callable|bool * * @phpstan-template A1 of string|curried * @phpstan-param ?A1 $field * @phpstan-return ($field is not null ? bool : callable(string):bool) */ public static function isBatchField( $field = null ) { return call_user_func_array( curryN( 1, function( $field ) { return self::isBatchId( Obj::prop( 'field_type', $field ) ); } ), func_get_args() ); } } StringTranslations::init();
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.24 | Генерация страницы: 0.01 |
proxy
|
phpinfo
|
Настройка