-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Bug Report
- Yes, I reviewed the contribution guidelines.
- Yes, more specifically, I reviewed the guidelines on how to write clear bug reports.
Describe the current, buggy behavior
When listing available languages for a plugin using the wp language plugin list <plugin> command, the status is always uninstalled if the plugin's slug ≠ plugin's text domain.
This is due to the wp_get_installed_translations() method used in
language-command/src/WP_CLI/CommandWithTranslation.php
Lines 251 to 257 in 24f76e3
| protected function get_installed_languages( $slug = 'default' ) { | |
| $available = wp_get_installed_translations( $this->obj_type ); | |
| $available = ! empty( $available[ $slug ] ) ? array_keys( $available[ $slug ] ) : array(); | |
| $available[] = 'en_US'; | |
| return $available; | |
| } |
wp_get_installed_translations() returns an array keyed by the text domain. As a result, the subsequent check for available languages ($available = ! empty( $available[ $slug ] ) ? array_keys( $available[ $slug ] ) : array();) results in an empty array if the plugin's slug is different from its text domain.
get_installed_languages() is used by the list command:
language-command/src/Plugin_Language_Command.php
Lines 92 to 153 in 24f76e3
| public function list_( $args, $assoc_args ) { | |
| $all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false ); | |
| if ( ! $all && empty( $args ) ) { | |
| WP_CLI::error( 'Please specify one or more plugins, or use --all.' ); | |
| } | |
| if ( $all ) { | |
| $args = array_map( '\WP_CLI\Utils\get_plugin_name', array_keys( $this->get_all_plugins() ) ); | |
| if ( empty( $args ) ) { | |
| WP_CLI::success( 'No plugins installed.' ); | |
| return; | |
| } | |
| } | |
| $updates = $this->get_translation_updates(); | |
| $current_locale = get_locale(); | |
| $translations = array(); | |
| $plugins = new \WP_CLI\Fetchers\Plugin(); | |
| foreach ( $args as $plugin ) { | |
| if ( ! $plugins->get( $plugin ) ) { | |
| WP_CLI::warning( "Plugin '{$plugin}' not found." ); | |
| continue; | |
| } | |
| $installed_translations = $this->get_installed_languages( $plugin ); | |
| $available_translations = $this->get_all_languages( $plugin ); | |
| foreach ( $available_translations as $translation ) { | |
| $translation['plugin'] = $plugin; | |
| $translation['status'] = in_array( $translation['language'], $installed_translations, true ) ? 'installed' : 'uninstalled'; | |
| if ( $current_locale === $translation['language'] ) { | |
| $translation['status'] = 'active'; | |
| } | |
| $filter_args = array( | |
| 'language' => $translation['language'], | |
| 'type' => 'plugin', | |
| 'slug' => $plugin, | |
| ); | |
| $update = wp_list_filter( $updates, $filter_args ); | |
| $translation['update'] = $update ? 'available' : 'none'; | |
| // Support features like --status=active. | |
| foreach ( array_keys( $translation ) as $field ) { | |
| if ( isset( $assoc_args[ $field ] ) && $assoc_args[ $field ] !== $translation[ $field ] ) { | |
| continue 2; | |
| } | |
| } | |
| $translations[] = $translation; | |
| } | |
| } | |
| $formatter = $this->get_formatter( $assoc_args ); | |
| $formatter->display_items( $translations ); | |
| } |
That's where the following check (against an empty $installed_translations array returned by get_installed_languages()) results in the uninstalled value:
| $translation['status'] = in_array( $translation['language'], $installed_translations, true ) ? 'installed' : 'uninstalled'; |
A solution is to account for the discrepancy between plugin slugs and text domains in the get_installed_languages() method.