tiveFunctions.file_system_read_file_put_contents } } } } } return $file; } /** * Creates PHP translation files after the translation updates process. * * @global WP_Filesystem_Base $wp_filesystem WP filesystem subclass. * * @param WP_Upgrader $upgrader WP_Upgrader instance. In other contexts this might be a * Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance. * @param array $hook_extra { * Array of bulk item update data. * * @type string $action Type of action. Default 'update'. * @type string $type Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'. * @type bool $bulk Whether the update process is a bulk update. Default true. * @type array $plugins Array of the basename paths of the plugins' main files. * @type array $themes The theme slugs. * @type array $translations { * Array of translations update data. * * @type string $language The locale the translation is for. * @type string $type Type of translation. Accepts 'plugin', 'theme', or 'core'. * @type string $slug Text domain the translation is for. The slug of a theme/plugin or * 'default' for core translations. * @type string $version The version of a theme, plugin, or core. * } * } * @return void * * @phpstan-param array{action: string, type: string, bulk: bool, plugins: string[], themes: string[], translations: array} $hook_extra */ public static function upgrader_process_complete( $upgrader, $hook_extra ) { /** * WP filesystem subclass. * * @var WP_Filesystem_Base $wp_filesystem WP filesystem subclass. */ global $wp_filesystem; if ( 'translation' !== $hook_extra['type'] || array() === $hook_extra['translations'] ) { return; } foreach ( $hook_extra['translations'] as $translation ) { $files = array(); switch ( $translation['type'] ) { case 'plugin': $files[] = WP_LANG_DIR . '/plugins/' . $translation['slug'] . '-' . $translation['language'] . '.mo'; break; case 'theme': $files[] = WP_LANG_DIR . '/themes/' . $translation['slug'] . '-' . $translation['language'] . '.mo'; break; default: $files[] = WP_LANG_DIR . '/' . $translation['language'] . '.mo'; $files[] = WP_LANG_DIR . '/admin-' . $translation['language'] . '.mo'; $files[] = WP_LANG_DIR . '/admin-network-' . $translation['language'] . '.mo'; $files[] = WP_LANG_DIR . '/continents-cities-' . $translation['language'] . '.mo'; break; } foreach ( $files as $file ) { if ( file_exists( $file ) ) { /** This filter is documented in lib/class-performant-translations.php */ $preferred_format = apply_filters( 'performant_translations_preferred_format', 'php' ); if ( ! in_array( $preferred_format, array( 'php', 'mo' ), true ) ) { $preferred_format = 'php'; } /** This filter is documented in wp-includes/l10n.php */ $preferred_format = apply_filters( 'translation_file_format', $preferred_format, $translation['slug'] ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound $mofile_preferred = $file; if ( 'mo' !== $preferred_format ) { $mofile_preferred = substr_replace( $file, ".l10n.$preferred_format", -strlen( '.mo' ) ); } /** This filter is documented in lib/class-performant-translations.php */ $convert = apply_filters( 'performant_translations_convert_files', true ); if ( 'mo' !== $preferred_format && $convert ) { $contents = WP_Translation_File::transform( $file, $preferred_format ); if ( false === $contents ) { return; } if ( true === $upgrader->fs_connect( array( dirname( $file ) ) ) ) { $file_written = $wp_filesystem->put_contents( $mofile_preferred, $contents, FS_CHMOD_FILE ); } else { $file_written = (bool) file_put_contents( $mofile_preferred, $contents, LOCK_EX ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents } if ( $file_written ) { /** This action is documented in lib/class-performant-translations.php */ do_action( 'performant_translations_file_written', $mofile_preferred ); } } } } } } /** * Adds a generator tag for the plugin. * * @codeCoverageIgnore * * @return void */ public static function add_generator_tag() { echo '' . "\n"; } /** * Regenerates a PHP translation file from a given MO file. * * Useful for plugins such as Loco Translate or WPML which generate custom MO files. * Prevents stale PHP files in those cases. * * This compatibility code is added out of courtesy and is not intended * to be merged into WordPress core. * * @codeCoverageIgnore * * @global WP_Filesystem_Base $wp_filesystem WP filesystem subclass. * * @param string $file Path to translation file. * @return void */ public static function regenerate_translation_file( string $file ) { /** * WP filesystem subclass. * * @var WP_Filesystem_Base $wp_filesystem WP filesystem subclass. */ global $wp_filesystem; if ( ! str_ends_with( $file, '.mo' ) ) { return; } /** This filter is documented in lib/class-performant-translations.php */ $preferred_format = apply_filters( 'performant_translations_preferred_format', 'php' ); if ( ! in_array( $preferred_format, array( 'php', 'mo' ), true ) ) { $preferred_format = 'php'; } $mofile_preferred = $file; if ( 'mo' !== $preferred_format ) { $mofile_preferred = substr_replace( $file, ".l10n.$preferred_format", -strlen( '.mo' ) ); } /** This filter is documented in lib/class-performant-translations.php */ $convert = apply_filters( 'performant_translations_convert_files', true ); if ( 'mo' !== $preferred_format && $convert ) { $contents = WP_Translation_File::transform( $file, $preferred_format ); if ( false !== $contents ) { if ( ! function_exists( 'WP_Filesystem' ) ) { require_once ABSPATH . '/wp-admin/includes/file.php'; } if ( true === WP_Filesystem() ) { $file_written = $wp_filesystem->put_contents( $mofile_preferred, $contents, FS_CHMOD_FILE ); } else { $file_written = (bool) file_put_contents( $mofile_preferred, $contents, LOCK_EX ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents } if ( $file_written ) { /** This action is documented in lib/class-performant-translations.php */ do_action( 'performant_translations_file_written', $mofile_preferred ); } } } } }