Файловый менеджер - Редактировать - /var/www/xthruster/html/wp-content/uploads/flags/translation-files.tar
Назад
Sync/TranslationUpdates.php 0000644 00000002667 14721540272 0012034 0 ustar 00 <?php namespace WPML\ST\TranslationFile\Sync; use WPML\Collect\Support\Collection; class TranslationUpdates { // The global constant is not defined yet. const ICL_STRING_TRANSLATION_COMPLETE = 10; /** @var \wpdb */ private $wpdb; /** @var \WPML_Language_Records */ private $languageRecords; /** @var null|Collection */ private $data; public function __construct( \wpdb $wpdb, \WPML_Language_Records $languageRecords ) { $this->wpdb = $wpdb; $this->languageRecords = $languageRecords; } /** * @param string $domain * @param string $locale * * @return int */ public function getTimestamp( $domain, $locale ) { $this->loadData(); $lang = $this->languageRecords->get_language_code( $locale ); return (int) $this->data->get( "$lang#$domain" ); } private function loadData() { if ( ! $this->data ) { $sql = " SELECT CONCAT(st.language,'#',s.context) AS lang_domain, UNIX_TIMESTAMP(MAX(st.translation_date)) as last_update FROM {$this->wpdb->prefix}icl_string_translations AS st INNER JOIN {$this->wpdb->prefix}icl_strings AS s ON st.string_id = s.id WHERE st.value IS NOT NULL AND st.status = %d GROUP BY s.context, st.language; "; $this->data = wpml_collect( $this->wpdb->get_results( $this->wpdb->prepare( $sql, self::ICL_STRING_TRANSLATION_COMPLETE ) ) )->pluck( 'last_update', 'lang_domain' ); } } public function reset() { $this->data = null; } } Sync/FileSync.php 0000644 00000004037 14721540272 0007715 0 ustar 00 <?php namespace WPML\ST\TranslationFile\Sync; use WPML\ST\TranslationFile\Manager; use WPML_ST_Translations_File_Locale; class FileSync { /** @var Manager */ private $manager; /** @var TranslationUpdates */ private $translationUpdates; /** @var WPML_ST_Translations_File_Locale */ private $fileLocale; public function __construct( Manager $manager, TranslationUpdates $translationUpdates, WPML_ST_Translations_File_Locale $FileLocale ) { $this->manager = $manager; $this->translationUpdates = $translationUpdates; $this->fileLocale = $FileLocale; } /** * Before to load the custom translation file, we'll: * - Re-generate it if it's missing or outdated. * - Delete it if we don't have custom translations. * * We will also sync the custom file when a native file is passed * because the custom file might never be loaded if it's missing. * * @param string|false $filePath * @param string $domain */ public function sync( $filePath, $domain ) { if ( ! $filePath ) { return; } $locale = $this->fileLocale->get( $filePath, $domain ); $filePath = $this->getCustomFilePath( $filePath, $domain, $locale ); $lastDbUpdate = $this->translationUpdates->getTimestamp( $domain, $locale ); $fileTimestamp = file_exists( $filePath ) ? filemtime( $filePath ) : 0; if ( 0 === $lastDbUpdate ) { if ( $fileTimestamp ) { $this->manager->remove( $domain, $locale ); } } elseif ( $fileTimestamp < $lastDbUpdate ) { $this->manager->add( $domain, $locale ); } } /** * @param string $filePath * @param string $domain * @param string $locale * * @return string|null */ private function getCustomFilePath( $filePath, $domain, $locale ) { if ( self::isWpmlCustomFile( $filePath ) ) { return $filePath; } return $this->manager->getFilepath( $domain, $locale ); } /** * @param string $file * * @return bool */ private static function isWpmlCustomFile( $file ) { return 0 === strpos( $file, WP_LANG_DIR . '/' . Manager::SUB_DIRECTORY ); } } DomainsLocalesMapper.php 0000644 00000004463 14721540272 0011332 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use wpdb; use WPML\Collect\Support\Collection; use WPML\FP\Fns; use WPML\FP\Lst; use WPML\FP\Obj; use WPML_Locale; class DomainsLocalesMapper { const ALIAS_STRINGS = 's'; const ALIAS_STRING_TRANSLATIONS = 'st'; /** @var wpdb $wpdb */ private $wpdb; /** @var WPML_Locale $locale */ private $locale; public function __construct( wpdb $wpdb, WPML_Locale $locale ) { $this->wpdb = $wpdb; $this->locale = $locale; } /** * @param array $string_translation_ids * * @return Collection of objects with properties `domain` and `locale` */ public function get_from_translation_ids( array $string_translation_ids ) { return $this->get_results_where( self::ALIAS_STRING_TRANSLATIONS, $string_translation_ids ); } /** * @param array $string_ids * * @return Collection of objects with properties `domain` and `locale` */ public function get_from_string_ids( array $string_ids ) { return $this->get_results_where( self::ALIAS_STRINGS, $string_ids ); } /** * @param callable $getActiveLanguages * @param string $domain * * @return array */ public function get_from_domain( callable $getActiveLanguages, $domain ) { $createEntity = function ( $locale ) use ( $domain ) { return (object) [ 'domain' => $domain, 'locale' => $locale, ]; }; /** @var array $defaultLocaleList */ $defaultLocaleList = Lst::pluck( 'default_locale', $getActiveLanguages() ); return Fns::map( $createEntity, Obj::values( $defaultLocaleList ) ); } /** * @param string $table_alias * @param array $ids * * @return Collection */ private function get_results_where( $table_alias, array $ids ) { $results = []; if ( array_filter( $ids ) ) { $results = $this->wpdb->get_results( " SELECT DISTINCT s.context AS domain, st.language FROM {$this->wpdb->prefix}icl_string_translations AS " . self::ALIAS_STRING_TRANSLATIONS . " JOIN {$this->wpdb->prefix}icl_strings AS " . self::ALIAS_STRINGS . " ON s.id = st.string_id WHERE $table_alias.id IN(" . wpml_prepare_in( $ids ) . ') ' ); } return wpml_collect( $results )->map( function( $row ) { return (object) [ 'domain' => $row->domain, 'locale' => $this->locale->get_locale( $row->language ), ]; } ); } } Hooks.php 0000644 00000002341 14721540272 0006344 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use WPML\ST\MO\Hooks\Factory; use WPML\ST\MO\Plural; use WPML_Action_Filter_Loader; use WPML_Package_Translation_Schema; use WPML_ST_Upgrade; use WPML_ST_Upgrade_MO_Scanning; class Hooks { /** @var WPML_Action_Filter_Loader $action_loader */ private $action_loader; /** @var WPML_ST_Upgrade $upgrade */ private $upgrade; public function __construct( WPML_Action_Filter_Loader $action_loader, WPML_ST_Upgrade $upgrade ) { $this->action_loader = $action_loader; $this->upgrade = $upgrade; } public function install() { if ( $this->hasPackagesTable() && $this->hasTranslationFilesTables() ) { $this->action_loader->load( [ Factory::class, Plural::class ] ); } } private function hasPackagesTable() { $updates_run = get_option( WPML_Package_Translation_Schema::OPTION_NAME, [] ); return in_array( WPML_Package_Translation_Schema::REQUIRED_VERSION, $updates_run, true ); } private function hasTranslationFilesTables() { return $this->upgrade->has_command_been_executed( WPML_ST_Upgrade_MO_Scanning::class ); } public static function useFileSynchronization() { return defined( 'WPML_ST_SYNC_TRANSLATION_FILES' ) && constant( 'WPML_ST_SYNC_TRANSLATION_FILES' ); } } UpdateHooks.php 0000644 00000013142 14721540272 0007510 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use stdClass; use WPML\Collect\Support\Collection; use WPML\Element\API\Languages; class UpdateHooks implements \IWPML_Action { /** @var Manager $file_manager */ private $file_manager; /** @var DomainsLocalesMapper $domains_locales_mapper */ private $domains_locales_mapper; /** @var array $updated_translation_ids */ private $updated_translation_ids = []; /** @var Collection $entities_to_update */ private $entities_to_update; /** @var callable */ private $resetDomainsCache; public function __construct( Manager $file_manager, DomainsLocalesMapper $domains_locales_mapper, callable $resetDomainsCache = null ) { $this->file_manager = $file_manager; $this->domains_locales_mapper = $domains_locales_mapper; $this->entities_to_update = wpml_collect( [] ); $this->resetDomainsCache = $resetDomainsCache ?: [ Domains::class, 'resetCache' ]; } public function add_hooks() { add_action( 'wpml_st_strings_table_altered', [ Domains::class, 'invalidateMODomainCache' ] ); add_action( 'wpml_st_string_registered', [ Domains::class, 'invalidateMODomainCache' ] ); add_action( 'wpml_st_string_unregistered', [ Domains::class, 'invalidateMODomainCache' ] ); add_action( 'wpml_st_string_updated', [ Domains::class, 'invalidateMODomainCache' ] ); add_action( 'wpml_st_add_string_translation', array( $this, 'add_to_update_queue' ) ); add_action( 'wpml_st_update_string', array( $this, 'refresh_after_update_original_string' ), 10, 6 ); add_action( 'wpml_st_before_remove_strings', array( $this, 'refresh_before_remove_strings' ) ); add_action( 'wpml_st_translation_files_process_queue', [ $this, 'process_update_queue_action' ] ); /** * @see UpdateHooks::refresh_domain * @since @3.1.0 */ add_action( 'wpml_st_refresh_domain', [ $this, 'refresh_domain' ] ); if ( ! $this->file_manager->isPartialFile() ) { add_action( 'wpml_st_translations_file_post_import', array( $this, 'update_imported_file' ) ); } } /** @param int $string_translation_id */ public function add_to_update_queue( $string_translation_id ) { if ( ! in_array( $string_translation_id, $this->updated_translation_ids, true ) ) { $this->updated_translation_ids[] = $string_translation_id; $this->add_shutdown_action(); } } private function add_shutdown_action() { if ( ! has_action( 'shutdown', array( $this, 'process_update_queue_action' ) ) ) { add_action( 'shutdown', array( $this, 'process_update_queue_action' ) ); } } public function process_update_queue_action() { remove_action( 'shutdown', array( $this, 'process_update_queue_action' ) ); $this->process_update_queue(); } /** * @return array */ public function process_update_queue() { call_user_func( $this->resetDomainsCache ); $outdated_entities = $this->domains_locales_mapper->get_from_translation_ids( $this->updated_translation_ids ); $this->entities_to_update = $this->entities_to_update->merge( $outdated_entities ); $this->entities_to_update->each( function ( $entity ) { $updatedFilename = $this->update_file( $entity->domain, $entity->locale ); do_action( 'wpml_st_translation_file_updated', $updatedFilename, $entity->domain, $entity->locale ); } ); return $this->entities_to_update->toArray(); } /** * @param string $domain * @param string $name * @param string $old_value * @param string $new_value * @param bool|false $force_complete * @param stdClass $string */ public function refresh_after_update_original_string( $domain, $name, $old_value, $new_value, $force_complete, $string ) { $outdated_entities = $this->domains_locales_mapper->get_from_string_ids( [ $string->id ] ); $this->entities_to_update = $this->entities_to_update->merge( $outdated_entities ); $this->add_shutdown_action(); } public function update_imported_file( \WPML_ST_Translations_File_Entry $file_entry ) { if ( $file_entry->get_status() === \WPML_ST_Translations_File_Entry::IMPORTED ) { $updatedFilename = $this->update_file( $file_entry->get_domain(), $file_entry->get_file_locale() ); if ( $updatedFilename ) { do_action( 'wpml_st_translation_file_updated', $updatedFilename, $file_entry->get_domain(), $file_entry->get_file_locale() ); } } } /** * It dispatches the regeneration of MO files for a specific domain in all active languages. * * @param string $domain */ public function refresh_domain( $domain ) { $outdated_entities = $this->domains_locales_mapper->get_from_domain( [ Languages::class, 'getActive' ], $domain ); $this->entities_to_update = $this->entities_to_update->merge( $outdated_entities ); $this->add_shutdown_action(); } /** * We need to refresh before the strings are deleted, * otherwise we can't determine which domains to refresh. * * @param array $string_ids */ public function refresh_before_remove_strings( array $string_ids ) { $outdated_entities = $this->domains_locales_mapper->get_from_string_ids( $string_ids ); $this->entities_to_update = $this->entities_to_update->merge( $outdated_entities ); $this->add_shutdown_action(); } /** * @param string $domain * @param string $locale * * @return false|string */ private function update_file( $domain, $locale ) { /** * It does not matter whether MO/JED file can be handled or not, that's why `remove` method is placed before `handles` check. * If a file is not `handable` then it can still should be removed. */ $this->file_manager->remove( $domain, $locale ); if ( $this->file_manager->handles( $domain ) ) { return $this->file_manager->add( $domain, $locale ); } return false; } } StringEntity.php 0000644 00000002621 14721540272 0007725 0 ustar 00 <?php namespace WPML\ST\TranslationFile; class StringEntity { /** @var string $original */ private $original; /** @var array $translations */ private $translations = array(); /** @var null|string $context */ private $context; /** @var string|null */ private $original_plural; /** @var string|null */ private $name; /** * @param string $original * @param array $translations * @param null|string $context * @param null|string $original_plural * @param null|string $name */ public function __construct( $original, array $translations, $context = null, $original_plural = null, $name = null ) { $this->original = $original; $this->translations = $translations; $this->context = $context ? $context : null; $this->original_plural = $original_plural; $this->name = $name; } /** @return string */ public function get_original() { return $this->original; } /** @return array */ public function get_translations() { return $this->translations; } /** @return null|string */ public function get_context() { return $this->context; } /** * @return string|null */ public function get_original_plural() { return $this->original_plural; } /** * @return string|null */ public function get_name() { return $this->name; } /** * @param string $name */ public function set_name( $name ) { $this->name = $name; } } Manager.php 0000644 00000007121 14721540272 0006634 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use WP_Filesystem_Direct; use WPML\Collect\Support\Collection; use WPML\ST\MO\File\makeDir; use WPML_Language_Records; use WPML_ST_Translations_File_Dictionary; use function wpml_collect; use WPML_ST_Translations_File_Entry; abstract class Manager { use makeDir; const SUB_DIRECTORY = 'wpml'; /** @var StringsRetrieve $strings */ protected $strings; /** @var WPML_Language_Records $language_records */ protected $language_records; /** @var Builder $builder */ protected $builder; /** @var WPML_ST_Translations_File_Dictionary $file_dictionary */ protected $file_dictionary; /** @var Domains $domains */ protected $domains; public function __construct( StringsRetrieve $strings, Builder $builder, WP_Filesystem_Direct $filesystem, WPML_Language_Records $language_records, Domains $domains ) { $this->strings = $strings; $this->builder = $builder; $this->filesystem = $filesystem; $this->language_records = $language_records; $this->domains = $domains; } /** * @param string $domain * @param string $locale */ public function remove( $domain, $locale ) { $filepath = $this->getFilepath( $domain, $locale ); $this->filesystem->delete( $filepath ); do_action( 'wpml_st_translation_file_removed', $filepath, $domain, $locale ); } public function write( $domain, $locale, $content ) { $filepath = $this->getFilepath( $domain, $locale ); $chmod = defined( 'FS_CHMOD_FILE' ) ? FS_CHMOD_FILE : 0644; if ( ! $this->filesystem->put_contents( $filepath, $content, $chmod ) ) { return false; } do_action( 'wpml_st_translation_file_written', $filepath, $domain, $locale ); return $filepath; } /** * Builds and saves the .MO file. * Returns false if file doesn't exist, file path otherwise. * * @param string $domain * @param string $locale * * @return false|string */ public function add( $domain, $locale ) { if ( ! $this->maybeCreateSubdir() ) { return false; } $lang_code = $this->language_records->get_language_code( $locale ); $strings = $this->strings->get( $domain, $lang_code, $this->isPartialFile() ); if ( ! $strings && $this->isPartialFile() ) { $this->remove( $domain, $locale ); return false; } $file_content = $this->builder ->set_language( $locale ) ->get_content( $strings ); return $this->write( $domain, $locale, $file_content ); } /** * @param string $domain * @param string $locale * * @return string|null */ public function get( $domain, $locale ) { $filepath = $this->getFilepath( $domain, $locale ); if ( $this->filesystem->is_file( $filepath ) && $this->filesystem->is_readable( $filepath ) ) { return $filepath; } return null; } /** * @param string $domain * @param string $locale * * @return string */ public function getFilepath( $domain, $locale ) { return $this->getSubdir() . '/' . strtolower( $domain ) . '-' . $locale . '.' . $this->getFileExtension(); } /** * @param string $domain * * @return bool */ public function handles( $domain ) { return $this->getDomains()->contains( $domain ); } /** @return string */ public static function getSubdir() { $subdir = WP_LANG_DIR . '/' . self::SUB_DIRECTORY; $site_id = get_current_blog_id(); if ( $site_id > 1 ) { $subdir .= '/' . $site_id; } return $subdir; } /** * @return string */ abstract protected function getFileExtension(); /** * @return bool */ abstract public function isPartialFile(); /** * @return Collection */ abstract protected function getDomains(); } UpdateHooksFactory.php 0000644 00000000562 14721540272 0011042 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use WPML\ST\MO\File\ManagerFactory; use function WPML\Container\make; class UpdateHooksFactory { /** @return UpdateHooks */ public static function create() { static $instance; if ( ! $instance ) { $instance = make( UpdateHooks::class, [ ':file_manager' => ManagerFactory::create() ] ); } return $instance; } } jed/wpml-st-script-translations-hooks.php 0000644 00000003714 14721540272 0014575 0 ustar 00 <?php class WPML_ST_Script_Translations_Hooks implements IWPML_Action { const PRIORITY_OVERRIDE_JED_FILE = 10; /** @var WPML_ST_Translations_File_Dictionary $dictionary */ private $dictionary; /** @var WPML_ST_JED_File_Manager $jed_file_manager */ private $jed_file_manager; /** @var WPML_File $wpml_file */ private $wpml_file; public function __construct( WPML_ST_Translations_File_Dictionary $dictionary, WPML_ST_JED_File_Manager $jed_file_manager, WPML_File $wpml_file ) { $this->dictionary = $dictionary; $this->jed_file_manager = $jed_file_manager; $this->wpml_file = $wpml_file; } public function add_hooks() { add_filter( 'load_script_translation_file', array( $this, 'override_jed_file' ), self::PRIORITY_OVERRIDE_JED_FILE, 3 ); } /** * @param string $filepath * @param string $handler * @param string $domain * * @return string */ public function override_jed_file( $filepath, $handler, $domain ) { if ( ! $filepath ) { return $filepath; } $locale = $this->get_file_locale( $filepath, $domain ); $domain = WPML_ST_JED_Domain::get( $domain, $handler ); $wpml_filepath = $this->jed_file_manager->get( $domain, $locale ); if ( $wpml_filepath ) { return $wpml_filepath; } return $filepath; } /** * @param string $filepath * * @return bool */ private function is_file_imported( $filepath ) { $relative_path = $this->wpml_file->get_relative_path( $filepath ); $file = $this->dictionary->find_file_info_by_path( $relative_path ); $statuses = array( WPML_ST_Translations_File_Entry::IMPORTED, WPML_ST_Translations_File_Entry::FINISHED ); return $file && in_array( $file->get_status(), $statuses, true ); } /** * @param string $filepath * @param string $domain * * @return string */ private function get_file_locale( $filepath, $domain ) { return \WPML\Container\make( \WPML_ST_Translations_File_Locale::class )->get( $filepath, $domain ); } } jed/wpml-st-jed-domain.php 0000644 00000000176 14721540272 0011437 0 ustar 00 <?php class WPML_ST_JED_Domain { public static function get( $domain, $handler ) { return $domain . '-' . $handler; } } jed/wpml-st-jed-file-builder.php 0000644 00000003072 14721540272 0012531 0 ustar 00 <?php use WPML\ST\TranslationFile\StringEntity; class WPML_ST_JED_File_Builder extends WPML\ST\TranslationFile\Builder { /** @var string $decoded_eot */ private $decoded_eot; public function __construct() { $this->decoded_eot = json_decode( WPML_ST_Translations_File_JED::DECODED_EOT_CHAR ); } /** * @param StringEntity[] $strings * @return string */ public function get_content( array $strings ) { $data = new stdClass(); $data->{'translation-revision-date'} = date( 'Y-m-d H:i:sO' ); $data->generator = 'WPML String Translation ' . WPML_ST_VERSION; $data->domain = 'messages'; $data->locale_data = new stdClass(); $data->locale_data->messages = new stdClass(); $data->locale_data->messages->{WPML_ST_Translations_File_JED::EMPTY_PROPERTY_NAME} = (object) array( 'domain' => 'messages', 'plural-forms' => $this->plural_form, 'lang' => $this->language, ); foreach ( $strings as $string ) { $original = $this->get_original_with_context( $string ); $data->locale_data->messages->{$original} = $string->get_translations(); } $jed_content = (string) wp_json_encode( $data ); return preg_replace( '/"' . WPML_ST_Translations_File_JED::EMPTY_PROPERTY_NAME . '"/', '""', $jed_content, 1 ); } private function get_original_with_context( StringEntity $string ) { if ( $string->get_context() ) { return $string->get_context() . $this->decoded_eot . $string->get_original(); } return $string->get_original(); } } jed/Hooks/Sync.php 0000644 00000002036 14721540272 0010023 0 ustar 00 <?php namespace WPML\ST\JED\Hooks; use WPML\ST\TranslationFile\Sync\FileSync; use WPML_ST_JED_Domain; use WPML_ST_JED_File_Manager; use WPML_ST_Script_Translations_Hooks; use WPML_ST_Translations_File_Locale; class Sync implements \IWPML_Frontend_Action, \IWPML_Backend_Action, \IWPML_DIC_Action { /** @var FileSync */ private $fileSync; public function __construct( FileSync $fileSync ) { $this->fileSync = $fileSync; } public function add_hooks() { add_filter( 'load_script_translation_file', [ $this, 'syncCustomJedFile' ], WPML_ST_Script_Translations_Hooks::PRIORITY_OVERRIDE_JED_FILE - 1, 3 ); } /** * @param string|false $jedFile Path to the translation file to load. False if there isn't one. * @param string $handler Name of the script to register a translation domain to. * @param string $domain The text domain. */ public function syncCustomJedFile( $jedFile, $handler, $domain ) { $this->fileSync->sync( $jedFile, WPML_ST_JED_Domain::get( $domain, $handler ) ); return $jedFile; } } jed/wpml-st-jed-file-manager.php 0000644 00000000644 14721540272 0012517 0 ustar 00 <?php use WPML\Collect\Support\Collection; use WPML\ST\TranslationFile\Manager; class WPML_ST_JED_File_Manager extends Manager { /** * @return string */ protected function getFileExtension() { return 'json'; } /** * @return bool */ public function isPartialFile() { return false; } /** * @return Collection */ protected function getDomains() { return $this->domains->getJEDDomains(); } } jed/wpml-st-script-translations-hooks-factory.php 0000644 00000003065 14721540272 0016241 0 ustar 00 <?php use WPML\ST\JED\Hooks\Sync; use WPML\ST\TranslationFile\Sync\FileSync; use function WPML\Container\make; use WPML\ST\TranslationFile\UpdateHooks; class WPML_ST_Script_Translations_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_Frontend_Action_Loader { /** * Create hooks. * * @return array|IWPML_Action * @throws \WPML\Auryn\InjectionException Auryn Exception. */ public function create() { $hooks = array(); $jed_file_manager = make( WPML_ST_JED_File_Manager::class, [ ':builder' => make( WPML_ST_JED_File_Builder::class ) ] ); $hooks['update'] = $this->get_update_hooks( $jed_file_manager ); if ( ! wpml_is_ajax() && ! wpml_is_rest_request() ) { $hooks['filtering'] = $this->get_filtering_hooks( $jed_file_manager ); } if ( WPML\ST\TranslationFile\Hooks::useFileSynchronization() ) { $hooks['sync'] = make( Sync::class, [ ':fileSync' => make( FileSync::class, [ ':manager' => $jed_file_manager ] ), ':manager' => $jed_file_manager, ] ); } return $hooks; } /** * @param WPML_ST_JED_File_Manager $jed_file_manager * * @return UpdateHooks */ private function get_update_hooks( $jed_file_manager ) { return make( UpdateHooks::class, [ ':file_manager' => $jed_file_manager ] ); } /** * @param WPML_ST_JED_File_Manager $jed_file_manager * * @return WPML_ST_Script_Translations_Hooks */ private function get_filtering_hooks( $jed_file_manager ) { return make( WPML_ST_Script_Translations_Hooks::class, [ ':jed_file_manager' => $jed_file_manager ] ); } } Domains.php 0000644 00000010726 14721540272 0006661 0 ustar 00 <?php namespace WPML\ST\TranslationFile; use wpdb; use WPML\Collect\Support\Collection; use WPML\FP\Fns; use WPML\FP\Just; use WPML\FP\Maybe; use WPML\FP\Nothing; use WPML\LIB\WP\Cache; use WPML\ST\Package\Domains as PackageDomains; use WPML_Admin_Texts; use WPML_ST_Blog_Name_And_Description_Hooks; use WPML_ST_Translations_File_Dictionary; use WPML\ST\Shortcode; class Domains { const MO_DOMAINS_CACHE_GROUP = 'WPML_ST_CACHE'; const MO_DOMAINS_CACHE_KEY = 'wpml_string_translation_has_mo_domains'; /** @var wpdb $wpdb */ private $wpdb; /** @var PackageDomains $package_domains */ private $package_domains; /** @var WPML_ST_Translations_File_Dictionary $file_dictionary */ private $file_dictionary; /** @var null|Collection $jed_domains */ private static $jed_domains; /** * Domains constructor. * * @param PackageDomains $package_domains * @param WPML_ST_Translations_File_Dictionary $file_dictionary */ public function __construct( wpdb $wpdb, PackageDomains $package_domains, WPML_ST_Translations_File_Dictionary $file_dictionary ) { $this->wpdb = $wpdb; $this->package_domains = $package_domains; $this->file_dictionary = $file_dictionary; } /** * @return Collection */ public function getMODomains() { $getMODomainsFromDB = function () { $cacheLifeTime = HOUR_IN_SECONDS; $excluded_domains = self::getReservedDomains()->merge( $this->getJEDDomains() ); $sql = " SELECT DISTINCT context {$this->getCollateForContextColumn()} FROM {$this->wpdb->prefix}icl_strings "; $mo_domains = wpml_collect( $this->wpdb->get_col( $sql ) ) ->diff( $excluded_domains ) ->values(); if ( $mo_domains->count() <= 0 ) { // if we don't get any data from DB, we set cache expire time to be 15 minutes so that cache refreshes in lesser time. $cacheLifeTime = 15 * MINUTE_IN_SECONDS; } Cache::set( self::MO_DOMAINS_CACHE_GROUP, self::MO_DOMAINS_CACHE_KEY, $cacheLifeTime, $mo_domains ); return $mo_domains; }; /** @var Just|Nothing $cacheItem */ $cacheItem = Cache::get( self::MO_DOMAINS_CACHE_GROUP, self::MO_DOMAINS_CACHE_KEY ); return $cacheItem->getOrElse( $getMODomainsFromDB ); } public static function invalidateMODomainCache() { static $invalidationScheduled = false; if ( ! $invalidationScheduled ) { $invalidationScheduled = true; add_action( 'shutdown', function () { Cache::flushGroup( self::MO_DOMAINS_CACHE_GROUP ); } ); } } /** * @return string */ private function getCollateForContextColumn() { $sql = " SELECT COLLATION_NAME FROM information_schema.columns WHERE TABLE_SCHEMA = '" . DB_NAME . "' AND TABLE_NAME = '{$this->wpdb->prefix}icl_strings' AND COLUMN_NAME = 'context' "; $collation = $this->wpdb->get_var( $sql ); if ( ! $collation ) { return ''; } list( $type ) = explode( '_', $collation ); if ( in_array( $type, [ 'utf8', 'utf8mb4' ] ) ) { return 'COLLATE ' . $type . '_bin'; } return ''; } /** * Returns a collection of MO domains that * WPML needs to automatically load. * * @return Collection */ public function getCustomMODomains() { $all_mo_domains = $this->getMODomains(); $native_mo_domains = $this->file_dictionary->get_domains( 'mo', get_locale() ); return $all_mo_domains->reject( function ( $domain ) use ( $native_mo_domains ) { /** * Admin texts, packages, string shortcodes are handled separately, * so they are loaded on-demand. */ return null === $domain || 0 === strpos( $domain, WPML_Admin_Texts::DOMAIN_NAME_PREFIX ) || $this->package_domains->isPackage( $domain ) || Shortcode::STRING_DOMAIN === $domain || in_array( $domain, $native_mo_domains, true ); } )->values(); } /** * @return Collection */ public function getJEDDomains() { if ( ! self::$jed_domains instanceof Collection ) { self::$jed_domains = wpml_collect( $this->file_dictionary->get_domains( 'json' ) ); } return self::$jed_domains; } public static function resetCache() { self::invalidateMODomainCache(); self::$jed_domains = null; } /** * Domains that are not handled with MO files, * but have direct DB queries. * * @return Collection */ public static function getReservedDomains() { return wpml_collect( [ WPML_ST_Blog_Name_And_Description_Hooks::STRING_DOMAIN, ] ); } /** * @return Collection */ private function getPackageDomains() { return $this->package_domains->getDomains(); } } StringsRetrieve.php 0000644 00000007732 14721540272 0010431 0 ustar 00 <?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; } } Builder.php 0000644 00000001232 14721540272 0006645 0 ustar 00 <?php namespace WPML\ST\TranslationFile; abstract class Builder { /** @var string $plural_form */ protected $plural_form = 'nplurals=2; plural=n != 1;'; /** @var string $language */ protected $language; /** * @param string $language * * @return Builder */ public function set_language( $language ) { $this->language = $language; return $this; } /** * @param string $plural_form * * @return Builder */ public function set_plural_form( $plural_form ) { $this->plural_form = $plural_form; return $this; } /** * @param StringEntity[] $strings * @return string */ abstract public function get_content( array $strings); }
| ver. 1.4 |
Github
|
.
| PHP 7.4.3-4ubuntu2.24 | Генерация страницы: 0.03 |
proxy
|
phpinfo
|
Настройка