'switch',
'title' => t('Localizer'),
'callback' => 'localizer_switch',
'access' => user_access('access localizer'),
'type' => MENU_CALLBACK);
$items[] = array(
'path' => 'node/'. arg(1) .'/localizer',
'title' => t('translation'),
'callback' => 'localizer_node_page',
'access' => user_access('administer localizer'),
'type' => MENU_LOCAL_TASK,
'weight' => 3);
}
localizer_menu_translate_all();
return $items;
}
/**
* Implementation of hook nodeapi.
* The translation mechanism acts here, for the "load" $op
*/
function localizer_nodeapi(&$node, $op, $teaser, $page) {
global $locale;
$localeinurl = explode('/', $_REQUEST['q']);
$localeinurl = $localeinurl[0];
$valid_locales = localizer_supported_languages();
if(array_key_exists($localeinurl, $valid_locales))
{
$locale = localizer_changelocale($localeinurl);
}
if(array_key_exists('locale', $_GET))
{
$locale = localizer_changelocale($_GET['locale']);
}
switch ($op) {
case 'load':
$node->localizer_locale = db_result(db_query('SELECT locale FROM {localizer} WHERE nid = %d', $node->nid));
if($locale != $node->localizer_locale) {
$pid = db_result(db_query('SELECT pid FROM {localizer} WHERE nid = %d', $node->nid));
if($pid) {
$nid = db_result(db_query("SELECT nid FROM {localizer} WHERE pid = %d AND locale= '%s'", $pid, $locale));
if($nid) {
$node=node_load($nid);
}
}
}
$object = db_fetch_object(db_query('SELECT locale, pid FROM {localizer} WHERE nid = %d', $node->nid));
return array('localizer_locale' => $object->locale, 'localizer_pid' => $object->pid);
break;
case 'insert':
if($node->localizer_pid == 0){
$node->localizer_pid = $node->nid;
}
db_query("INSERT INTO {localizer} (nid, locale, pid) VALUES (%d, '%s', %d)", $node->nid, $node->localizer_locale, $node->localizer_pid);
break;
case 'update':
if($node->localizer_pid == 0){
$node->localizer_pid = $node->nid;
}
db_query('DELETE FROM {localizer} WHERE nid = %d', $node->nid);
db_query("INSERT INTO {localizer} (nid, locale, pid) VALUES (%d, '%s', %d)", $node->nid, $node->localizer_locale, $node->localizer_pid);
break;
case 'delete':
db_query('DELETE FROM {localizer} WHERE nid = %d', $node->nid);
break;
}
}
/**
* Modify the form for every node adding the necessary fields for localizer module : pid and locale
*/
function localizer_form_alter($form_id, &$form) {
if (!isset($form['type'])) {
return;
}
switch ($form_id) {
case $form['type']['#value'] .'_node_form':
global $locale;
if(arg(3) == 'localizer' && user_access('administer localizer')) {
// We are translating a node in the form : node/add/type/translation/nid/lang
global $user;
$source_nid = arg(4);
$target_locale = arg(5);
$node = node_load($source_nid);
$node->nid = NULL;
$node->uid = $user->uid;
$node->created = 0;
$node->menu = NULL;
$node->path = NULL;
$node->title = localizer_t($node->title, NULL ,$locale);
$node->localizer_locale = $target_locale;
$locale=$target_locale;
$_SESSION['current_locale']=$target_locale;
node_save($node);
drupal_goto('node/'. $node->nid . '/edit');
}
$options = localizer_supported_languages();
if(!isset($form['#node']->localizer_locale))
{
$form['#node']->localizer_locale = $locale;
}
$form['localizer_locale'] = array(
'#type' => 'select',
'#title' => t('Locale'),
'#default_value' => $form['#node']->localizer_locale,
'#options' => $options,
'#required' => TRUE,
'#weight' => 0,
);
break;
}
}
/**
* Hook for the submit of the form, updating the pid of the node
*/
function localizer_node_form_submit($form_id, $form_values){
$op = $_POST['op'];
$localizer_pid = $form_values['localizer_pid'];
$nid = $form_values['nid'];
if( $localizer_pid && $nid ) {
db_query("UPDATE {localizer} SET pid = %d WHERE nid=%d", $localizer_pid, $nid);
drupal_set_message(t('The translation has been saved'));
}
}
/**
* Translates all user's menus items
*/
function localizer_menu_translate_all(){
global $_menu;
global $user;
global $locale;
foreach($_menu['items'] as $mid => $item) {
if($item['type'] & MENU_CREATED_BY_ADMIN) {
$expanded = false;
$path = $item['path'];
$reqpath = $_REQUEST['q'];
$drupalpath = drupal_get_normal_path($reqpath);
if($drupalpath == $path) {
$expanded = true;
}
if(!$expanded) {
$drupalpath = drupal_get_normal_path(localizer_pathwithoutlocale($reqpath));
if($drupalpath == $path) {
$expanded = true;
}
}
if(!$expanded) {
$languages = localizer_supported_languages();
foreach($languages as $langprefix=>$langname) {
if(!$expanded) {
$drupalpath = drupal_get_normal_path(localizer_pathwithlocale($reqpath, $langprefix));
if($drupalpath == $path) {
$expanded = true;
break;
}
}
}
}
if($expanded) {
localizer_expandmenu($mid);
$_menu['items'][$mid]['path'] = drupal_get_normal_path($reqpath);
}
$_menu['items'][$mid]['title'] = t($_menu['items'][$mid]['title']);
}
}
}
function localizer_expandmenu($_mid) {
global $_menu;
if($_mid>0) {
$_menu['visible'][$pid]['type'] = MENU_EXPANDED;
$_menu['visible'][$_mid]['type'] = MENU_EXPANDED;
$pid = $_menu['visible'][$_mid]['pid'];
localizer_expandmenu($pid);
}
}
/**
* Sets the intial language in the order : session, user preferences or browser detect
*/
function i18n_get_lang() {
global $user;
$languages = localizer_supported_languages();
if (isset($_SESSION['current_locale']) && $languages[$_SESSION['current_locale']]) {
return $_SESSION['current_locale'];
}
else if ($user->uid && $languages[$user->language]) {
return $user->language;
}
else if (variable_get('localizer_detect_browser', TRUE) && ($lang = localizer_get_browser_lang())) {
return $lang;
}
else {
return key($languages);
}
}
/**
* Lists the supported languages form the locale module
*/
function localizer_supported_languages() {
static $languages;
if(!isset($languages)) {
if (function_exists('locale')) {
$languages = locale_supported_languages();
$languages = $languages['name'];
}
else {
$languages = array('en' => 'English');
}
}
return $languages;
}
/**
* Returns is the locale provided is valid
*/
function localizer_isvalidlocale($_locale = '') {
static $valid_locales;
$valid_locales = localizer_supported_languages();
if(($_locale!= '') && array_key_exists($_locale, $valid_locales)){
return true;
}
else
{
return false;
}
}
/**
* Returns the path without the locale
*/
function localizer_pathwithoutlocale($_path) {
$exploded_path = explode('/', $_path);
$localeinpath = $exploded_path[0];
if(localizer_isvalidlocale($localeinpath)){
array_shift($exploded_path);
return implode("/", $exploded_path);
}
else
{
return $_path;
}
}
/**
* Returns the path with the locale prefixed
*/
function localizer_pathwithlocale($_path, $_locale) {
if(localizer_isvalidlocale($_locale)) {
return $_locale . '/' . localizer_pathwithoutlocale($_path);
}
else
{
return $_path;
}
}
/**
* Returns the locale contained in the path
*/
function localizer_localeinpath($_path) {
$exploded_path = explode('/', $_path);
$localeinpath = $exploded_path[0];
if(localizer_isvalidlocale($localeinpath)){
return $localeinpath;
}
else
{
return '';
}
}
/**
* Get the language of the browser
*/
function localizer_get_browser_lang() {
$languages = localizer_supported_languages();
$exploded_server = explode(";",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
$accept=explode(',',array_shift($exploded_server)); ;
foreach ($accept as $lang) {
$lang=substr($lang,0,2);
if (!empty($lang) && array_key_exists($lang,$languages)) {
return $lang;
}
}
return NULL;
}
/**
* Hook for switching the language through the block
* @param switch_to the locale of the new selected language
*/
function localizer_switch($switch_to) {
localizer_changelocale($switch_to);
drupal_goto();
}
/**
* Generate HTML for the localizer block
* @param op the operation from the URL
* @param delta offset
* @returns block HTML
*/
function localizer_block($op = 'list', $delta = 0, $edit = array()) {
global $user;
switch ($op) {
case 'list':
$block[0]['info'] = t('Select language');
break;
case 'view':
if($delta == 0 && !($user->uid && variable_get('localizer_hide_block', FALSE))) {
$block['subject'] = t('Select language');
$block['content'] = theme('item_list', localizer_get_links(variable_get('localizer_show_flags', TRUE), variable_get('localizer_name',TRUE), variable_get('localizer_separator', ' ')));
}
break;
}
return $block;
}
/**
* Generate HTML for language change
* @out prints HTML code on standard output
* @returns HTML code
*/
function localizer_changelanguageblock($out=true)
{
$output = theme('item_list', localizer_get_links(variable_get('localizer_show_flags', TRUE), variable_get('localizer_name',TRUE), variable_get('localizer_separator', ' ')));
if($out) {
echo $output;
}
return $output;
}
/**
* Creates the links for the switching language block
* @param flags shows the languages flags
* @param names shows the languages names
* @param separator text to use as separator between the flag and the name
* @returns links in HTML format
*/
function localizer_get_links($flags = 1, $names = 1, $separator = ' ') {
global $locale;
$languages = localizer_supported_languages();
$destination = localizer_get_destination();
if($destination == ''){
$destination = variable_get('site_frontpage', 'node');
}
$path = explode("?", $destination);
$path = $path[0];
foreach ($languages as $lang => $langname) {
if($lang != $locale) {
if(drupal_get_normal_path($lang . "/" . $path) != ($lang . "/" . $path)){
$locale_destination = $lang . "/" . $destination;
}
else
{
$locale_destination = $destination;
}
$langname = localizer_t($langname, 0, $lang);
$flag = $flags ? localizer_flag($lang, array('alt' => $langname)) : '' ;
$separator = ($langname != '' && $flag != '') ? $separator : '';
$pos = strpos($locale_destination, 'destination=');
if($pos === FALSE) {
$locale_destination = "destination=" . urlencode($locale_destination);
$links[]= l("$flag$separator$langname", 'switch/'.$lang, array('title' => t('Switch language to %lang', array('%lang' => $langname))), $locale_destination , NULL, NULL, TRUE);
}
else
{
$locale_path = $_REQUEST['q'];
$destination = urldecode($destination);
$destination = substr($destination, strlen('destination='));
$locale_destination = "destination=" . urlencode($locale_path . '?destination=' . $destination);
$links[]= l("$flag$separator$langname", 'switch/'.$lang, array('title' => t('Switch language to %lang', array('%lang' => $langname))), $locale_destination , NULL, NULL, TRUE);
}
}
}
return $links;
}
/**
* Create the HTML a language's flag
* @param lang the language of the flag
* @param attribs additional attributes
* @returns HTML code
*/
function localizer_flag($lang, $attribs = array()) {
if ($path = variable_get('localizer_flags_path', drupal_get_path('module', 'localizer') . '/flags/*.png')) {
$src = base_path() . str_replace('*', $lang, $path);
list($width, $height) = explode('x', variable_get('localizer_flags_size', '16x12'));
$attribs = array_merge(array('class' => 'localizer-flag', 'width' => $width, 'height' => $height, 'alt' => ''), $attribs);
$html = "";
return $html;
}
}
/**
* Hook settings for the module
*/
function localizer_settings() {
$form['localizer_detect_browser'] = array (
'#type' => 'checkbox',
'#title' => t('Browser language detection'),
'#default_value' => variable_get('localizer_detect_browser', 1),
);
$form['localizer_hide_block'] = array (
'#type' => 'checkbox',
'#title' => t('Hide block for authenticated user'),
'#default_value' => variable_get('localizer_hide_block', 1),
);
$form['localizer_name'] = array (
'#type' => 'checkbox',
'#title' => t('Display language name'),
'#default_value' => variable_get('localizer_name', 1),
);
$form['localizer_show_flags'] = array (
'#type' => 'checkbox',
'#title' => t('Show flags'),
'#default_value' => variable_get('localizer_show_flags', 1),
);
$form['localizer_show_flags'] = array (
'#type' => 'textfield',
'#title' => t('Flag and language separator'),
'#default_value' => variable_get('localizer_separator', ' '),
'#size' => 5,
'#maxlength' => 10,
'#description' => 'Token separating the flag and languagename.',
);
$form['localizer_flags_path'] = array (
'#type' => 'textfield',
'#title' => t('Flag icons path'),
'#default_value' => variable_get('localizer_flags_path', drupal_get_path('module', 'localizer') . '/flags/*.png'),
'#size' => 50,
'#maxlength' => 180,
'#description' => 'Path for flag icons, relative to Drupal installation. \'*\' is a placeholder for language code.',
);
$form['localizer_flags_size'] = array (
'#type' => 'textfield',
'#title' => t('Flag icons size'),
'#default_value' => variable_get('localizer_flags_size', variable_get('localizer_flags_size', '16x12')),
'#size' => 10,
'#maxlength' => 10,
'#description' => 'Image size for flags, in the form "width x height".',
);
return $form;
}
/**
* Hook for the overview of a node.
* Implements the translations tab interface
*/
function localizer_node_overview($node) {
$languages = localizer_supported_languages();
unset($languages[$node->localizer_locale]);
$output = t('
No nodes available in %language
", array('%language' => $languages[$locale]) ); } } /** * Gets the translations for the current node * @param nid the id of the node * @param getitself includes also the node in the list */ function localizer_node_get_translations($nid, $getitself = FALSE) { $pid = db_result(db_query('SELECT pid FROM {localizer} WHERE nid = %d', $nid)); if($getitself) { $result = db_query('SELECT n.nid, n.title, n.status, l.locale FROM {node} n INNER JOIN {localizer} l ON n.nid = l.nid AND l.pid = %d', $pid); } else { $result = db_query('SELECT n.nid, n.title, n.status, l.locale FROM {node} n INNER JOIN {localizer} l ON n.nid = l.nid AND l.pid = %d AND l.nid <> %d', $pid, $_nid); } $items = array(); while ($node = db_fetch_object($result)) { $items[$node->locale] = $node; } return $items; } /** * Change the global locale * @param string the new locale * @param _locale the locale to use for the translation * @returns the global locale */ function localizer_changelocale($_locale = '') { global $locale; static $valid_locales; $valid_locales = localizer_supported_languages(); if(($_locale != '') && ($_locale != $locale) && (array_key_exists($_locale, $valid_locales))) { $locale=$_locale; $_SESSION['current_locale']=$locale; } return $locale; } function localizer_get_destination() { if (isset($_REQUEST['destination'])) { return 'destination='. urlencode($_REQUEST['destination']); } else { // Use $_REQUEST here to retrieve the original path. $path = isset($_REQUEST['q']) ? $_REQUEST['q'] : ''; $path = localizer_pathwithoutlocale($_REQUEST['q']); $query = drupal_query_string_encode($_GET, array('q')); if ($query != '') { $path .= '?'. $query; } return $path; } } //Rewrite of some core functions /** * Translates a string a substitute the arguments * @param string the string to translate * @param args array of additional arguments to substitute * @param _locale the locale to use for the translation */ function localizer_t($string, $args = 0, $_locale = '') { global $locale; if($_locale == '') { $_locale = $locale; } if (function_exists('localizer_locale') && $_locale != 'en') { $string = localizer_locale($string, $_locale); } if (!$args) { return $string; } else { return strtr($string, $args); } } /** * Translates a string * @param string the stirng to translate * @param _locale the locale to use for the translation */ function localizer_locale($string, $_locale = '') { global $locale; if($_locale == '') { $_locale = $locale; }; $cache = cache_get("locale:$_locale"); if ($cache == 0) { locale_refresh_cache(); $cache = cache_get("locale:$_locale"); } $locale_t = unserialize($cache->data); // We have the translation cached (if it is TRUE, then there is no // translation, so there is no point in checking the database) if (isset($locale_t[$string])) { $string = ($locale_t[$string] === TRUE ? $string : $locale_t[$string]); } // We do not have this translation cached, so get it from the DB. else { $result = db_query("SELECT s.lid, t.translation FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid WHERE s.source = '%s' AND t.locale = '%s'", $string, $_locale); // Translation found if ($trans = db_fetch_object($result)) { if (!empty($trans->translation)) { $locale_t[$string] = $trans->translation; $string = $trans->translation; } } // Either we have no such source string, or no translation else { $result = db_query("SELECT lid, source FROM {locales_source} WHERE source = '%s'", $string); // We have no such translation if ($obj = db_fetch_object($result)) { if ($_locale) { db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '')", $obj->lid, $_locale); } } // We have no such source string else { db_query("INSERT INTO {locales_source} (location, source) VALUES ('%s', '%s')", request_uri(), $string); if ($_locale) { $lid = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $string)); db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '')", $lid->lid, $_locale); } } // Clear locale cache in DB cache_clear_all("locale:$_locale"); } } return $string; } ?>