all[ $domain ][ $locale ] ?? $this->get_path_from_lang_dir( $domain, $locale ); return apply_filters( 'lang_dir_for_domain', $path, $domain, $locale ); } public function has( $domain ) { return ( isset( $this->current[ $domain ] ) || empty( $this->all[ $domain ] ) || in_array( $domain, $this->domains_with_translations, true ) ); } public function set( $domain, $locale, $path ) { $this->all[ $domain ][ $locale ] = $path ? rtrim( $path, '/' ) . '/' : false; $this->current[ $domain ] = $this->all[ $domain ][ $locale ]; } public function set_custom_path( $domain, $path ) { // If just-in-time loading was triggered before, reset the entry so it can be tried again. if ( isset( $this->all[ $domain ] ) ) { $this->all[ $domain ] = array_filter( $this->all[ $domain ] ); } if ( empty( $this->current[ $domain ] ) ) { unset( $this->current[ $domain ] ); } $this->custom_paths[ $domain ] = rtrim( $path, '/' ); } public function get_language_files_from_path( $path ) { $path = rtrim( $path, '/' ) . '/'; $files = apply_filters( 'pre_get_language_files_from_path', null, $path ); if ( null !== $files ) { return $files; } $cache_key = md5( $path ); $files = wp_cache_get( $cache_key, 'translation_files' ); if ( false === $files ) { $files = glob( $path . '*.mo' ); if ( false === $files ) { $files = array(); } $php_files = glob( $path . '*.l10n.php' ); if ( is_array( $php_files ) ) { $files = array_merge( $files, $php_files ); } wp_cache_set( $cache_key, $files, 'translation_files', HOUR_IN_SECONDS ); } return $files; } public function invalidate_mo_files_cache( $upgrader, $hook_extra ) { if ( ! isset( $hook_extra['type'] ) || 'translation' !== $hook_extra['type'] || array() === $hook_extra['translations'] ) { return; } $translation_types = array_unique( wp_list_pluck( $hook_extra['translations'], 'type' ) ); foreach ( $translation_types as $type ) { switch ( $type ) { case 'plugin': wp_cache_delete( md5( WP_LANG_DIR . '/plugins/' ), 'translation_files' ); break; case 'theme': wp_cache_delete( md5( WP_LANG_DIR . '/themes/' ), 'translation_files' ); break; default: wp_cache_delete( md5( WP_LANG_DIR . '/' ), 'translation_files' ); break; } } } private function get_paths_for_domain( $domain ) { $locations = array( WP_LANG_DIR . '/plugins', WP_LANG_DIR . '/themes', ); if ( isset( $this->custom_paths[ $domain ] ) ) { $locations[] = $this->custom_paths[ $domain ]; } return $locations; } private function get_path_from_lang_dir( $domain, $locale ) { $locations = $this->get_paths_for_domain( $domain ); $found_location = false; foreach ( $locations as $location ) { $files = $this->get_language_files_from_path( $location ); $mo_path = "$location/$domain-$locale.mo"; $php_path = "$location/$domain-$locale.l10n.php"; foreach ( $files as $file_path ) { if ( ! in_array( $domain, $this->domains_with_translations, true ) && str_starts_with( str_replace( "$location/", '', $file_path ), "$domain-" ) ) { $this->domains_with_translations[] = $domain; } if ( $file_path === $mo_path || $file_path === $php_path ) { $found_location = rtrim( $location, '/' ) . '/'; break 2; } } } if ( $found_location ) { $this->set( $domain, $locale, $found_location ); return $found_location; } /* * If no path is found for the given locale and a custom path has been set * using load_plugin_textdomain/load_theme_textdomain, use that one. */ if ( isset( $this->custom_paths[ $domain ] ) ) { $fallback_location = rtrim( $this->custom_paths[ $domain ], '/' ) . '/'; $this->set( $domain, $locale, $fallback_location ); return $fallback_location; } $this->set( $domain, $locale, false ); return false; } }