File: /var/www/delta/wp-content/plugins/wpml-string-translation/classes/MO/Hooks/CustomTextDomains.php
<?php
namespace WPML\ST\MO\Hooks;
use WPML\FP\Lst;
use WPML\ST\MO\File\Manager;
use WPML\ST\MO\JustInTime\MO;
use WPML\ST\MO\LoadedMODictionary;
use WPML\ST\Storage\StoragePerLanguageInterface;
use WPML\ST\TranslationFile\Domains;
use function WPML\FP\pipe;
use function WPML\FP\spreadArgs;
use WPML_Locale;
class CustomTextDomains implements \IWPML_Action {
const CACHE_ID = 'wpml-st-custom-mo-files';
const CACHE_ALL_LOCALES = 'locales';
const CACHE_KEY_DOMAINS = 'domains';
const CACHE_KEY_FILES = 'files';
/** @var Manager $manager */
private $manager;
/** @var Domains $domains */
private $domains;
/** @var LoadedMODictionary $loadedDictionary */
private $loadedDictionary;
/** @var StoragePerLanguageInterface */
private $cache;
/** @var WPML_Locale */
private $locale;
/** @var callable */
private $syncMissingFile;
/** @var string[] $loaded_custom_domains */
private $loaded_custom_domains = [];
public function __construct(
Manager $file_manager,
Domains $domains,
LoadedMODictionary $loadedDictionary,
StoragePerLanguageInterface $cache,
WPML_Locale $locale,
callable $syncMissingFile = null
) {
$this->manager = $file_manager;
$this->domains = $domains;
$this->loadedDictionary = $loadedDictionary;
$this->cache = $cache;
$this->locale = $locale;
$this->syncMissingFile = $syncMissingFile ?: function () {};
// Flush cache when a custom MO file is written, removed or updated.
add_action( 'wpml_st_translation_file_written', [ $this, 'clear_cache' ], 10, 0 );
add_action( 'wpml_st_translation_file_removed', [ $this, 'clear_cache' ], 10, 0 );
// The filename could be changed on update, that's why we need to clear the cache.
add_action( 'wpml_st_translation_file_updated', [ $this, 'clear_cache' ], 10, 0 );
}
public function clear_cache() {
$locales = $this->cache->get( self::CACHE_ALL_LOCALES );
if ( ! is_array( $locales ) ) {
// No cache.
return;
}
// Clear cache for all locales, because the domains list will change
// for all languages when a the first custom translation file is written
// for a new domain (even if the other locales don't get that file).
foreach ( $locales as $locale ) {
$this->cache->delete( $locale );
}
// Also flush the list of cached locales.
$this->cache->delete( self::CACHE_ALL_LOCALES );
}
public function add_hooks() {
$this->init_custom_text_domains();
}
public function init_custom_text_domains( $locale = null ) {
$locale = $locale ?: determine_locale();
$addJitMoToL10nGlobal = pipe( Lst::nth( 0 ), function ( $domain ) use ( $locale ) {
// Following unset is important because WordPress is setting their
// static $noop_translation variable by reference. Without unset it
// would become our JustInTime/MO and is used for other domains.
// @see wpmldev-2508
unset( $GLOBALS['l10n'][ $domain ] );
$this->loaded_custom_domains[] = $domain;
$GLOBALS['l10n'][ $domain ] = new MO( $this->loadedDictionary, $locale, $domain );
} );
$getDomainPathTuple = function ( $domain ) use ( $locale ) {
return [ $domain, $this->manager->getFilepath( $domain, $locale ) ];
};
$cache = $this->cache->get( $locale );
// Get domains.
if ( isset( $cache[ self::CACHE_KEY_DOMAINS ] ) ) {
// Cache hit.
$domains = \wpml_collect( $cache[ self::CACHE_KEY_DOMAINS ] );
} else {
// No cache for site domains.
$cache_update_required = true;
$domains = \wpml_collect( $this->domains->getCustomMODomains() );
}
$files = $domains->map( $getDomainPathTuple )
->each( spreadArgs( $this->syncMissingFile ) )
->each( spreadArgs( [ $this->loadedDictionary, 'addFile' ] ) );
// Load local files.
if ( isset( $cache[ self::CACHE_KEY_FILES ] ) ) {
// Cache hit.
$localeFiles = \wpml_collect( $cache[ self::CACHE_KEY_FILES ] );
} else {
// No cache for this locale readable custom .mo files.
$cache_update_required = true;
$isReadableFile = function ( $domainAndFilePath ) {
return is_readable( $domainAndFilePath[1] );
};
$localeFiles = $files->filter( $isReadableFile );
}
if ( isset( $cache_update_required ) ) {
$this->cache->save(
$locale,
[
self::CACHE_KEY_DOMAINS => $domains->toArray(),
self::CACHE_KEY_FILES => $localeFiles->toArray(),
]
);
$cache_locales = $this->cache->get( self::CACHE_ALL_LOCALES );
$cache_locales = is_array( $cache_locales ) ? $cache_locales : [];
if ( ! in_array( $locale, $cache_locales, true ) ) {
$cache_locales[] = $locale;
$this->cache->save(
self::CACHE_ALL_LOCALES,
array_unique( $cache_locales )
);
}
}
$localeFiles->each( $addJitMoToL10nGlobal );
}
}