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