| Commit | Line | Data |
|---|---|---|
| 78e8cd8d JR |
1 | <?php |
| 2 | // $Id$ | |
| 55209b2f | 3 | |
| 78e8cd8d | 4 | /** |
| afcc0a25 | 5 | * @file |
| 4c4a8511 | 6 | * Internationalization (i18n) module. |
| 78e8cd8d | 7 | * |
| 818652bd JR |
8 | * This module extends multilingual support being the base module for the i18n package. |
| 9 | * - Multilingual variables | |
| 10 | * - Extended languages for nodes | |
| 11 | * - Extended language API | |
| 136d636d | 12 | * |
| 78e8cd8d JR |
13 | * @author Jose A. Reyero, 2004 |
| 14 | */ | |
| 15 | ||
| afcc0a25 JR |
16 | // Some constants. Language support modes for content |
| 17 | define('LANGUAGE_SUPPORT_NONE', 0); | |
| 18 | define('LANGUAGE_SUPPORT_NORMAL', 1); | |
| 19 | define('LANGUAGE_SUPPORT_EXTENDED', 2); | |
| 5196f381 | 20 | define('LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED', 3); |
| 3314df44 | 21 | |
| 90d529a0 | 22 | /** |
| ec427688 JR |
23 | * Implementation of hook_boot() |
| 24 | * | |
| 25 | * Initialize variables, that will be used to decide on site_frontpage | |
| 26 | */ | |
| 27 | function i18n_boot() { | |
| 28 | drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE); | |
| 29 | _i18n_init(); | |
| 30 | } | |
| 31 | ||
| 32 | /** | |
| 98f49db3 | 33 | * Implementation of hook_init(). |
| 136d636d | 34 | * |
| 98f49db3 | 35 | * Special fix for site_frontpage, that may have been used before the language variables are loaded. |
| 937ec95a | 36 | */ |
| 98f49db3 | 37 | function i18n_init() { |
| ec427688 | 38 | // If not in bootstrap, variable init. Otherwise we are serving a cached page so we don't need anything else. |
| 98f49db3 | 39 | if (!_i18n_is_bootstrap()) { |
| ec427688 | 40 | _i18n_init(TRUE); |
| f8f1d8cf JR |
41 | _i18n_init_mode(); |
| 42 | } | |
| 43 | } | |
| 44 | ||
| 45 | /** | |
| 46 | * Initialize multilingual variables and use them for site_frontpage | |
| 47 | * | |
| 48 | * Special fix for site_frontpage, that may have been used before the language variables are loaded. | |
| 49 | */ | |
| ec427688 | 50 | function _i18n_init($check_frontpage = FALSE) { |
| 27bba143 | 51 | static $done, $default_frontpage; |
| f8f1d8cf JR |
52 | |
| 53 | // Prevent this function from running twice; | |
| 54 | if (!isset($done)) { | |
| 55 | $done = TRUE; | |
| b28c2734 | 56 | $default_frontpage = variable_get('site_frontpage', 'node'); |
| b28c2734 | 57 | i18n_variable_init(); |
| 27bba143 JR |
58 | } |
| 59 | // We do aditional frontpage check if this has run after first bootstrap phase. | |
| 60 | // But if this runs in hook_boot we should be ok | |
| 61 | if ($check_frontpage && $default_frontpage != variable_get('site_frontpage', 'node') && $_GET['q'] == drupal_get_normal_path($default_frontpage)) { | |
| 62 | $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node')); | |
| afcc0a25 | 63 | } |
| 90d529a0 | 64 | } |
| 3128d317 | 65 | |
| 6681618a | 66 | /** |
| f8f1d8cf JR |
67 | * Initialize selection mode |
| 68 | */ | |
| 69 | function _i18n_init_mode() { | |
| 70 | if (i18n_selection_mode() != 'off') { | |
| 71 | // Node language when loading specific nodes or creating translations. | |
| 72 | if (arg(0) == 'node' ) { | |
| 73 | if (($node = menu_get_object('node')) && $node->language) { | |
| 74 | i18n_selection_mode('node', $node->language); | |
| 75 | } | |
| 76 | elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) { | |
| 77 | i18n_selection_mode('translation', db_escape_string($_GET['language'])); | |
| 78 | } | |
| 79 | } | |
| 80 | elseif (arg(0) == 'admin') { | |
| 81 | // There are some exceptions for admin pages. | |
| 82 | if (arg(1) == 'content' && user_access('administer all languages')) { | |
| 83 | // No restrictions for administration pages. | |
| 84 | i18n_selection_mode('off'); | |
| 85 | } | |
| 95c3e7df | 86 | elseif (arg(1) == 'build' && (arg(2) == 'menu-customize' || arg(2) == 'menu')) { |
| f8f1d8cf JR |
87 | // All nodes available when editing custom menu items. |
| 88 | i18n_selection_mode('off'); | |
| 89 | } | |
| 90 | } | |
| 91 | } | |
| 92 | } | |
| 93 | /** | |
| 6681618a JR |
94 | * Implementation of hook_help(). |
| 95 | */ | |
| affdb36b JR |
96 | function i18n_help($path = 'admin/help#i18n', $arg) { |
| 97 | switch ($path) { | |
| d469e0bb | 98 | case 'admin/help#i18n' : |
| 98f49db3 | 99 | $output = '<p>'. t('This module improves support for multilingual content in Drupal sites:') .'</p>'; |
| 98e35ee4 | 100 | $output .= '<ul>'; |
| 10973c0b | 101 | $output .= '<li>'. t('Shows content depending on page language.') .'</li>'; |
| 102 | $output .= '<li>'. t('Handles multilingual variables.') .'</li>'; | |
| 98f49db3 | 103 | $output .= '<li>'. t('Extended language option for chosen content types. For these content types transations will be allowed for all defined languages, not only for enabled ones.') .'</li>'; |
| 1d637c88 | 104 | $output .= '<li>'. t('Provides a block for language selection and two theme functions: <em>i18n_flags</em> and <em>i18n_links</em>.') .'</li>'; |
| 818652bd | 105 | $output .= '</ul>'; |
| 98f49db3 | 106 | $output .= '<p>'. t('This is the base module for several others adding different features:') .'</p>'; |
| 136d636d | 107 | $output .= '<ul>'; |
| 77fa73f1 | 108 | $output .= '<li>'. t('Multilingual menu items.') .'</li>'; |
| 109 | $output .= '<li>'. t('Multilingual taxonomy adds a language field for taxonomy vocabularies and terms.') .'</li>'; | |
| 98e35ee4 | 110 | $output .= '</ul>'; |
| 98f49db3 | 111 | $output .= '<p>'. t('For more information, see the online handbook entry for <a href="@i18n">Internationalization module</a>.', array('@i18n' => 'http://drupal.org/node/133977')) .'</p>'; |
| 98e35ee4 | 112 | return $output; |
| ac10f554 | 113 | |
| 0b07a5e3 | 114 | case 'admin/settings/language/i18n': |
| 818652bd | 115 | $output = '<ul>'; |
| 98f49db3 | 116 | $output .= '<li>'. t('To enable multilingual support for specific content types go to <a href="@configure_content_types">configure content types</a>.', array('@configure_content_types' => url('admin/content/types'))) .'</li>'; |
| 117 | $output .= '</ul>'; | |
| 38f996de | 118 | return $output; |
| 6681618a | 119 | } |
| 6681618a JR |
120 | } |
| 121 | ||
| 122 | /** | |
| 8dcb741b | 123 | * Implementation of hook_menu(). |
| 8dcb741b | 124 | */ |
| afcc0a25 | 125 | function i18n_menu() { |
| 0b07a5e3 | 126 | $items['admin/settings/language/i18n'] = array( |
| afcc0a25 | 127 | 'title' => 'Multilingual system', |
| 818652bd JR |
128 | 'description' => 'Configure extended options for multilingual content and translations.', |
| 129 | 'page callback' => 'drupal_get_form', | |
| 130 | 'page arguments' => array('i18n_admin_settings'), | |
| 131 | 'access arguments' => array('administer site configuration'), | |
| 132 | 'file' => 'i18n.admin.inc', | |
| e40ff52f | 133 | 'type' => MENU_LOCAL_TASK, |
| 0b07a5e3 | 134 | 'weight' => 10, |
| 0173ca0a | 135 | ); |
| 0b07a5e3 JR |
136 | $items['admin/settings/language/i18n/configure'] = array( |
| 137 | 'title' => 'Multilingual system', | |
| 138 | 'description' => 'Configure extended options for multilingual content and translations.', | |
| 139 | //'page callback' => 'drupal_get_form', | |
| 140 | //'page arguments' => array('i18n_admin_settings'), | |
| 141 | //'access arguments' => array('administer site configuration'), | |
| 142 | 'file' => 'i18n.admin.inc', | |
| 143 | 'type' => MENU_DEFAULT_LOCAL_TASK, | |
| afcc0a25 | 144 | ); |
| 1d40cadd JR |
145 | // Autocomplete callback for nodes |
| 146 | $items['i18n/node/autocomplete'] = array( | |
| 147 | 'title' => 'Node title autocomplete', | |
| 148 | 'page callback' => 'i18n_node_autocomplete', | |
| 149 | 'access arguments' => array('access content'), | |
| 150 | 'type' => MENU_CALLBACK, | |
| 151 | 'file' => 'i18n.pages.inc', | |
| 152 | ); | |
| 8dcb741b JR |
153 | return $items; |
| 154 | } | |
| 98e35ee4 | 155 | |
| 8dcb741b | 156 | /** |
| 818652bd | 157 | * Implementation of hook_menu_alter(). |
| 136d636d | 158 | * |
| 98f49db3 | 159 | * Take over the node translation page. |
| 818652bd JR |
160 | */ |
| 161 | function i18n_menu_alter(&$items) { | |
| 818652bd JR |
162 | $items['node/%node/translate']['page callback'] = 'i18n_translation_node_overview'; |
| 163 | $items['node/%node/translate']['file'] = 'i18n.pages.inc'; | |
| 164 | $items['node/%node/translate']['module'] = 'i18n'; | |
| 818652bd JR |
165 | } |
| 166 | ||
| 167 | /** | |
| 98e35ee4 JR |
168 | * Implementation of hook_nodeapi(). |
| 169 | */ | |
| 3314df44 JR |
170 | function i18n_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { |
| 171 | global $language; | |
| 172 | ||
| 173 | if (variable_get('language_content_type_' . $node->type, 0)) { | |
| 174 | // Set current language for new nodes if option enabled | |
| 175 | if ($op == 'prepare' && empty($node->nid) && empty($node->language) && variable_get('i18n_newnode_current_' . $node->type, 0)) { | |
| 176 | $node->language = $language->language; | |
| 177 | } | |
| 178 | } | |
| 179 | } | |
| 180 | ||
| 98e35ee4 | 181 | /** |
| 818652bd JR |
182 | * Implementation of hook_alter_translation_link(). |
| 183 | * | |
| 98f49db3 | 184 | * Handles links for extended language. The links will have current language. |
| 818652bd JR |
185 | */ |
| 186 | function i18n_translation_link_alter(&$links, $path) { | |
| 187 | global $language; | |
| 136d636d | 188 | |
| 818652bd JR |
189 | // Check for a node related path, and for its translations. |
| 190 | if ((preg_match("!^node/([0-9]+)(/.+|)$!", $path, $matches)) && ($node = node_load((int)$matches[1])) && !empty($node->tnid)) { | |
| 1d40cadd | 191 | // make sure language support is set to LANGUAGE_SUPPORT_EXTENDED, so links |
| 5196f381 JR |
192 | // dont get added for LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED |
| 193 | if (variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL) == LANGUAGE_SUPPORT_EXTENDED) { | |
| 194 | $languages = language_list(); | |
| 195 | $extended = array(); | |
| 196 | foreach (translation_node_get_translations($node->tnid) as $langcode => $translation_node) { | |
| 197 | if (!isset($links[$langcode]) && isset($languages[$langcode])) { | |
| 198 | $extended[$langcode] = array( | |
| 199 | 'href' => 'node/'. $translation_node->nid . $matches[2], | |
| 200 | 'language' => $language, | |
| 201 | 'language_icon' => $languages[$langcode], | |
| 202 | 'title' => $languages[$langcode]->native, | |
| 203 | 'attributes' => array('class' => 'language-link'), | |
| 204 | ); | |
| 205 | } | |
| 818652bd | 206 | } |
| 5196f381 JR |
207 | // This will run after languageicon module, so we add icon in case that one is enabled. |
| 208 | if ($extended && function_exists('languageicons_translation_link_alter')) { | |
| 209 | languageicons_translation_link_alter($extended, $path); | |
| 210 | } | |
| 211 | $links = array_merge($links, $extended); | |
| 818652bd | 212 | } |
| 818652bd JR |
213 | } |
| 214 | } | |
| 215 | ||
| 216 | /** | |
| 217 | * Implementation of hook_link_alter(). | |
| 218 | * | |
| 98f49db3 | 219 | * Handles links for extended languages. Sets current interface language. |
| 818652bd JR |
220 | */ |
| 221 | function i18n_link_alter(&$links, $node) { | |
| 222 | global $language; | |
| 136d636d | 223 | |
| 5196f381 JR |
224 | $language_support = variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL); |
| 225 | ||
| 226 | // Hide node translation links. | |
| 227 | if (variable_get('i18n_hide_translation_links', 0) == 1) { | |
| 228 | foreach ($links as $module => $link) { | |
| 229 | if (strpos($module, 'node_translation') === 0) { | |
| 230 | unset($links[$module]); | |
| 231 | } | |
| 232 | } | |
| 233 | } | |
| 234 | ||
| 1e456352 | 235 | if (!empty($node->tnid)) { |
| 818652bd | 236 | foreach (array_keys(i18n_language_list('extended')) as $langcode) { |
| 98f49db3 | 237 | $index = 'node_translation_'. $langcode; |
| 818652bd | 238 | if (!empty($links[$index])) { |
| 5196f381 JR |
239 | if ($language_support != LANGUAGE_SUPPORT_EXTENDED && $links[$index]['language']->enabled == 0) { |
| 240 | unset($links[$index]); | |
| 241 | } | |
| 242 | else { | |
| 243 | $links[$index]['language'] = $language; | |
| 244 | } | |
| 818652bd JR |
245 | } |
| 246 | } | |
| 247 | } | |
| 248 | } | |
| 249 | ||
| 250 | /** | |
| 98f49db3 | 251 | * Implementation of hook_user(). |
| 136d636d | 252 | * |
| 98f49db3 | 253 | * Switch to user's language after login. |
| afcc0a25 JR |
254 | */ |
| 255 | function i18n_user($op, &$edit, &$account, $category = NULL) { | |
| 98f49db3 | 256 | if ($op == 'login' && $account->language) { |
| afcc0a25 JR |
257 | $_SESSION['language'] = $account->language; |
| 258 | i18n_get_lang($account->language); | |
| 98e35ee4 | 259 | } |
| 74c2972e JR |
260 | } |
| 261 | ||
| 262 | /** | |
| ac152d40 NR |
263 | * Implementation of hook_elements(). |
| 264 | * | |
| 265 | * Add a process callback for textfields. | |
| 266 | */ | |
| 267 | function i18n_elements() { | |
| 268 | $type = array(); | |
| 269 | $type['textfield'] = array('#process' => array('i18n_textfield_process')); | |
| 270 | return $type; | |
| 271 | } | |
| 272 | ||
| 273 | /** | |
| 274 | * Process callback for textfield elements. | |
| 275 | * | |
| 276 | * When editing or translating a node, set Javascript to rewrite autocomplete | |
| 277 | * paths to use the node language prefix rather than the current content one. | |
| 278 | */ | |
| 279 | function i18n_textfield_process($element) { | |
| 280 | global $language; | |
| 281 | static $sent = FALSE; | |
| 282 | ||
| 283 | // Ensure we send the Javascript only once. | |
| 284 | if (!$sent && isset($element['#autocomplete_path']) && !empty($element['#autocomplete_path']) && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) { | |
| 285 | // Add a JS file for node forms. | |
| 286 | // Determine if we are either editing or translating an existing node. | |
| 287 | // We can't act on regular node creation because we don't have a specified | |
| 288 | // node language. | |
| 289 | $node_edit = $node = menu_get_object() && arg(2) == 'edit' && isset($node->language) && !empty($node->language); | |
| 290 | $node_translate = arg(0) == 'node' && arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language']); | |
| 291 | if ($node_edit || $node_translate) { | |
| 292 | $node_language = $node_edit ? $node->language : $_GET['language']; | |
| 293 | // Only needed if the node language is different from the interface one. | |
| 2d823751 | 294 | if ($node_language != $language->language) { |
| ac152d40 NR |
295 | $languages = language_list(); |
| 296 | if (isset($languages[$node_language])) { | |
| 297 | drupal_add_js(drupal_get_path('module', 'i18n') . '/i18n.js'); | |
| 298 | // Pass the interface and content language base paths. | |
| 299 | // Remove any trailing forward slash. Doing so prevents a mismatch | |
| 300 | // that occurs when a language has no prefix and hence gets a path | |
| 301 | // with a trailing forward slash. | |
| 302 | $interface = rtrim(url('', array('absolute' => TRUE)), '/'); | |
| 303 | $content = rtrim(url('', array('absolute' => TRUE, 'language' => $languages[$node_language])), '/'); | |
| 304 | $data = array('interface_path' => $interface, 'content_path' => $content); | |
| 305 | drupal_add_js(array('i18n' => $data), 'setting'); | |
| 306 | } | |
| 307 | } | |
| 308 | } | |
| 309 | $sent = TRUE; | |
| 310 | } | |
| 311 | return $element; | |
| 312 | } | |
| 313 | ||
| 314 | /** | |
| 81f2a50c | 315 | * Simple i18n API |
| 78e8cd8d | 316 | */ |
| 6681618a | 317 | |
| 98e35ee4 | 318 | /** |
| 98f49db3 | 319 | * Get language properties. |
| 136d636d | 320 | * |
| 98e35ee4 | 321 | * @param $code |
| 98f49db3 | 322 | * Language code. |
| 98e35ee4 JR |
323 | * @param $property |
| 324 | * It may be 'name', 'native', 'ltr'... | |
| 325 | */ | |
| 818652bd JR |
326 | function i18n_language_property($code, $property) { |
| 327 | $languages = language_list(); | |
| 16ae3caa | 328 | return isset($languages[$code]->$property) ? $languages[$code]->$property : NULL; |
| 98e35ee4 JR |
329 | } |
| 330 | ||
| 331 | /** | |
| 98f49db3 | 332 | * Get node language. |
| 90d529a0 | 333 | */ |
| 90d529a0 | 334 | function i18n_node_get_lang($nid, $default = '') { |
| 98f49db3 | 335 | $lang = db_result(db_query('SELECT language FROM {node} WHERE nid = %d', $nid)); |
| 90d529a0 JR |
336 | return $lang ? $lang : $default ; |
| 337 | } | |
| 338 | ||
| 339 | /** | |
| 98f49db3 | 340 | * Get allowed languages for node. |
| 136d636d | 341 | * |
| 98f49db3 | 342 | * This allows node types to define its own language list implementing hook 'language_list'. |
| 136d636d | 343 | * |
| 818652bd | 344 | * @param $node |
| 98f49db3 | 345 | * Node to retrieve language list for. |
| 818652bd | 346 | * @param $translate |
| 98f49db3 | 347 | * Only languages available for translation. Filter out existing translations. |
| 818652bd JR |
348 | */ |
| 349 | function i18n_node_language_list($node, $translate = FALSE) { | |
| 98f49db3 | 350 | // Check if the node module manages its own language list. |
| 818652bd | 351 | $languages = node_invoke($node, 'language_list', $translate); |
| 0173ca0a | 352 | |
| 818652bd | 353 | if (!$languages) { |
| 0698d0c8 | 354 | if (variable_get('i18n_node_'. $node->type, 0) >= LANGUAGE_SUPPORT_EXTENDED) { |
| 818652bd | 355 | $languages = locale_language_list('name', TRUE); // All defined languages |
| 98f49db3 | 356 | } |
| 357 | else { | |
| 818652bd JR |
358 | $languages = locale_language_list(); // All enabled languages |
| 359 | } | |
| 360 | if ($translate && isset($node->tnid) && $node->tnid && ($translations = translation_node_get_translations($node->tnid))) { | |
| 361 | unset($translations[$node->language]); | |
| 362 | foreach (array_keys($translations) as $langcode) { | |
| 363 | unset($languages[$langcode]); | |
| 364 | } | |
| 365 | } | |
| 3314df44 JR |
366 | // Language may be locked for this node type, restrict options to current one |
| 367 | if (variable_get('i18n_lock_node_' . $node->type, 0) && !empty($node->language) && !empty($languages[$node->language])) { | |
| 368 | $languages = array($node->language => $languages[$node->language]); | |
| 369 | } | |
| 370 | // Check language required for this type (no language neutral) | |
| 371 | elseif (!variable_get('i18n_required_node_' . $node->type, 0)) { | |
| 372 | $languages = array('' => t('Language neutral')) + $languages; | |
| 0173ca0a | 373 | } |
| afcc0a25 | 374 | } |
| 818652bd JR |
375 | |
| 376 | return $languages; | |
| 90d529a0 JR |
377 | } |
| 378 | ||
| 379 | /** | |
| ee361f1b | 380 | * Selection mode for content. |
| 136d636d | 381 | * |
| 98f49db3 | 382 | * Warning: when used with params they need to be escaped, as some values are thrown directly in queries. |
| 136d636d | 383 | * |
| 98f49db3 | 384 | * Allows several modes for query rewriting and to change them programatically. |
| 385 | * off = No language conditions inserted. | |
| 386 | * simple = Only current language and no language. | |
| 387 | * mixed = Only current and default languages. | |
| 388 | * strict = Only current language. | |
| 389 | * default = Only default language. | |
| 390 | * user = User defined, in the module's settings page. | |
| 391 | * params = Gets the stored params. | |
| 392 | * reset = Returns to previous. | |
| 393 | * custom = add custom where clause, like "%alias.language = 'en'". | |
| 394 | */ | |
| 395 | function i18n_selection_mode($mode = NULL, $params = NULL) { | |
| f8f1d8cf | 396 | static $current_mode; |
| 8dcb741b JR |
397 | static $current_value = ''; |
| 398 | static $store = array(); | |
| 136d636d | 399 | |
| f8f1d8cf JR |
400 | // Initialization, first time this runs |
| 401 | if (!isset($current_mode)) { | |
| ee361f1b | 402 | $current_mode = variable_get('i18n_selection_mode', 'simple'); |
| ee361f1b | 403 | } |
| 136d636d | 404 | |
| 98f49db3 | 405 | if (!$mode) { |
| 8dcb741b | 406 | return $current_mode; |
| 98f49db3 | 407 | } |
| 408 | elseif ($mode == 'params') { | |
| 8dcb741b | 409 | return $current_value; |
| 98f49db3 | 410 | } |
| 411 | elseif ($mode == 'reset') { | |
| 8dcb741b | 412 | list($current_mode, $current_value) = array_pop($store); |
| 98f49db3 | 413 | } |
| 414 | else { | |
| 8dcb741b JR |
415 | array_push($store, array($current_mode, $current_value)); |
| 416 | $current_mode = $mode; | |
| 417 | $current_value = $params; | |
| 136d636d | 418 | } |
| 81f2a50c | 419 | } |
| 74c2972e JR |
420 | |
| 421 | /** | |
| 98f49db3 | 422 | * Implementation of hook_db_rewrite_sql(). |
| 136d636d | 423 | * |
| 98f49db3 | 424 | * Rewrite node queries so language selection options are enforced. |
| 74c2972e | 425 | */ |
| 98f49db3 | 426 | function i18n_db_rewrite_sql($query, $primary_table, $primary_key, $args = array()) { |
| 427 | // If mode is 'off' = no rewrite, we cannot return any empty 'where' string so check here. | |
| 88d92733 JR |
428 | $mode = i18n_selection_mode(); |
| 429 | if ($mode == 'off') return; | |
| 136d636d | 430 | |
| 98f49db3 | 431 | // Disable language conditions for views. |
| 432 | if (array_key_exists('view', $args)) return; | |
| a1bb6aa6 | 433 | |
| 74c2972e JR |
434 | switch ($primary_table) { |
| 435 | case 'n': | |
| 436 | case 'node': | |
| 98f49db3 | 437 | // No rewrite for queries with subselect ? (views count queries). |
| 438 | // @ TO DO Actually these queries look un-rewrittable, check with other developers. | |
| 5aaad3de | 439 | if (preg_match("/FROM \(SELECT/", $query)) return; |
| 98f49db3 | 440 | // No rewrite for translation module queries. |
| 818652bd | 441 | if (preg_match("/.*FROM {node} $primary_table WHERE.*$primary_table\.tnid/", $query)) return; |
| 98f49db3 | 442 | // When loading specific nodes, language conditions shouldn't apply. |
| afcc0a25 | 443 | if (preg_match("/WHERE.*\s$primary_table.nid\s*=\s*(\d|%d)/", $query)) return; |
| 98f49db3 | 444 | // If language conditions already there, get out. |
| afcc0a25 | 445 | if (preg_match("/i18n/", $query)) return; |
| 136d636d | 446 | |
| 447 | ||
| 0ef28a15 | 448 | // Mixed mode is a bit more complex, we need to join in one more table |
| 98f49db3 | 449 | // and add some more conditions, but only if language is not default. |
| a838e19d | 450 | if ($mode == 'mixed') { |
| 0ef28a15 | 451 | $result['where'] = i18n_db_rewrite_where($primary_table, 'node', 'simple'); |
| a838e19d | 452 | if (i18n_get_lang() != i18n_default_language()) { |
| 6bdc58de | 453 | $result['join'] = "LEFT JOIN {node} i18n ON $primary_table.tnid > 0 AND $primary_table.tnid = i18n.tnid AND i18n.language = '". i18n_get_lang() ."'"; |
| a838e19d | 454 | // So we show also nodes that have default language. |
| 6bdc58de | 455 | $result['where'] .= " OR $primary_table.language = '". i18n_default_language() ."' AND i18n.nid IS NULL"; |
| a838e19d | 456 | } |
| 98f49db3 | 457 | } |
| 458 | else { | |
| 0ef28a15 JR |
459 | $result['where'] = i18n_db_rewrite_where($primary_table, 'node', $mode); |
| 460 | } | |
| afcc0a25 | 461 | return $result; |
| 74c2972e JR |
462 | } |
| 463 | } | |
| 464 | ||
| 98e35ee4 | 465 | /** |
| 98f49db3 | 466 | * Rewrites queries depending on rewriting mode. |
| 98e35ee4 | 467 | */ |
| 98f49db3 | 468 | function i18n_db_rewrite_where($alias, $type, $mode = NULL) { |
| afcc0a25 | 469 | if (!$mode) { |
| 98f49db3 | 470 | // Some exceptions for query rewrites. |
| afcc0a25 | 471 | $mode = i18n_selection_mode(); |
| 136d636d | 472 | } |
| 0ef28a15 | 473 | |
| 98f49db3 | 474 | // Get languages to simplify query building. |
| 0ef28a15 JR |
475 | $current = i18n_get_lang(); |
| 476 | $default = i18n_default_language(); | |
| 136d636d | 477 | |
| 88d92733 | 478 | if ($mode == 'strict' && $type != 'node') { |
| 98f49db3 | 479 | // Special case. Selection mode is 'strict' but this should be only for node queries. |
| 88d92733 | 480 | $mode = 'simple'; |
| 136d636d | 481 | } |
| 0ef28a15 | 482 | elseif ($mode == 'mixed' && $current == $default) { |
| 98f49db3 | 483 | // If mode is mixed but current = default, is the same as 'simple'. |
| 0ef28a15 JR |
484 | $mode = 'simple'; |
| 485 | } | |
| 136d636d | 486 | |
| 98f49db3 | 487 | switch ($mode) { |
| afcc0a25 JR |
488 | case 'off': |
| 489 | return ''; | |
| 98f49db3 | 490 | |
| 74c2972e | 491 | case 'simple': |
| 0ef28a15 | 492 | return "$alias.language ='$current' OR $alias.language ='' OR $alias.language IS NULL" ; |
| 98f49db3 | 493 | |
| 74c2972e | 494 | case 'mixed': |
| 0ef28a15 | 495 | return "$alias.language ='$current' OR $alias.language ='$default' OR $alias.language ='' OR $alias.language IS NULL" ; |
| 98f49db3 | 496 | |
| 74c2972e | 497 | case 'strict': |
| 0ef28a15 | 498 | return "$alias.language ='$current'" ; |
| 98f49db3 | 499 | |
| 74c2972e JR |
500 | case 'node': |
| 501 | case 'translation': | |
| 98f49db3 | 502 | return "$alias.language ='". i18n_selection_mode('params') ."' OR $alias.language ='' OR $alias.language IS NULL" ; |
| 503 | ||
| 74c2972e | 504 | case 'default': |
| 0ef28a15 | 505 | return "$alias.language ='$default' OR $alias.language ='' OR $alias.language IS NULL" ; |
| 98f49db3 | 506 | |
| 74c2972e | 507 | case 'custom': |
| afcc0a25 | 508 | return str_replace('%alias', $alias, i18n_selection_mode('params')); |
| 136d636d | 509 | } |
| 74c2972e JR |
510 | } |
| 511 | ||
| 512 | /** | |
| bbb1a8ec JR |
513 | * Implementation of hook_preprocess_page(). |
| 514 | * | |
| 515 | * Add the language code to the classes for the <body> tag. Unfortunately, some | |
| 516 | * themes will not respect the variable we're modifying to achieve this - in | |
| 517 | * particular, Garland and Minelli do not. | |
| 518 | */ | |
| 519 | function i18n_preprocess_page(&$variables) { | |
| 520 | if (isset($variables['body_classes'])) { | |
| 521 | global $language; | |
| 522 | $variables['body_classes'] .= ' i18n-' . $language->language; | |
| 523 | } | |
| 524 | } | |
| 525 | ||
| 526 | /** | |
| 98f49db3 | 527 | * Implementation of hook_exit(). |
| 74c2972e | 528 | */ |
| 98f49db3 | 529 | function i18n_exit() { |
| 38f996de | 530 | _i18n_variable_exit(); |
| 74c2972e JR |
531 | } |
| 532 | ||
| 533 | /** | |
| 818652bd | 534 | * Implementation of hook_form_alter(); |
| 136d636d | 535 | * |
| 98f49db3 | 536 | * This is the place to add language fields to all forms. |
| 74c2972e | 537 | */ |
| afcc0a25 | 538 | function i18n_form_alter(&$form, $form_state, $form_id) { |
| 3314df44 JR |
539 | global $language; |
| 540 | ||
| 98f49db3 | 541 | switch ($form_id) { |
| 542 | case 'node_type_form': | |
| 3314df44 JR |
543 | $disabled = !variable_get('language_content_type_'. $form['#node_type']->type, 0); |
| 544 | $form['i18n'] = array( | |
| 545 | '#type' => 'fieldset', | |
| 546 | '#title' => t('Multilanguage options'), | |
| 547 | '#collapsible' => TRUE, | |
| 548 | '#collapsed' => TRUE, | |
| 549 | '#description' => t('Extended multilingual options provided by Internationalization module.'), | |
| 550 | '#disabled' => $disabled, | |
| 551 | ); | |
| 552 | // Add disabled message | |
| 553 | if ($disabled) { | |
| 0173ca0a | 554 | $form['i18n']['#description'] .= ' <em>' . t('These will be available only when you enable Multilingual support in Workflow settings above.') . '</em>'; |
| 3314df44 JR |
555 | } |
| 556 | // Some settings about node languages | |
| 557 | $form['i18n']['options'] = array( | |
| 558 | '#title' => t('Options for node language'), | |
| 559 | '#type' => 'fieldset', | |
| 560 | '#disabled' => $disabled, | |
| 561 | ); | |
| 562 | $form['i18n']['options']['i18n_newnode_current'] = array( | |
| 563 | '#type' => 'checkbox', | |
| 564 | '#title' => t('Set current language as default for new content.'), | |
| 565 | '#default_value' => variable_get('i18n_newnode_current_' . $form['#node_type']->type, 0), | |
| 566 | '#disabled' => $disabled, | |
| 567 | ); | |
| 568 | $form['i18n']['options']['i18n_required_node'] = array( | |
| 569 | '#type' => 'checkbox', | |
| 570 | '#title' => t('Require language (Do not allow Language Neutral).'), | |
| 571 | '#default_value' => variable_get('i18n_required_node_' . $form['#node_type']->type, 0), | |
| 572 | '#disabled' => $disabled, | |
| 573 | ); | |
| 574 | $form['i18n']['options']['i18n_lock_node'] = array( | |
| 575 | '#type' => 'checkbox', | |
| 576 | '#title' => t('Lock language (Cannot be changed).'), | |
| 577 | '#default_value' => variable_get('i18n_lock_node_' . $form['#node_type']->type, 0), | |
| 578 | '#disabled' => $disabled, | |
| 579 | ); | |
| 98f49db3 | 580 | // Add extended language support option to content type form. |
| 3314df44 | 581 | $form['i18n']['i18n_node'] = array( |
| 98f49db3 | 582 | '#type' => 'radios', |
| 583 | '#title' => t('Extended language support'), | |
| 584 | '#default_value' => variable_get('i18n_node_'. $form['#node_type']->type, LANGUAGE_SUPPORT_NORMAL), | |
| 585 | '#options' => _i18n_content_language_options(), | |
| 3314df44 JR |
586 | '#description' => t('If enabled, all defined languages will be allowed for this content type in addition to only enabled ones. This is useful to have more languages for content than for the interface.'), |
| 587 | '#disabled' => $disabled, | |
| 98f49db3 | 588 | ); |
| 589 | break; | |
| afcc0a25 | 590 | |
| 74c2972e | 591 | default: |
| a1887ef3 | 592 | // Extensions for node edit forms |
| 818652bd | 593 | if (isset($form['#id']) && $form['#id'] == 'node-form') { |
| a1887ef3 | 594 | if (isset($form['#node']->type)) { |
| 3314df44 JR |
595 | if (variable_get('language_content_type_'. $form['#node']->type, 0)) { |
| 596 | if (!empty($form['language']['#options'])) { | |
| 597 | $form['language']['#options'] = i18n_node_language_list($form['#node'], TRUE); | |
| 598 | } | |
| 98f49db3 | 599 | } |
| 3314df44 JR |
600 | elseif (!isset($form['#node']->nid)) { |
| 601 | // Set language to empty for not multilingual nodes when creating | |
| 602 | $form['language'] = array('#type' => 'value', '#value' => ''); | |
| 74c2972e | 603 | } |
| 74c2972e | 604 | } |
| 74c2972e | 605 | } |
| a1887ef3 | 606 | |
| 98f49db3 | 607 | // Multilingual variables in settings form. |
| afcc0a25 | 608 | if (isset($form['#theme']) && $form['#theme'] == 'system_settings_form' && $variables = variable_get('i18n_variables', 0)) { |
| 66f2307e | 609 | if ($i18n_variables = i18n_form_alter_settings($form, $variables)) { |
| 27bba143 | 610 | array_unshift($form['#submit'], 'i18n_variable_form_submit'); |
| 66f2307e | 611 | $form['#i18n_variables'] = $i18n_variables; |
| 98e35ee4 JR |
612 | } |
| 613 | } | |
| 136d636d | 614 | } |
| 74c2972e JR |
615 | } |
| 616 | ||
| 617 | /** | |
| afcc0a25 | 618 | * Implementation of hook_perm(). |
| 136d636d | 619 | * |
| afcc0a25 JR |
620 | * Permissions defined |
| 621 | * - administer all languages | |
| 622 | * Disables language conditions for administration pages, so the user can view objects for all languages at the same time. | |
| 623 | * This applies for: menu items, taxonomy | |
| 1d40cadd JR |
624 | * - administer translations |
| 625 | * Will allow to add/remove existing nodes to/from translation sets. | |
| afcc0a25 JR |
626 | */ |
| 627 | function i18n_perm() { | |
| 1d40cadd JR |
628 | return array('administer all languages', 'administer translations'); |
| 629 | } | |
| 630 | ||
| 631 | /** | |
| 4c4a8511 | 632 | * Implementation of hook_theme(). |
| 1d40cadd JR |
633 | */ |
| 634 | function i18n_theme() { | |
| 635 | return array( | |
| 636 | 'i18n_node_select_translation' => array( | |
| 637 | 'arguments' => array('element' => NULL), | |
| 638 | 'file' => 'i18n.pages.inc', | |
| 639 | ), | |
| 640 | ); | |
| afcc0a25 | 641 | } |
| 98f49db3 | 642 | |
| afcc0a25 JR |
643 | /** |
| 644 | * Process menu and menu item add/edit form submissions. | |
| 645 | */ | |
| affdb36b JR |
646 | function i18n_menu_edit_item_form_submit($form, &$form_state) { |
| 647 | $mid = menu_edit_item_save($form_state['values']); | |
| 648 | db_query("UPDATE {menu} SET language = '%s' WHERE mid = %d", $form_state['values']['language'], $mid); | |
| afcc0a25 JR |
649 | return 'admin/build/menu'; |
| 650 | } | |
| 651 | ||
| 652 | /** | |
| 98f49db3 | 653 | * Check for multilingual variables in form. |
| 98e35ee4 JR |
654 | */ |
| 655 | function i18n_form_alter_settings(&$form, &$variables) { | |
| 6ca1272a | 656 | $result = array(); |
| afcc0a25 | 657 | foreach (element_children($form) as $field) { |
| 6ca1272a | 658 | if (count(element_children($form[$field])) && empty($form[$field]['#tree'])) { |
| 98e35ee4 JR |
659 | $result += i18n_form_alter_settings($form[$field], $variables); |
| 660 | } | |
| 661 | elseif (in_array($field, $variables)) { | |
| 66f2307e JR |
662 | // Add form field class: i18n-variable |
| 663 | $form[$field]['#attributes']['class'] = !empty($form[$field]['#attributes']['class']) ? $form[$field]['#attributes']['class'] . ' i18n-variable' : 'i18n-variable'; | |
| 664 | $form[$field]['#description'] = !empty($form[$field]['#description']) ? $form[$field]['#description'] : ''; | |
| 98f49db3 | 665 | $form[$field]['#description'] .= ' <strong>'. t('This is a multilingual variable.') .'</strong>'; |
| 66f2307e JR |
666 | // Addd field => name to result |
| 667 | $result[$field] = !empty($form[$field]['#title']) ? $form[$field]['#title'] : $field; | |
| 98e35ee4 JR |
668 | } |
| 669 | } | |
| 670 | return $result; | |
| 671 | } | |
| 672 | ||
| 673 | /** | |
| 98f49db3 | 674 | * Save multilingual variables and remove them from form. |
| 98e35ee4 | 675 | */ |
| afcc0a25 | 676 | function i18n_variable_form_submit($form, &$form_state) { |
| affdb36b | 677 | $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : ''; |
| 98e35ee4 JR |
678 | $variables = variable_get('i18n_variables', array()); |
| 679 | $language = i18n_get_lang(); | |
| 27bba143 | 680 | |
| affdb36b | 681 | foreach ($form_state['values'] as $key => $value) { |
| afcc0a25 | 682 | if (in_array($key, $variables)) { |
| 98e35ee4 JR |
683 | if ($op == t('Reset to defaults')) { |
| 684 | i18n_variable_del($key, $language); | |
| 685 | } | |
| 686 | else { | |
| affdb36b | 687 | if (is_array($value) && isset($form_state['values']['array_filter'])) { |
| 98e35ee4 | 688 | $value = array_keys(array_filter($value)); |
| 74c2972e | 689 | } |
| 98e35ee4 | 690 | i18n_variable_set($key, $value, $language); |
| 74c2972e | 691 | } |
| affdb36b | 692 | unset($form_state['values'][$key]); |
| 136d636d | 693 | } |
| 98e35ee4 JR |
694 | } |
| 695 | // Re-submit form | |
| afcc0a25 | 696 | // system_settings_form_submit($form_id, $form_values); |
| 98e35ee4 JR |
697 | } |
| 698 | ||
| 699 | /** | |
| 98f49db3 | 700 | * Initialization of multilingual variables. |
| 136d636d | 701 | * |
| afcc0a25 | 702 | * @param $language |
| 98f49db3 | 703 | * Language to retrieve variables. Defaults to current language. |
| 27bba143 JR |
704 | * @param $i18n_variables |
| 705 | * Optional variable list to initialize | |
| 38f996de | 706 | */ |
| 27bba143 | 707 | function i18n_variable_init($langcode = NULL, $i18n_variables = NULL) { |
| 38f996de JR |
708 | global $conf; |
| 709 | global $i18n_conf; | |
| 136d636d | 710 | |
| b28c2734 | 711 | $langcode = $langcode ? $langcode : i18n_get_lang(); |
| 27bba143 JR |
712 | $i18n_variables = $i18n_variables ? $i18n_variables : variable_get('i18n_variables', ''); |
| 713 | ||
| 714 | if ($i18n_variables) { | |
| 715 | $i18n_add = array(); | |
| afcc0a25 JR |
716 | if (!$i18n_conf) { |
| 717 | $i18n_conf = array(); | |
| 718 | } | |
| 27bba143 | 719 | $variables = _i18n_variable_init($langcode); |
| 98f49db3 | 720 | foreach ($i18n_variables as $name) { |
| 27bba143 | 721 | $i18n_add[$name] = isset($variables[$name]) ? $variables[$name] : (isset($conf[$name]) ? $conf[$name] : NULL); |
| 38f996de | 722 | } |
| b28c2734 | 723 | |
| 27bba143 JR |
724 | $conf = array_merge($conf, $i18n_add); |
| 725 | $i18n_conf = array_merge($i18n_conf, $i18n_add); | |
| 38f996de JR |
726 | } |
| 727 | } | |
| 728 | ||
| 74c2972e | 729 | /** |
| 4c4a8511 | 730 | * Get language from context. |
| 57f0a2c1 JR |
731 | */ |
| 732 | function _i18n_get_context_lang() { | |
| 733 | // Node language when loading specific nodes or creating translations. | |
| 734 | if (arg(0) == 'node' ) { | |
| 735 | if (($node = menu_get_object('node')) && $node->language) { | |
| 736 | return $node->language; | |
| 737 | } | |
| 738 | elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) { | |
| 739 | return $_GET['language']; | |
| 740 | } | |
| 741 | } | |
| 742 | } | |
| 743 | ||
| 744 | /** | |
| 98f49db3 | 745 | * Helper function to create language selector. |
| 74c2972e | 746 | */ |
| 98f49db3 | 747 | function _i18n_language_select($value ='', $description ='', $weight = -20, $languages = NULL) { |
| 818652bd | 748 | $languages = $languages ? $languages : locale_language_list(); |
| 74c2972e | 749 | return array( |
| 98f49db3 | 750 | '#type' => 'select', |
| 751 | '#title' => t('Language'), | |
| 752 | '#default_value' => $value, | |
| 753 | '#options' => array_merge(array('' => ''), $languages), | |
| 754 | '#description' => $description, | |
| 755 | '#weight' => $weight, | |
| 74c2972e JR |
756 | ); |
| 757 | } | |
| 758 | ||
| afcc0a25 | 759 | /** |
| 98f49db3 | 760 | * Load language variables into array. |
| afcc0a25 | 761 | */ |
| 27bba143 | 762 | function _i18n_variable_init($langcode) { |
| f8f1d8cf | 763 | static $variables; |
| 27bba143 JR |
764 | |
| 765 | if (!isset($variables[$langcode])) { | |
| 766 | $cacheid = 'variables:'. $langcode; | |
| f8f1d8cf | 767 | if ($cached = cache_get($cacheid)) { |
| 27bba143 | 768 | $variables[$langcode] = $cached->data; |
| f8f1d8cf JR |
769 | } |
| 770 | else { | |
| 27bba143 JR |
771 | $result = db_query("SELECT * FROM {i18n_variable} WHERE language = '%s'", $langcode); |
| 772 | $variables[$langcode] = array(); | |
| f8f1d8cf | 773 | while ($variable = db_fetch_object($result)) { |
| 27bba143 | 774 | $variables[$langcode][$variable->name] = unserialize($variable->value); |
| f8f1d8cf | 775 | } |
| 27bba143 | 776 | cache_set($cacheid, $variables[$langcode]); |
| 74c2972e | 777 | } |
| 74c2972e | 778 | } |
| 27bba143 JR |
779 | |
| 780 | return $variables[$langcode]; | |
| 74c2972e JR |
781 | } |
| 782 | ||
| 38f996de | 783 | /** |
| 98f49db3 | 784 | * Save multilingual variables that may have been changed by other methods than settings pages. |
| 38f996de | 785 | */ |
| 98f49db3 | 786 | function _i18n_variable_exit() { |
| 74c2972e JR |
787 | global $i18n_conf; |
| 788 | global $conf; | |
| 98f49db3 | 789 | if ($i18n_conf) { |
| afcc0a25 | 790 | $lang = i18n_get_lang(); |
| 74c2972e | 791 | $refresh = FALSE; |
| 98f49db3 | 792 | // Rewritten because array_diff_assoc may fail with array variables. |
| 793 | foreach ($i18n_conf as $name => $value) { | |
| ed3081d0 | 794 | if (isset($conf[$name]) && $value != $conf[$name]) { |
| 74c2972e JR |
795 | $refresh = TRUE; |
| 796 | $i18n_conf[$name] = $conf[$name]; | |
| ed3081d0 | 797 | db_query("DELETE FROM {i18n_variable} WHERE name='%s' AND language='%s'", $name, $lang); |
| 74c2972e JR |
798 | db_query("INSERT INTO {i18n_variable} (language, name, value) VALUES('%s', '%s', '%s')", $lang, $name, serialize($conf[$name])); |
| 799 | } | |
| 800 | } | |
| 98f49db3 | 801 | if ($refresh) { |
| 802 | cache_set('variables:'. $lang, $i18n_conf); | |
| 74c2972e JR |
803 | } |
| 804 | } | |
| 7027e3b5 | 805 | } |
| afcc0a25 JR |
806 | |
| 807 | /** | |
| 4c4a8511 | 808 | * Check whether we are in bootstrap mode. |
| 136d636d | 809 | */ |
| 98f49db3 | 810 | function _i18n_is_bootstrap() { |
| afcc0a25 | 811 | return !function_exists('drupal_get_headers'); |
| 136d636d | 812 | } |
| afcc0a25 JR |
813 | |
| 814 | /** | |
| 4c4a8511 MD |
815 | * Drupal 6, backwards compatibility layer. |
| 816 | * | |
| afcc0a25 JR |
817 | * @ TO DO Fully upgrade all the modules and remove |
| 818 | */ | |
| 818652bd | 819 | |
| afcc0a25 JR |
820 | /** |
| 821 | * This one expects to be called first from common.inc | |
| 822 | */ | |
| 818652bd | 823 | function i18n_get_lang() { |
| afcc0a25 | 824 | global $language; |
| afcc0a25 JR |
825 | return $language->language; |
| 826 | } | |
| 827 | ||
| 5aaad3de | 828 | /** |
| 818652bd JR |
829 | * @defgroup i18n_api Extended language API |
| 830 | * @{ | |
| 831 | * This is an extended language API to be used by modules in i18n package. | |
| afcc0a25 | 832 | */ |
| 818652bd JR |
833 | |
| 834 | /** | |
| 4c4a8511 | 835 | * Returns language lists. |
| 818652bd JR |
836 | */ |
| 837 | function i18n_language_list($type = 'enabled', $field = 'name') { | |
| 838 | switch ($type) { | |
| 839 | case 'enabled': | |
| 840 | return locale_language_list($field); | |
| 98f49db3 | 841 | |
| 818652bd JR |
842 | case 'extended': |
| 843 | $enabled = locale_language_list($field); | |
| 844 | $defined = locale_language_list($field, TRUE); | |
| 845 | return array_diff_assoc($defined, $enabled); | |
| afcc0a25 | 846 | } |
| 818652bd | 847 | } |
| 5aaad3de | 848 | |
| 818652bd | 849 | /** |
| 98f49db3 | 850 | * Returns default language code. |
| 818652bd | 851 | */ |
| 98f49db3 | 852 | function i18n_default_language() { |
| 136d636d | 853 | return language_default('language'); |
| afcc0a25 JR |
854 | } |
| 855 | ||
| 856 | /** | |
| 98f49db3 | 857 | * Get list of supported languages, native name. |
| 136d636d | 858 | * |
| afcc0a25 | 859 | * @param $all |
| 98f49db3 | 860 | * TRUE to get all defined languages. |
| afcc0a25 JR |
861 | */ |
| 862 | function i18n_supported_languages($all = FALSE) { | |
| 818652bd | 863 | return locale_language_list('native', $all); |
| afcc0a25 JR |
864 | } |
| 865 | ||
| 866 | /** | |
| afcc0a25 JR |
867 | * Set a persistent language dependent variable. |
| 868 | * | |
| 869 | * @param $name | |
| 870 | * The name of the variable to set. | |
| 871 | * @param $value | |
| 872 | * The value to set. This can be any PHP data type; these functions take care | |
| 873 | * of serialization as necessary. | |
| 874 | * @param $langcode | |
| 98f49db3 | 875 | * Language code. |
| afcc0a25 JR |
876 | */ |
| 877 | function i18n_variable_set($name, $value, $langcode) { | |
| 878 | global $conf, $i18n_conf; | |
| 879 | ||
| 6a513f8b JR |
880 | $serialized_value = serialize($value); |
| 881 | db_query("UPDATE {i18n_variable} SET value = '%s' WHERE name = '%s' AND language = '%s'", $serialized_value, $name, $langcode); | |
| 882 | if (!db_affected_rows()) { | |
| 883 | @db_query("INSERT INTO {i18n_variable} (name, language, value) VALUES ('%s', '%s', '%s')", $name, $langcode, $serialized_value); | |
| 884 | } | |
| afcc0a25 | 885 | |
| 98f49db3 | 886 | cache_clear_all('variables:'. $langcode, 'cache'); |
| afcc0a25 JR |
887 | |
| 888 | $conf[$name] = $value; | |
| 889 | $i18n_conf[$name] = $value; | |
| 890 | } | |
| 891 | ||
| 892 | /** | |
| 27bba143 JR |
893 | * Get single multilingual variable |
| 894 | */ | |
| 895 | function i18n_variable_get($name, $langcode, $default = NULL) { | |
| 896 | if ($variables = _i18n_variable_init($langcode)) { | |
| 897 | return isset($variables[$name]) ? $variables[$name] : $default; | |
| 898 | } | |
| 899 | else { | |
| 900 | return $default; | |
| 901 | } | |
| 902 | } | |
| 903 | ||
| 904 | /** | |
| afcc0a25 JR |
905 | * Unset a persistent multilingual variable. |
| 906 | * | |
| 907 | * @param $name | |
| 908 | * The name of the variable to undefine. | |
| 909 | * @param $langcode | |
| 98f49db3 | 910 | * Language code. |
| afcc0a25 JR |
911 | */ |
| 912 | function i18n_variable_del($name, $langcode) { | |
| 913 | global $conf, $i18n_conf; | |
| 914 | ||
| 915 | db_query("DELETE FROM {i18n_variable} WHERE name = '%s' AND language='%s'", $name, $langcode); | |
| 98f49db3 | 916 | cache_clear_all('variables:'. $langcode, 'cache'); |
| afcc0a25 JR |
917 | |
| 918 | unset($conf[$name]); | |
| 919 | unset($i18n_conf[$name]); | |
| 920 | } | |
| 921 | ||
| 922 | /** | |
| 98f49db3 | 923 | * Utility. Get part of array variable. |
| afcc0a25 JR |
924 | */ |
| 925 | function i18n_array_variable_get($name, $element, $default = NULL) { | |
| 926 | if (($values = variable_get($name, array())) && isset($values[$element])) { | |
| 927 | return $values[$element]; | |
| 98f49db3 | 928 | } |
| 929 | else { | |
| afcc0a25 | 930 | return $default; |
| 136d636d | 931 | } |
| afcc0a25 JR |
932 | } |
| 933 | ||
| 934 | /** | |
| 98f49db3 | 935 | * Utility. Set part of array variable. |
| afcc0a25 JR |
936 | */ |
| 937 | function i18n_array_variable_set($name, $element, $value) { | |
| 938 | $values = variable_get($name, array()); | |
| 939 | $values[$element] = $value; | |
| 940 | variable_set($name, $values); | |
| 941 | } | |
| 942 | ||
| 943 | /** | |
| 944 | * @} End of "defgroup i18n_api". | |
| 945 | */ | |
| e562cb3d | 946 | |
| 98f49db3 | 947 | /** |
| 948 | * List of language support modes for content. | |
| 949 | */ | |
| e562cb3d JR |
950 | function _i18n_content_language_options() { |
| 951 | return array( | |
| 952 | LANGUAGE_SUPPORT_NORMAL => t('Normal - All enabled languages will be allowed.'), | |
| 5196f381 JR |
953 | LANGUAGE_SUPPORT_EXTENDED => t('Extended - All defined languages will be allowed.'), |
| 954 | LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED => t('Extended, but not displayed - All defined languages will be allowed for input, but not displayed in links.'), | |
| e562cb3d | 955 | ); |
| 5aaad3de | 956 | } |