Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save stephenh1988/3066080 to your computer and use it in GitHub Desktop.
Save stephenh1988/3066080 to your computer and use it in GitHub Desktop.
Change the language by the click of a button (link in the admin bar).
<?php
! defined( 'ABSPATH' ) AND exit;
/*
Plugin Name: User Language Switcher
Plugin URI: http://example.com
Description: Change the language per user, by the click of a button
Author: Stephen Harris
Author URI: http://example.com
Contributors: Franz Josef Kaiser
Version: 0.2
License: GNU GPL 2
*/
# PUBLIC API #
/**
* A function returns with returns the user's selectd locale, if stored.
*
* @since 0.1
*
* @param bool $locale
* @return mixed string/bool $locale
*/
function get_user_locale( $locale )
{
if ( $new_locale = get_user_meta(
get_current_user_id()
,'user_language'
,true
)
);
return $new_locale;
return $locale;
}
if ( ! class_exists( 'UserLangSelect' ) )
{
//add_action( 'init', array( 'UserLangSelect', 'init' ) );
/**
* Allows the user to change the systems language.
* Saves the preference as user meta data.
*
* @since 0.1
*
* @author Stephen Harrs
* @link http://wordpress.stackexchange.com/questions/35622/change-language-by-clicking-a-button/57503
*
* @package WordPress
* @subpackage User Language Change
*/
class UserLangSelect
{
/**
* Instance
*
* @access protected
* @var object
*/
static protected $instance;
/**
* A unique name for this plug-in
*
* @since 0.1
*
* @access public
* @var string
*/
static public $name ='sh_pick_lang';
/**
* Hook the functions
*
* @since 0.1
*
* @return void
*/
public function __construct()
{
isset( $_POST[ self :: $name ] ) AND add_action( 'locale', array( $this, 'update_user' ) );
add_filter( 'locale', 'get_user_locale',10);
add_action( 'wp_before_admin_bar_render', array( $this, 'admin_bar') );
}
/**
* Update the user's option just in time!
* Only once mind...
*
* @since 0.1
*
* @param $locale string
* @return $locale string
*/
public function update_user( $locale )
{
remove_filter( current_filter(), array( $this, 'update_user' ) );
update_user_meta(
get_current_user_id()
,'user_language'
,$_POST[ self :: $name ]
);
//Just in case get_user_locale runs too early
return get_user_locale($locale);
}
/**
* The drop down for the admin bar
*
* @since 0.1
*
* @return void
*/
public function admin_bar()
{
global $wp_admin_bar;
$wp_admin_bar->add_menu( array(
'id' => 'user_lang_pick'
,'title' => $this->lang_dropown()
) );
}
/**
* Generates a list of available locales.
* Searches the wp-content/languages folder for files of the form xx_xx.mo
*
* Based on Thomas "toscho" Scholz answer on the following WPSE question by Stephen Harris:
* @link http://wordpress.stackexchange.com/questions/57606/obtain-a-list-of-available-translations/57609
*
* //FIXME including wp-admin/includes/ms.php in non-ms sites displays message prompting user to update network sites.
*
* @since 0.1
* @uses get_available_language()
* @uses format_code_lang()
* @return string $html
*/
public function lang_dropown()
{
$langs = get_available_languages();
$langs[] = 'en_US';
$locale = get_locale();
// For the labels (format_code_lang)
require_once( ABSPATH.'wp-admin/includes/ms.php');
// Build the option elements
$elements = '';
foreach ( $langs as $lang )
{
$elements .= sprintf (
'<option %s value="%s">%s</option>'
,selected( $lang, $locale, false )
,$lang
,format_code_lang( $lang )
);
}
// Build the form
$html = sprintf(
'<form method="post"><select onchange="javascript: form.submit();" name="%s">%s</select></form>'
,self :: $name
,$elements
);
return $html;
}
} // END Class UserLangSelect
$user_language_switcher = new UserLangSelect();
} // endif;
@franz-josef-kaiser
Copy link

Oh, and the id inside admin_bar() could be self :: $name. Making stuff generic makes it also easier to extend. Another possibility would be to add a filter to the lang_dropown()s input data (and change its name to just "dropdown" and $lang to just $val). This would make it possible to use any sort of data and add an user specific drop down to the admin user interface. But when we're already at this point, it would be better to also split the file in half and take the definition, specification to another file.

... after thinking about it: It would even be kooler, if the languages would be in another method get_data() where get_available_languages(); and en_US get set. So overriding wouldn't need a filter, but just another (overriding child) method that calls and builds the input data for the core class.

@franz-josef-kaiser
Copy link

Ehm, ok. Forget extending the class. I read through again it and its simply not worth the effort. Too much specific stuff in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment