Skip to content

Incorrect language installation status when plugin's slug is different from its text domain #136

Open
@mrcasual

Description

@mrcasual

Bug Report

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

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions