Skip Navigation

Resolved

Reported for: WPML Multilingual CMS 4.6.5

Resolved in: 4.6.6

Topic Tags: Bug

Overview of the issue

After updating to WPML 4.6.5 on multisite WordPress installations, you will notice that that the translator list, which should be available under WPML > Translation Management > Translators, is empty.

Workaround

Please, make sure of having a full backup of your site before proceeding.

  • Open …/wp-content/plugins/sitepress-multilingual-cms/classes/user/class-wpml-translation-roles-records.php file.
  • Look for line 116.
  • Replace the method: /WPML_Translation_Roles_Records::get_records:
    	private function get_records( $compare, $search = '', $limit = -1 ) {
    		$search = trim( $search );
    
    		$cache_key = md5( (string) wp_json_encode( [ get_class( $this ), $compare, $search, $limit ] ) );
    		$cache     = wpml_get_cache( self::CACHE_GROUP );
    		$found     = false;
    		$results   = $cache->get( $cache_key, $found );
    		if ( $found ) {
    			return $results;
    		}
    
    		$preparedUserQuery = $this->wpdb->prepare(
    			"SELECT u.id FROM {$this->wpdb->prefix}users u INNER JOIN {$this->wpdb->prefix}usermeta c ON c.user_id=u.ID AND CAST(c.meta_key AS BINARY)=%s AND c.meta_value {$compare} %s",
    			"{$this->wpdb->prefix}capabilities",
    			"%" . $this->get_capability() . "%"
    		);
    
    		if ( self::USERS_WITHOUT_CAPABILITY === $compare ) {
    			$required_wp_roles = $this->get_required_wp_roles();
    			foreach( $required_wp_roles as $required_wp_role ) {
    				$preparedUserQuery .= $this->wpdb->prepare( " AND c.meta_value LIKE %s", "%{$required_wp_role}%" );
    			}
    		}
    
    		if ( $search ) {
    			$preparedUserQuery .= $this->wpdb->prepare( " AND (u.user_login LIKE %s OR u.user_nicename LIKE %s OR u.user_email LIKE %s)", "%{$search}%", "%{$search}%", "%{$search}%" );
    		}
    
    		$preparedUserQuery .= ' ORDER BY user_login ASC';
    
    		if ( $limit > 0 ) {
    			$preparedUserQuery .= $this->wpdb->prepare(" LIMIT 0,%d", $limit );
    		}
    
    		$users      = $this->wpdb->get_col( $preparedUserQuery );
    
    		if ( $search && strlen( $search ) > self::MIN_SEARCH_LENGTH && ( $limit <= 0 || count( $users ) < $limit ) ) {
    			$users_from_metas = $this->get_records_from_users_metas( $compare, $search, $limit );
    			$users_with_dupes = array_merge( $users, $users_from_metas );
    			$users            = wpml_array_unique( $users_with_dupes, SORT_REGULAR );
    		}
    
    		$results = array();
    		foreach ( $users as $user_id ) {
    			$user_data = get_userdata( $user_id );
    			if ( $user_data ) {
    				$language_pair_records = new WPML_Language_Pair_Records( $this->wpdb, new WPML_Language_Records( $this->wpdb ) );
    				$language_pairs        = $language_pair_records->get( $user_id );
    
    				$result    = (object) array(
    					'ID'             => $user_data->ID,
    					'full_name'      => trim( $user_data->first_name . ' ' . $user_data->last_name ),
    					'user_login'     => $user_data->user_login,
    					'user_email'     => $user_data->user_email,
    					'display_name'   => $user_data->display_name,
    					'language_pairs' => $language_pairs,
    					'roles'          => $user_data->roles
    				);
    				$results[] = $result;
    			}
    		}
    
    		$cache->set( $cache_key, $results );
    
    		return $results;
    	}
    
  • With:
    	private function get_records( $compare, $search = '', $limit = -1 ) {
    		$search = trim( $search );
    
    		$cache_key = md5( (string) wp_json_encode( [ get_class( $this ), $compare, $search, $limit ] ) );
    		$cache     = wpml_get_cache( self::CACHE_GROUP );
    		$found     = false;
    		$results   = $cache->get( $cache_key, $found );
    		if ( $found ) {
    			return $results;
    		}
    
    		$query_args = array(
    			'fields'     => 'ID',
    			'meta_query' => array(
    				array(
    					'key'     => "{$this->wpdb->prefix}capabilities",
    					'value'   => $this->get_capability(),
    					'compare' => $compare,
    				),
    			),
    			'number'     => $limit,
    		);
    
    		if ( 'NOT LIKE' === $compare ) {
    			$required_wp_roles = $this->get_required_wp_roles();
    			if ( $required_wp_roles ) {
    				$query_args['role__in'] = $required_wp_roles;
    			}
    		}
    
    		if ( $search ) {
    			$query_args['search']         = '*' . $search . '*';
    			$query_args['search_columns'] = array( 'user_login', 'user_nicename', 'user_email' );
    		}
    
    		$user_query = $this->user_query_factory->create( $query_args );
    		$users      = $user_query->get_results();
    
    		if ( $search && strlen( $search ) > self::MIN_SEARCH_LENGTH && ( $limit <= 0 || count( $users ) < $limit ) ) {
    			$users_from_metas = $this->get_records_from_users_metas( $compare, $search, $limit );
    			$users_with_dupes = array_merge( $users, $users_from_metas );
    			$users            = wpml_array_unique( $users_with_dupes, SORT_REGULAR );
    		}
    
    		$results = array();
    		foreach ( $users as $user_id ) {
    			$user_data = get_userdata( $user_id );
    			if ( $user_data ) {
    				$language_pair_records = new WPML_Language_Pair_Records( $this->wpdb, new WPML_Language_Records( $this->wpdb ) );
    				$language_pairs        = $language_pair_records->get( $user_id );
    
    				$result    = (object) array(
    					'ID'             => $user_data->ID,
    					'full_name'      => trim( $user_data->first_name . ' ' . $user_data->last_name ),
    					'user_login'     => $user_data->user_login,
    					'user_email'     => $user_data->user_email,
    					'display_name'   => $user_data->display_name,
    					'language_pairs' => $language_pairs,
    					'roles'          => $user_data->roles
    				);
    				$results[] = $result;
    			}
    		}
    
    		$cache->set( $cache_key, $results );
    
    		return $results;
    	}