summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Reyero2011-01-19 06:11:38 (GMT)
committer Jose Reyero2011-01-19 06:11:38 (GMT)
commitfbc239e60000bdd76a6e0c02fc530e872947cdc7 (patch)
tree0c1f56211af89e7cee8f8495c2c2a7ee73e3f606
parent19770ec4ec9338918576cdb7aa648f42d3929823 (diff)
Merging from https://github.com/josereyero/i18n
https://github.com/josereyero/i18n/commit/5da7bb06110e1458f32d3d1c0900b70979aab889
-rw-r--r--CHANGELOG.txt14
-rw-r--r--i18n.module269
-rw-r--r--i18n_block/i18n_block.js31
-rw-r--r--i18n_block/i18n_block.module43
-rw-r--r--i18n_menu/i18n_menu.module26
-rw-r--r--i18n_node/i18n_node.module66
-rw-r--r--i18n_string/i18n_string.admin.inc6
-rw-r--r--i18n_string/i18n_string.inc16
-rw-r--r--i18n_string/i18n_string.module36
-rw-r--r--i18n_sync/i18n_sync.module281
-rw-r--r--i18n_taxonomy/i18n_taxonomy.module79
-rw-r--r--i18n_taxonomy/i18n_taxonomy.pages.inc2
-rw-r--r--tests/i18n_blocks.test2
-rw-r--r--tests/i18n_test.info1
14 files changed, 394 insertions, 478 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index ba76017..303a24f 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,13 +1,5 @@
// $Id$
--6.x-1.6 to 6.x-1.7
--------------------
--- Fixed: Missing function i18n_taxonomy_translate_term_name(), by srobert72, #870366
--- Fixed: Parameter 1 to menu_nodeapi() expected to be a reference (php5.3), by setvik, #886700
--- Fixed: Multilingual variables cache being rebuilt every page load, by patrick2000, #905428
--- Improved variable api, added i18n_variable(), extended i18n_variable_del()
--- Improved variable settings, variables for default language are now set to main table
-
6.x-1.5 to 6.x-1.6
-----------------
- Fixed: issues with i18nvariables, do not check anymore i18n_variables on initialization, by Jose, #850708
@@ -15,9 +7,9 @@
- Fixed: PHP notices, by eMPee584, #769318
- Delete description on menu item delete, #844208 by plach
- Fixed: Node type help not translated, by NaX, #685788
-- Some improvements to i18nmenu API, by plach, #386372
-- Renamed theme_taxonomy_term_page() to theme_i18ntaxonomy_term_page() to avoid namespace conflicts
-- Added some taxonomy API functions: i18ntaxonomy_translate_term_name()....
+- Some improvements to i18n_menu API, by plach, #386372
+- Renamed theme_taxonomy_term_page() to theme_i18n_taxonomy_term_page() to avoid namespace conflicts
+- Added some taxonomy API functions: i18n_taxonomy_translate_term_name()....
- Fixed: Access denied to database query (LOCK TABLES) on i18n_variable_set(), #769260
- Reworked variable initialization to fix multiple issues (front page, etc), #826774
- Some changes to variables API, added new function: i18n_variable_get()
diff --git a/i18n.module b/i18n.module
index 2b27d3a..9bbc38e 100644
--- a/i18n.module
+++ b/i18n.module
@@ -13,32 +13,48 @@
* @author Jose A. Reyero, 2004
*/
-// Some constants. Language support modes for content
-define('LANGUAGE_SUPPORT_NONE', 0);
-define('LANGUAGE_SUPPORT_NORMAL', 1);
-define('LANGUAGE_SUPPORT_EXTENDED', 2);
-define('LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED', 3);
-
+// All multilingual options disabled
+define('I18N_LANGUAGE_DISABLED', 0);
// Language list will include all enabled languages
-define('I18N_LANGUAGE_ENABLED', 0);
+define('I18N_LANGUAGE_ENABLED', 1);
// Language list will include also disabled languages
-define('I18N_LANGUAGE_EXTENDED', 1);
+define('I18N_LANGUAGE_EXTENDED', 4);
+// Disabled languages will be hidden when possible
+define('I18N_LANGUAGE_HIDDEN', 8);
+// All defined languages will be allowed but hidden when possible
+define('I18N_LANGUAGE_EXTENDED_NOT_DISPLAYED', I18N_LANGUAGE_EXTENDED | I18N_LANGUAGE_HIDDEN);
+
+// No multilingual options
+define('I18N_MODE_NONE', 0);
+// Localizable object. Run through the localization system
+define('I18N_MODE_LOCALIZE', 1);
+// Predefined language for this object and all related ones.
+define('I18N_MODE_LANGUAGE', 2);
+// Multilingual objects, translatable but not localizable.
+define('I18N_MODE_TRANSLATE', 4);
/**
* Implements hook_boot()
- *
- * Initialize variables, that will be used to decide on site_frontpage
*/
function i18n_boot() {
// Just make sure the module is loaded for boot and the API is available.
}
/**
- * Get global language, make sure it is initialized
+ * Get global language object, make sure it is initialized
+ *
+ * @param $language
+ * Language code or language object to convert to valid language object
*/
function i18n_language($language = NULL) {
if ($language) {
- return $language;
+ if (is_object($language)) {
+ return $language;
+ }
+ else {
+ $list = language_list();
+ return isset($list[$language]) ? $list[$language] : i18n_language();
+ }
}
else {
if (empty($GLOBALS['language'])) {
@@ -54,8 +70,9 @@ function i18n_language($language = NULL) {
*
* @todo See about creating a permission for seeing disabled languages
*/
-function i18n_language_list($field = 'name') {
- return locale_language_list($field, I18N_LANGUAGE_EXTENDED & variable_get('i18n_language_list', I18N_LANGUAGE_ENABLED));
+function i18n_language_list($field = 'name', $mode = NULL) {
+ $mode = isset($mode) ? $mode : variable_get('i18n_language_list', I18N_LANGUAGE_ENABLED);
+ return locale_language_list($field, I18N_LANGUAGE_EXTENDED & $mode);
}
/**
@@ -87,48 +104,6 @@ function i18n_langcode($langcode = NULL) {
}
/**
- * Implements hook_init().
- *
- * Special fix for site_frontpage, that may have been used before the language variables are loaded.
- */
-/*
-function i18n_init() {
- // If not in bootstrap, variable init. Otherwise we are serving a cached page so we don't need anything else.
- if (!_i18n_is_bootstrap()) {
- _i18n_init_mode();
- }
-}
-*/
-
-/**
- * Initialize selection mode
- */
-function _i18n_init_mode() {
- if (i18n_selection_mode() != 'off') {
- // Node language when loading specific nodes or creating translations.
- if (arg(0) == 'node' ) {
- if (($node = menu_get_object('node')) && $node->language) {
- i18n_selection_mode('node', $node->language);
- }
- elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) {
- i18n_selection_mode('translation', db_escape_string($_GET['language']));
- }
- }
- elseif (arg(0) == 'admin') {
- // There are some exceptions for admin pages.
- if (arg(1) == 'content' && user_access('administer all languages')) {
- // No restrictions for administration pages.
- i18n_selection_mode('off');
- }
- elseif (arg(1) == 'build' && (arg(2) == 'menu-customize' || arg(2) == 'menu')) {
- // All nodes available when editing custom menu items.
- i18n_selection_mode('off');
- }
- }
- }
-}
-
-/**
* Implements hook_help().
*/
function i18n_help($path = 'admin/help#i18n', $arg) {
@@ -199,20 +174,19 @@ function i18n_modules_installed($modules) {
}
/**
- * Implements hook_user_login().
- *
- * Switch to user's language after login.
+ * Simple i18n API
*/
-function i18n_user_login(&$edit, &$account) {
- if ($account->language) {
- $_SESSION['language'] = $account->language;
- i18n_get_lang($account->language);
- }
-}
/**
- * Simple i18n API
+ * Switch select Mode on off if enabled
*/
+function i18n_select($value = NULL) {
+ static $mode;
+ if (isset($value)) {
+ $mode = $value;
+ }
+ return $mode;
+}
/**
* Get language properties.
@@ -228,148 +202,11 @@ function i18n_language_property($code, $property) {
}
/**
- * Selection mode for content.
- *
- * Warning: when used with params they need to be escaped, as some values are thrown directly in queries.
- *
- * Allows several modes for query rewriting and to change them programatically.
- * off = No language conditions inserted.
- * simple = Only current language and no language.
- * mixed = Only current and default languages.
- * strict = Only current language.
- * default = Only default language.
- * user = User defined, in the module's settings page.
- * params = Gets the stored params.
- * reset = Returns to previous.
- * custom = add custom where clause, like "%alias.language = 'en'".
- *
- * @param $reset
- * Whether to reset the internal cache for the selection mode.
- */
-function i18n_selection_mode($mode = NULL, $params = NULL, $reset = FALSE) {
- $current_mode = &drupal_static(__FUNCTION__ . '_mode', NULL, $reset);
- $current_mode = &drupal_static(__FUNCTION__ . '_value', '', $reset);
- $store = &drupal_static(__FUNCTION__ . '_store', '', $reset);
-
- // Initialization, first time this runs
- if (!isset($current_mode)) {
- $current_mode = variable_get('i18n_selection_mode', 'simple');
- }
-
- if (!$mode) {
- return $current_mode;
- }
- elseif ($mode == 'params') {
- return $current_value;
- }
- elseif ($mode == 'reset') {
- list($current_mode, $current_value) = array_pop($store);
- }
- else {
- array_push($store, array($current_mode, $current_value));
- $current_mode = $mode;
- $current_value = $params;
- }
-}
-
-/**
- * Rewrites queries depending on rewriting mode.
- *
- * @return DatabaseCondition
+ * Implements hook_preprocess_html().
*/
-function i18n_db_rewrite_where($alias, $type, $mode = NULL) {
- if (!$mode) {
- // Some exceptions for query rewrites.
- $mode = i18n_selection_mode();
- }
-
- // Get languages to simplify query building.
- $current = i18n_language()->language;
- $default = language_default('language');
-
- if ($mode == 'strict' && $type != 'node') {
- // Special case. Selection mode is 'strict' but this should be only for node queries.
- $mode = 'simple';
- }
- elseif ($mode == 'mixed' && $current == $default) {
- // If mode is mixed but current = default, is the same as 'simple'.
- $mode = 'simple';
- }
-
- switch ($mode) {
- case 'off':
- return '';
-
- case 'simple':
- return db_condition('OR')
- ->condition($alias . '.language', $current)
- ->condition($alias . '.language', '')
- ->condition($alias . '.language', NULL);
-
- case 'mixed':
- return db_condition('OR')
- ->condition($alias . '.language', $current)
- ->condition($alias . '.language', $default)
- ->condition($alias . '.language', '')
- ->condition($alias . '.language', NULL);
-
- case 'strict':
- return db_condition('AND')->condition($alias . '.language', $current);
-
- case 'node':
- case 'translation':
- return db_condition('OR')
- ->condition($alias . '.language', i18n_selection_mode('params'))
- ->condition($alias . '.language', '')
- ->condition($alias . '.language', NULL);
-
- case 'default':
- return db_condition('OR')
- ->condition($alias . '.language', $default)
- ->condition($alias . '.language', '')
- ->condition($alias . '.language', NULL);
-
- case 'custom':
- return str_replace('%alias', $alias, i18n_selection_mode('params'));
- }
-}
-
-/**
- * Implements hook_preprocess_page().
- *
- * Add the language code to the classes for the <body> tag. Unfortunately, some
- * themes will not respect the variable we're modifying to achieve this - in
- * particular, Garland and Minelli do not.
- */
-function i18n_preprocess_page(&$variables) {
- if (isset($variables['body_classes'])) {
- global $language;
- $variables['body_classes'] .= ' i18n-' . $language->language;
- }
-}
-
-
-/**
- * Implements hook_permission().
- *
- * Permissions defined
- * - administer all languages
- * Disables language conditions for administration pages, so the user can view objects for all languages at the same time.
- * This applies for: menu items, taxonomy
- * - administer translations
- * Will allow to add/remove existing nodes to/from translation sets.
- */
-function i18n_permission() {
- return array(
- 'administer all languages' => array(
- 'title' => t('Administer all languages'),
- 'description' => t('Administer all languages.'),
- ),
- 'administer translations' => array(
- 'title' => t('Administer translations'),
- 'description' => t('Administer translations.'),
- ),
- );
+function i18n_preprocess_html(&$variables) {
+ global $language;
+ $variables['classes_array'][] = 'i18n-' . $language->language;
}
/**
@@ -403,15 +240,15 @@ function i18n_string($name, $string, $options = array()) {
/**
* Get language from context.
+ *
+ * Depending on the page content we may need to use a different language for some operations.
*/
-function _i18n_get_context_lang() {
- // Node language when loading specific nodes or creating translations.
- if (arg(0) == 'node' ) {
- if (($node = menu_get_object('node')) && $node->language) {
- return $node->language;
- }
- elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['language'])) {
- return $_GET['language'];
+function i18n_context_language() {
+ // Get language from the first module that provides it
+ foreach (module_implements('i18n_context_language') as $module) {
+ if ($language = module_invoke($module, 'i18n_context_language')) {
+ return $language;
}
}
-}
+ return i18n_language();
+} \ No newline at end of file
diff --git a/i18n_block/i18n_block.js b/i18n_block/i18n_block.js
new file mode 100644
index 0000000..9fced10
--- /dev/null
+++ b/i18n_block/i18n_block.js
@@ -0,0 +1,31 @@
+// $Id$
+
+(function ($) {
+
+/**
+ * Provide the summary information for the block settings vertical tab.
+ */
+Drupal.behaviors.i18nSettingsSummary = {
+ attach: function (context) {
+
+ $('fieldset#edit-languages', context).drupalSetSummary(function (context) {
+ var summary = '';
+ if ($('.form-item-i18n-mode input[type=checkbox]:checked', context).val()) {
+ summary += Drupal.t('Translatable');
+ }
+ else {
+ summary += Drupal.t('Not translatable');
+ }
+ summary += ', ';
+ if ($('.form-item-languages input[type=checkbox]:checked', context).val()) {
+ summary += Drupal.t('Restricted to certain languages');
+ }
+ else {
+ summary += Drupal.t('Not restricted');
+ }
+ return summary;
+ });
+ }
+};
+
+})(jQuery);
diff --git a/i18n_block/i18n_block.module b/i18n_block/i18n_block.module
index 368a988..fd629ee 100644
--- a/i18n_block/i18n_block.module
+++ b/i18n_block/i18n_block.module
@@ -10,13 +10,6 @@
* @ TODO Add strings on block update.
*/
-// Tag for localizable block, cannot be any language.
-define('I18N_BLOCK_LOCALIZE', '__LOCALIZE__');
-// Block type: localizable
-define('I18N_BLOCK_LOCALIZABLE', 1);
-// Block type: block with language
-define('I18N_BLOCK_LANGUAGE', 0);
-
/**
* Implements hook_block_list_alter().
*
@@ -172,10 +165,6 @@ function i18n_block_form_block_add_block_form_alter(&$form, &$form_state, $form_
* Remove block title for multilingual blocks.
*/
function i18n_block_form_block_admin_configure_alter(&$form, &$form_state, $form_id) {
- $default_options = db_query("SELECT language FROM {i18n_block_language} WHERE module = :module AND delta = :delta", array(
- ':module' => $form['module']['#value'],
- ':delta' => $form['delta']['#value'],
- ))->fetchCol();
$form['i18n_block']['languages'] = array(
'#type' => 'fieldset',
'#title' => t('Languages'),
@@ -183,23 +172,31 @@ function i18n_block_form_block_admin_configure_alter(&$form, &$form_state, $form
'#collapsed' => TRUE,
'#group' => 'visibility',
'#weight' => 5,
+ '#attached' => array(
+ 'js' => array(drupal_get_path('module', 'i18n_block') . '/i18n_block.js'),
+ ),
+ );
+
+ // Add translatable option, just title for module blocks, title and content for custom blocks.
+ $block = block_load($form['module']['#value'], $form['delta']['#value']);
+ $form['i18n_block']['languages']['i18n_mode'] = array(
+ '#type' => 'checkbox',
+ '#title' => $form['module']['#value'] == 'block' ? t("Make this block's title and content translatable.") : t("Make this block's title translatable."),
+ '#default_value' => (int) @$block->i18n_mode,
+ '#access' => module_exists('i18n_string'),
);
+
+ // Add option to select which language pages to show on.
+ $default_options = db_query("SELECT language FROM {i18n_block_language} WHERE module = :module AND delta = :delta", array(
+ ':module' => $form['module']['#value'],
+ ':delta' => $form['delta']['#value'],
+ ))->fetchCol();
$form['i18n_block']['languages']['languages'] = array(
'#type' => 'checkboxes',
- '#title' => t('Show block for specific languages'),
+ '#title' => t('Only show this block for these languages'),
'#default_value' => $default_options,
'#options' => i18n_language_list(),
- '#description' => t('Show this block only on pages for the given language(s). If you select no language, there will be no language-specific limitation.'),
- );
- // Add translatable option, just title for module blocks, title and content for custom blocks.
- $block = block_load($form['module']['#value'], $form['delta']['#value']);
- $form['i18n_block']['languages']['i18n_mode'] = array(
- '#type' => 'radios',
- '#title' => t('Block translation'),
- '#default_value' => $block->i18n_mode,
- '#options' => array(t('Disabled'), t('Enabled')),
- '#description' => $form['module']['#value'] == 'block' ? t('Make this block title and content translatable.') : t('Make this block title translatable.'),
- '#disabled' => !module_exists('i18n_string'),
+ '#description' => t('If no language is selected, block will show regardless of language.'),
);
$form['#submit'][] = 'i18n_block_form_block_admin_configure_submit';
}
diff --git a/i18n_menu/i18n_menu.module b/i18n_menu/i18n_menu.module
index 8f79c48..9cb022c 100644
--- a/i18n_menu/i18n_menu.module
+++ b/i18n_menu/i18n_menu.module
@@ -188,9 +188,9 @@ function i18n_menu_help($path, $arg) {
*/
function i18n_menu_translated_tree($menu_name, $reset = FALSE) {
$menu_output = &drupal_static(__FUNCTION__);
- if (!isset($menu_output[$menu_name]) || $reset) {
+ if (!isset($menu_output[$menu_name]) || $reset) {
$tree = menu_tree_page_data($menu_name);
- i18n_menu_localize_tree($tree);
+ $tree = i18n_menu_localize_tree($tree);
$menu_output[$menu_name] = menu_tree_output($tree);
}
return $menu_output[$menu_name];
@@ -199,16 +199,15 @@ function i18n_menu_translated_tree($menu_name, $reset = FALSE) {
/**
* Localize menu tree.
*/
-function i18n_menu_localize_tree(&$tree) {
- global $language;
-
- foreach ($tree as $index => $item) {
+function i18n_menu_localize_tree($tree, $langcode = NULL) {
+ $langcode = i18n_langcode($langcode);
+ foreach ($tree as $index => &$item) {
$link = $item['link'];
if ($link['customized'] && !empty($link['access']) && empty($link['hidden']) && empty($link['i18n_menu'])) {
// Remove links for other languages than current.
// Links with language wont be localized.
- if (!empty($link['options']['langcode'])) {
- if ($link['options']['langcode'] != $language->language) {
+ if (!empty($link['language'])) {
+ if ($link['language'] != $langcode) {
unset($tree[$index]);
}
}
@@ -216,18 +215,19 @@ function i18n_menu_localize_tree(&$tree) {
$router = i18n_menu_get_router($link['router_path']);
// If the title is the same it will be localized by the menu system.
if ($link['link_title'] != $router['title']) {
- $tree[$index]['link']['title'] = _i18n_menu_link_title($link);
+ $item['link']['title'] = _i18n_menu_link_title($link, $langcode);
}
- if ($description = _i18n_menu_link_description($link)) {
- $tree[$index]['link']['localized_options']['attributes']['title'] = $description;
+ if ($description = _i18n_menu_link_description($link, $langcode)) {
+ $item['link']['localized_options']['attributes']['title'] = $description;
}
// Localize subtree.
if ($item['below'] !== FALSE) {
- i18n_menu_localize_tree($tree[$index]['below'], $update);
+ $item['below'] = i18n_menu_localize_tree($item['below'], $langcode);
}
}
}
}
+ return $tree;
}
/**
@@ -254,7 +254,7 @@ function i18n_menu_menu_navigation_links($menu_name, $level = 0) {
// Get the menu hierarchy for the current page.
$tree = menu_tree_page_data($menu_name);
- i18n_menu_localize_tree($tree);
+ $tree = i18n_menu_localize_tree($tree);
// Go down the active trail until the right level is reached.
while ($level-- > 0 && $tree) {
diff --git a/i18n_node/i18n_node.module b/i18n_node/i18n_node.module
index 1059be7..d2eafa6 100644
--- a/i18n_node/i18n_node.module
+++ b/i18n_node/i18n_node.module
@@ -101,6 +101,21 @@ function i18n_node_help($path, $arg) {
}
/**
+ * Implements hook_i18n_context_language()
+ */
+function i18n_node_i18n_context_language() {
+ // Node language when loading specific nodes or creating translations.
+ if (arg(0) == 'node' ) {
+ if (($node = menu_get_object('node')) && !empty($node->language)) {
+ return i18n_language($node->language);
+ }
+ elseif (arg(1) == 'add' && !empty($_GET['translation']) && !empty($_GET['target'])) {
+ return i18n_language($_GET['target']);
+ }
+ }
+}
+
+/**
* Implements hook_i18n_string_info()
*/
function i18n_node_i18n_string_info() {
@@ -179,12 +194,7 @@ function i18n_node_language_list($node, $translate = FALSE) {
$languages = node_invoke($node, 'language_list', $translate);
if (!$languages) {
- if (variable_get('i18n_node_'. $node->type, 0) >= LANGUAGE_SUPPORT_EXTENDED) {
- $languages = locale_language_list('name', TRUE); // All defined languages
- }
- else {
- $languages = locale_language_list(); // All enabled languages
- }
+ $languages = i18n_language_list('name', i18n_node_language_mode($node));
if ($translate && isset($node->tnid) && $node->tnid && ($translations = translation_node_get_translations($node->tnid))) {
unset($translations[$node->language]);
foreach (array_keys($translations) as $langcode) {
@@ -204,6 +214,13 @@ function i18n_node_language_list($node, $translate = FALSE) {
return $languages;
}
+/**
+ * Get language mode for node or node type
+ */
+function i18n_node_language_mode($type) {
+ $type = is_object($type) ? $type->type : $type;
+ return variable_get('i18n_node_'. $type, I18N_LANGUAGE_ENABLED);
+}
/**
* Implements hook_node_prepare().
@@ -218,6 +235,25 @@ function i18n_node_nodeapi($node) {
}
/**
+ * Implements hook_permission().
+ *
+ * Permissions defined
+ * - administer all languages
+ * Disables language conditions for administration pages, so the user can view objects for all languages at the same time.
+ * This applies for: menu items, taxonomy
+ * - administer translations
+ * Will allow to add/remove existing nodes to/from translation sets.
+ */
+function i18n_node_permission() {
+ return array(
+ 'administer content translations' => array(
+ 'title' => t('Administer content translations'),
+ 'description' => t('Add or remove existing content to translation sets.'),
+ ),
+ );
+}
+
+/**
* Implements hook_alter_translation_link().
*
* Handles links for extended language. The links will have current language.
@@ -229,9 +265,9 @@ function i18n_node_translation_link_alter(&$links, $path) {
// Check for a node related path, and for its translations.
if ((preg_match("!^node/([0-9]+)(/.+|)$!", $path, $matches)) && ($node = node_load((int)$matches[1])) && !empty($node->tnid)) {
- // make sure language support is set to LANGUAGE_SUPPORT_EXTENDED, so links
- // dont get added for LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED
- if (variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL) == LANGUAGE_SUPPORT_EXTENDED) {
+ // make sure language support is set to I18N_LANGUAGE_EXTENDED, so links
+ // dont get added for I18N_LANGUAGE_EXTENDED_NOT_DISPLAYED
+ if (!(i18n_node_languabe_mode($node->type) & I18N_LANGUAGE_HIDDEN)) {
$languages = language_list();
$extended = array();
foreach (translation_node_get_translations($node->tnid) as $langcode => $translation_node) {
@@ -265,7 +301,7 @@ function i18n_node_translation_link_alter(&$links, $path) {
function i18n_node_link_alter(&$links, $node) {
global $language;
- $language_support = variable_get('i18n_node_'. $node->type, LANGUAGE_SUPPORT_NORMAL);
+ $language_support = i18n_node_language_mode($node);
// Hide node translation links.
if (variable_get('i18n_hide_translation_links', 0) == 1) {
@@ -280,7 +316,7 @@ function i18n_node_link_alter(&$links, $node) {
foreach (i18n_node_language_list($node) as $langcode) {
$index = 'node_translation_'. $langcode;
if (!empty($links[$index])) {
- if ($language_support != LANGUAGE_SUPPORT_EXTENDED && $links[$index]['language']->enabled == 0) {
+ if (!($language_support & I18N_LANGUAGE_EXTENDED) && $links[$index]['language']->enabled == 0) {
unset($links[$index]);
}
else {
@@ -449,7 +485,7 @@ function i18n_node_form_node_type_form_alter(&$form, &$form_state) {
$form['i18n']['i18n_node'] = array(
'#type' => 'radios',
'#title' => t('Extended language support'),
- '#default_value' => variable_get('i18n_node_'. $form['#node_type']->type, LANGUAGE_SUPPORT_NORMAL),
+ '#default_value' => i18n_node_language_mode($form['#node_type']->type),
'#options' => _i18n_node_language_options(),
'#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.'),
'#disabled' => $disabled,
@@ -498,9 +534,9 @@ function i18n_node_theme() {
*/
function _i18n_node_language_options() {
return array(
- LANGUAGE_SUPPORT_NORMAL => t('Normal - All enabled languages will be allowed.'),
- LANGUAGE_SUPPORT_EXTENDED => t('Extended - All defined languages will be allowed.'),
- LANGUAGE_SUPPORT_EXTENDED_NOT_DISPLAYED => t('Extended, but not displayed - All defined languages will be allowed for input, but not displayed in links.'),
+ I18N_LANGUAGE_ENABLED => t('Normal - All enabled languages will be allowed.'),
+ I18N_LANGUAGE_EXTENDED => t('Extended - All defined languages will be allowed.'),
+ I18N_LANGUAGE_EXTENDED | I18N_LANGUAGE_HIDDEN => t('Extended, but not displayed - All defined languages will be allowed for input, but not displayed in links.'),
);
}
diff --git a/i18n_string/i18n_string.admin.inc b/i18n_string/i18n_string.admin.inc
index ccb421d..ba4a128 100644
--- a/i18n_string/i18n_string.admin.inc
+++ b/i18n_string/i18n_string.admin.inc
@@ -89,7 +89,7 @@ function i18n_string_admin_update($language, $groups) {
$count = 0;
foreach($result as $string) {
- // Just update strings when no input format, otherwise it could be dangerous under some circumstances.
+ // Just update strings when no text format, otherwise it could be dangerous under some circumstances.
if (empty($string->format) && !empty($string->translation)) {
$count++;
db_insert(locales_target)
@@ -117,11 +117,11 @@ function i18n_string_admin_settings() {
$format_list[$fid] = $format->name;
}
$form['i18n_string_allowed_formats'] = array(
- '#title' => t('Translatable input formats'),
+ '#title' => t('Translatable text formats'),
'#options' => $format_list,
'#type' => 'checkboxes',
'#default_value' => variable_get('i18n_string_allowed_formats', array(variable_get('filter_default_format', 1))),
- '#description' => t('Only the strings that have the input formats selected will be allowed by the translation system. All the others will be deleted next time the strings are refreshed.'),
+ '#description' => t('Only the strings that have the text formats selected will be allowed by the translation system. All the others will be deleted next time the strings are refreshed.'),
);
// Whitelist text groups without formatted strings for backwards compatibility
$textgroups = module_invoke_all('locale', 'groups');
diff --git a/i18n_string/i18n_string.inc b/i18n_string/i18n_string.inc
index e6cf38f..7bcfab5 100644
--- a/i18n_string/i18n_string.inc
+++ b/i18n_string/i18n_string.inc
@@ -52,10 +52,10 @@ class i18n_string_default {
return $string;
}
/**
- * Check if input format is allowed for translation
+ * Check if text format is allowed for translation
*
* @param $format
- * Input format key or NULL if not format (will be allowed)
+ * Text format key or NULL if not format (will be allowed)
*/
public static function allowed_format($format = NULL) {
$allowed_formats = variable_get('i18n_string_allowed_formats', array(variable_get('filter_default_format', 1)));
@@ -73,7 +73,7 @@ class i18n_string_default {
* @param $i18nstring
* String object
* @param $format
- * Input format, for strings that will go through some filter
+ * Text format, for strings that will go through some filter
* @return
* Update status.
*/
@@ -172,7 +172,7 @@ class i18n_string_default {
if (!empty($i18nstring->format) && !self::allowed_format($i18nstring->format)) {
// This format is not allowed, so we remove the string, in this case we produce a warning
$params = self::string_params($i18nstring);
- drupal_set_message(t('The string %location for textgroup %textgroup is not allowed for translation because of its input format.', $params), 'warning');
+ drupal_set_message(t('The string %location for textgroup %textgroup is not allowed for translation because of its text format.', $params), 'warning');
return FALSE;
}
else {
@@ -206,10 +206,10 @@ class i18n_string_default {
}
/**
- * Get translation from the database. Full object with input format.
+ * Get translation from the database. Full object with text format.
*
* This one doesn't return anything if we don't have the full i18n strings data there
- * to prevent missing data resulting in missing input formats
+ * to prevent missing data resulting in missing text formats
*/
protected function get_translation($i18nstring) {
// First, populate available data from the cache
@@ -478,7 +478,7 @@ class i18n_string_default {
* Source string in default language. Default language may or may not be English.
* @param $options
* Array with additional options:
- * - 'format', String format if the string has input format
+ * - 'format', String format if the string has text format
* - 'messages', Whether to print out status messages
*/
public function update($context, $string, $options = array()) {
@@ -514,7 +514,7 @@ class i18n_string_default {
* @pram $string
* New value of string for update/create. May be empty for removing.
* @param $format
- * Input format, that must have been checked against allowed formats for translation
+ * Text format, that must have been checked against allowed formats for translation
* @return status
* SAVED_UPDATED | SAVED_NEW | SAVED_DELETED
*/
diff --git a/i18n_string/i18n_string.module b/i18n_string/i18n_string.module
index d43a5fa..d44e26d 100644
--- a/i18n_string/i18n_string.module
+++ b/i18n_string/i18n_string.module
@@ -91,19 +91,19 @@ function i18n_string_help($path, $arg) {
$output .= '<li>' . t('Use the update option when some of the strings had been previously translated with the localization system, but the translations are not showing up for the configurable strings.') . '</li>';
$output .= '</ul>';
$output .= '<p>' . t('To search and translate strings, use the <a href="@translate-interface">translation interface</a> pages.', array('@translate-interface' => url('admin/config/regional/translate'))) . '</p>';
- $output .= '<p>' . t('<strong>Important:</strong> To configure which Input formats are safe for translation, visit the <a href="@configure-strings">configure strings</a> page before refreshing your strings.', array('@configure-strings' => url('admin/config/regional/i18n/strings'))) . '</p>';
+ $output .= '<p>' . t('<strong>Important:</strong> To configure which text formats are safe for translation, visit the <a href="@configure-strings">configure strings</a> page before refreshing your strings.', array('@configure-strings' => url('admin/config/regional/i18n/strings'))) . '</p>';
return $output;
case 'admin/config/language':
$output = '<p>' . t('<strong>Warning</strong>: Changing the default language may have unwanted effects on string translations. Read more about <a href="@i18n_string-help">String translation</a>', array('@i18n_string-help' => url('admin/help/i18n_string'))) . '</p>';
return $output;
case 'admin/config/regional/i18n/strings':
- $output = '<p>' . t('When translating user defined strings that have an Input format associated, translators will be able to edit the text before it is filtered which may be a security risk for some filters. An obvious example is when using the PHP filter but other filters may also be dangerous.') . '</p>';
- $output .= '<p>' . t('As a general rule <strong>do not allow any filtered text to be translated unless the translators already have access to that Input format</strong>. However if you are doing all your translations through this site\'s translation UI or the Localization client, and never importing translations for other textgroups than <i>default</i>, filter access will be checked for translators on every translation page.') . '</p>';
- $output .= '<p>' . t('<strong>Important:</strong> After disallowing some Input format, use the <a href="@refresh-strings">refresh strings</a> page so forbidden strings are deleted and not allowed anymore for translators.', array('@refresh-strings' => url('admin/build/translate/refresh'))) . '</p>';
+ $output = '<p>' . t('When translating user defined strings that have a text format associated, translators will be able to edit the text before it is filtered which may be a security risk for some filters. An obvious example is when using the PHP filter but other filters may also be dangerous.') . '</p>';
+ $output .= '<p>' . t('As a general rule <strong>do not allow any filtered text to be translated unless the translators already have access to that text format</strong>. However if you are doing all your translations through this site\'s translation UI or the Localization client, and never importing translations for other textgroups than <i>default</i>, filter access will be checked for translators on every translation page.') . '</p>';
+ $output .= '<p>' . t('<strong>Important:</strong> After disallowing some text format, use the <a href="@refresh-strings">refresh strings</a> page so forbidden strings are deleted and not allowed anymore for translators.', array('@refresh-strings' => url('admin/build/translate/refresh'))) . '</p>';
return $output;
case 'admin/config/filters':
- return '<p>' . t('After updating your Input formats do not forget to review the list of formats allowed for string translations on the <a href="@configure-strings">configure translatable strings</a> page.', array('@configure-strings' => url('admin/config/regional/i18n/strings'))) . '</p>';
+ return '<p>' . t('After updating your text formats do not forget to review the list of formats allowed for string translations on the <a href="@configure-strings">configure translatable strings</a> page.', array('@configure-strings' => url('admin/config/regional/i18n/strings'))) . '</p>';
}
}
@@ -174,17 +174,18 @@ function i18n_string_form_alter(&$form, &$form_state, $form_id) {
// Replace validate callback
$form['#validate'] = array('i18n_string_translate_edit_form_validate');
if ($context->format) {
- $format = filter_formats($context->format);
- $disabled = !filter_access($context->format);
+ $formats = filter_formats();
+ $format = $formats[$context->format];
+ $disabled = !filter_access($format);
if ($disabled) {
- drupal_set_message(t('This string uses the %name input format. You are not allowed to translate or edit texts with this format.', array('%name' => $format->name)), 'warning');
+ drupal_set_message(t('This string uses the %name text format. You are not allowed to translate or edit texts with this format.', array('%name' => $format->name)), 'warning');
}
foreach (element_children($form['translations']) as $langcode) {
$form['translations'][$langcode]['#disabled'] = $disabled;
}
$form['translations']['format_help'] = array(
'#type' => 'item',
- '#title' => t('Input format: @name', array('@name' => $format->name)),
+ '#title' => t('Text format: @name', array('@name' => $format->name)),
'#value' => theme('filter_tips', _filter_tips($context->format, FALSE))
);
$form['submit']['#disabled'] = $disabled;
@@ -207,13 +208,16 @@ function i18n_string_form_alter(&$form, &$form_state, $form_id) {
function i18n_string_translate_edit_form_validate($form, &$form_state) {
$context = $form_state['values']['i18n_string_context'];
if (empty($context->format)) {
- // If not input format use regular validation for all strings
+ // If not text format use regular validation for all strings
$copy_state = $form_state;
$copy_state['values']['textgroup'] = 'default';
locale_translate_edit_form_validate($form, $copy_state);
}
- elseif (!filter_access($context->format)) {
- form_set_error('translations', t('You are not allowed to translate or edit texts with this input format.'));
+ else {
+ $formats = filter_formats();
+ if (!filter_access($formats[$context->format])) {
+ form_set_error('translations', t('You are not allowed to translate or edit texts with this text format.'));
+ }
}
}
@@ -313,7 +317,7 @@ function i18n_string_update_object($context, $object, $properties = array()) {
* Array of key => string to update multiple strings at once
* @param $options
* Array with additional options:
- * - 'format', String format if the string has input format
+ * - 'format', String format if the string has text format
* - 'messages', Whether to print out status messages
*/
function i18n_string_update($name, $string, $options = array()) {
@@ -449,7 +453,7 @@ function i18n_string_modules_enabled($modules) {
/**
* Get translation for user defined string.
*
- * This function is intended to return translations for plain strings that have NO input format
+ * This function is intended to return translations for plain strings that have NO text format
*
* @param $name
* Textgroup and context glued with ':'
@@ -522,7 +526,7 @@ function i18n_string_format($i18nstring, $options = array()) {
/**
* Get filtered translation.
*
- * This function is intended to return translations for strings that have an input format
+ * This function is intended to return translations for strings that have an text format
*
* @param $name
* Full string id
@@ -627,7 +631,7 @@ function i18n_string_l10n_client_add($context, $options) {
l10_client_add_string_to_page(FALSE, $context->translation, $context->textgroup);
}
else {
- // Additional checking for input format, if its a dangerous one we ignore the string
+ // Additional checking for text format, if its a dangerous one we ignore the string
$source = i18n_string_get_source($context);
if (!empty($source) && (i18n_string_allowed_format($source->format) || filter_access($source->format))) {
l10_client_add_string_to_page($string, $translation, $context->textgroup);
diff --git a/i18n_sync/i18n_sync.module b/i18n_sync/i18n_sync.module
index cf5fdb1..4b83762 100644
--- a/i18n_sync/i18n_sync.module
+++ b/i18n_sync/i18n_sync.module
@@ -17,6 +17,20 @@
*/
/**
+ * Global switch to enable / disable syncing and check whether we are synching at the moment
+ *
+ * @return boolean
+ * TRUE if we need to run sync operations. FALSE during syncing so we don't have recursion.
+ */
+function i18n_sync($status = NULL) {
+ static $current = TRUE;
+ if (isset($status)) {
+ $current = $status;
+ }
+ return $status;
+}
+
+/**
* Implements hook_help().
*/
function i18n_sync_help($path, $arg) {
@@ -49,54 +63,66 @@ function i18n_sync_theme() {
}
/**
- * Implements hook_form_alter().
- * - Vocabulary options
- * - Content type options
+ * Implements hook_form_FORM_ID_alter().
*/
-function i18n_sync_form_alter(&$form, $form_state, $form_id) {
- // Taxonomy vocabulary form.
- switch ($form_id) {
- case 'node_type_form':
- $type = $form['#node_type']->type;
- $current = i18n_sync_node_fields($type);
- $disabled = $form['i18n']['#disabled'];
- $form['i18n']['i18n_sync_nodeapi'] = array(
- '#type' => 'fieldset',
- '#tree' => TRUE,
- '#title' => t('Synchronize translations'),
- '#collapsible' => TRUE,
- '#collapsed' => !count($current),
- '#description' => t('Select which fields to synchronize for all translations of this content type.'),
- '#disabled' => $disabled,
- );
- // Each set provides title and options. We build a big checkboxes control for it to be
- // saved as an array. Special themeing for group titles.
- foreach (i18n_sync_node_available_fields($type) as $group => $data) {
- $title = $data['#title'];
- if (!empty($data['#options'])) {
- foreach ($data['#options'] as $field => $name) {
- $form['i18n']['i18n_sync_nodeapi'][$field] = array(
- '#group_title' => $title,
- '#title' => $name,
- '#type' => 'checkbox',
- '#default_value' => in_array($field, $current),
- '#theme' => 'i18n_sync_workflow_checkbox',
- '#disabled' => $disabled,
- );
- $title = '';
- }
+function i18n_sync_form_node_admin_content_alter(&$form, &$form_state) {
+ if (!empty($form['operation']) && $form['operation']['#value'] == 'delete') {
+ $form['#submit'] = array_merge(array('i18n_sync_node_delete_submit'), $form['#submit']);
+ }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function i18n_sync_form_node_delete_confirm_alter(&$form, &$form_state) {
+ // Intercept form submission so we can handle uploads, replace callback
+ $form['#submit'] = array_merge(array('i18n_sync_node_delete_submit'), $form['#submit']);
+}
+
+
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function i18n_sync_form_node_type_form_alter(&$form, &$form_state) {
+ if (isset($form['type'])) {
+ $type = $form['#node_type']->type;
+ $disabled = !translation_supported_type($type);
+ $form['i18n_sync'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Synchronize translations'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#group' => 'additional_settings',
+ '#attributes' => array(
+ 'class' => array('i18n-node-type-settings-form'),
+ ),
+ '#description' => t('Select which fields to synchronize for all translations of this content type.'),
+ '#disabled' => $disabled,
+ );
+ $form['i18n_sync']['i18n_sync_node_type'] = array(
+ '#title' => t('Synchronize fields'),
+ '#type' => 'fieldset',
+ '#tree' => TRUE,
+ );
+ // Each set provides title and options. We build a big checkboxes control for it to be
+ // saved as an array. Special themeing for group titles.
+ foreach (i18n_sync_node_available_fields($type) as $group => $data) {
+ $title = $data['#title'];
+ if (!empty($data['#options'])) {
+ foreach ($data['#options'] as $field => $name) {
+ $form['i18n_sync']['i18n_sync_nodeapi'][$field] = array(
+ '#group_title' => $title,
+ '#title' => $name,
+ '#type' => 'checkbox',
+ '#default_value' => in_array($field, $current),
+ '#theme' => 'i18n_sync_workflow_checkbox',
+ '#disabled' => $disabled,
+ );
+ $title = '';
}
}
- break;
- case 'node_delete_confirm':
- // Intercept form submission so we can handle uploads, replace callback
- $form['#submit'] = array_merge(array('i18n_sync_node_delete_submit'), $form['#submit']);
- break;
- case 'node_admin_content':
- if (!empty($form['operation']) && $form['operation']['#value'] == 'delete') {
- $form['#submit'] = array_merge(array('i18n_sync_node_delete_submit'), $form['#submit']);
- }
- break;
+ }
}
}
@@ -146,97 +172,98 @@ function theme_i18n_sync_workflow_checkbox($element) {
}
/**
- * Implements hook_nodeapi().
+ * Check whether this node is to be synced
*/
-function i18n_sync_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
- global $i18n_sync; // This variable will be true when a sync operation is in progress.
-
- // Only for nodes that have language and belong to a translation set.
- if (translation_supported_type($node->type) && !empty($node->language) && !$i18n_sync) {
- switch ($op) {
- case 'load':
- // Add instance count for cck fields so we can use the information later, see hook_file_references()
- if (!empty($node->tnid) && ($sync_fields = i18n_sync_node_fields($node->type)) && ($content_fields = _i18n_sync_cck_fields($node->type))) {
- if ($translations = _i18n_sync_node_translations($node, TRUE)) {
- $count = count($translations);
- foreach ($sync_fields as $field) {
- if (isset($content_fields[$field]) && !empty($node->$field) && is_array($node->$field)) {
- // The node field should be an array with one or more fields
- // Reminder: Use brackets for $node->{$field}[$key] as $node->$field[$key] won't work
- foreach (array_keys($node->$field) as $key) {
- if (is_array($node->{$field}[$key])) {
- $node->{$field}[$key]['i18n_sync'] = $count;
- }
- }
- }
- }
- }
- }
- break;
+function i18n_sync_node_check($node) {
+ return translation_supported_type($node->type) && !empty($node->language) && i18n_sync();
+}
- case 'prepare translation':
- // We copy over all the fields to be synchronized.
- if ($fields = i18n_sync_node_fields($node->type)) {
- i18n_sync_prepare_translation($node, $node->translation_source, $fields);
- }
- break;
-
- case 'insert':
- // When creating a translation, there are some aditional steps, different from update
- if (!empty($node->translation_source)) {
- // Set tnid that is not set by translation module
- $node->tnid = $node->translation_source->tnid ? $node->translation_source->tnid : $node->translation_source->nid;
- // If we have files, we need to save the files that have been inherited
- if (!empty($node->files) && i18n_sync_node_fields($node->type, 'files')) {
- foreach ($node->files as $fid => $file) {
- $file = (object)$file;
- if (empty($file->remove) && empty($file->new)) {
- db_query("INSERT INTO {upload} (fid, nid, vid, list, description, weight) VALUES (%d, %d, %d, %d, '%s', %d)", $file->fid, $node->nid, $node->vid, $file->list, $file->description, $file->weight);
- }
+/**
+ * Implements hook_node_load().
+ */
+function i18n_sync_node_load($node) {
+ // Add instance count for cck fields so we can use the information later, see hook_file_references()
+ if (i18n_sync_node_check($node) && !empty($node->tnid) && ($sync_fields = i18n_sync_node_fields($node->type)) && ($content_fields = _i18n_sync_cck_fields($node->type))) {
+ if ($translations = _i18n_sync_node_translations($node, TRUE)) {
+ $count = count($translations);
+ foreach ($sync_fields as $field) {
+ if (isset($content_fields[$field]) && !empty($node->$field) && is_array($node->$field)) {
+ // The node field should be an array with one or more fields
+ // Reminder: Use brackets for $node->{$field}[$key] as $node->$field[$key] won't work
+ foreach (array_keys($node->$field) as $key) {
+ if (is_array($node->{$field}[$key])) {
+ $node->{$field}[$key]['i18n_sync'] = $count;
}
}
}
- // Intentional no break.
- case 'update':
- // Let's go with field synchronization.
- if (!empty($node->tnid) && ($fields = i18n_sync_node_fields($node->type)) && ($translations = _i18n_sync_node_translations($node, TRUE))) {
- $i18n_sync = TRUE;
- $count = 0;
- // If we have fields we need to reload them so we have the full data (fid, etc...)
- if (!empty($node->files) && in_array('files', $fields)) {
- $node->files = upload_load($node);
- }
- // Disable language selection temporarily, enable it again later
- i18n_selection_mode('off');
- foreach ($translations as $trnode) {
- if ($node->nid != $trnode->nid) {
- i18n_sync_node_translation($node, $trnode, $fields, $op);
- $count++;
- }
- }
- i18n_selection_mode('reset');
- $i18n_sync = FALSE;
- drupal_set_message(format_plural($count, 'One node translation has been synchronized.', 'All @count node translations have been synchronized.'));
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_node_insert().
+ */
+function i18n_sync_node_insert($node) {
+ // When creating a translation, there are some aditional steps, different from update
+ if (i18n_sync_node_check($node) && !empty($node->translation_source)) {
+ // Set tnid that is not set by translation module
+ $node->tnid = $node->translation_source->tnid ? $node->translation_source->tnid : $node->translation_source->nid;
+ // If we have files, we need to save the files that have been inherited
+ if (!empty($node->files) && i18n_sync_node_fields($node->type, 'files')) {
+ foreach ($node->files as $fid => $file) {
+ $file = (object)$file;
+ if (empty($file->remove) && empty($file->new)) {
+ db_query("INSERT INTO {upload} (fid, nid, vid, list, description, weight) VALUES (%d, %d, %d, %d, '%s', %d)", $file->fid, $node->nid, $node->vid, $file->list, $file->description, $file->weight);
}
- break;
+ }
}
- }
+ i18n_sync_node_update($node);
+ }
}
/**
- * Prepare node translation. Copy over sincronizable fields.
+ * Implements hook_node_update().
*/
-function i18n_sync_prepare_translation(&$node, $source, $field_list) {
- foreach ($field_list as $field) {
- if (empty($source->$field)) continue;
- switch ($field) {
- case 'taxonomy':
- // Do nothing, this is handled by the i18n_taxonomy module
- break;
-
- default:
- $node->$field = $source->$field;
- break;
+function i18n_sync_node_update($node) {
+ // Let's go with field synchronization.
+ if (i18n_sync_node_check($node) && !empty($node->tnid) && ($fields = i18n_sync_node_fields($node->type)) && ($translations = _i18n_sync_node_translations($node, TRUE))) {
+ i18n_sync(FALSE);
+ $count = 0;
+ // If we have fields we need to reload them so we have the full data (fid, etc...)
+ if (!empty($node->files) && in_array('files', $fields)) {
+ $node->files = upload_load($node);
+ }
+ // Disable language selection temporarily, enable it again later
+ i18n_select(FALSE);
+ foreach ($translations as $trnode) {
+ if ($node->nid != $trnode->nid) {
+ i18n_sync_node_translation($node, $trnode, $fields, $op);
+ $count++;
+ }
+ }
+ i18n_select(TRUE);
+ i18n_sync(TRUE);
+ drupal_set_message(format_plural($count, 'One node translation has been synchronized.', 'All @count node translations have been synchronized.'));
+ }
+}
+
+/**
+ * Implements hook_node_prepare().
+ */
+function i18n_sync_node_prepare($node) {
+ // If creating a translation, copy over all the fields to be synchronized.
+ if (empty($node->nid) && !empty($node->translation_source) && ($sync_fields = i18n_sync_node_fields($node->type))) {
+ foreach ($field_list as $field) {
+ if (empty($node->translation_source->$field)) continue;
+ switch ($field) {
+ case 'taxonomy':
+ // Do nothing, this is handled by the i18n_taxonomy module
+ break;
+ default:
+ $node->$field = $node->translation_source->$field;
+ break;
+ }
}
}
}
@@ -515,7 +542,7 @@ function i18n_sync_node_available_fields($type) {
'timezone' => t('Timezone')
);
}
-
+/*
// Get CCK fields.
if (($contentfields = _i18n_sync_cck_fields($type))) {
// Get context information.
@@ -525,7 +552,7 @@ function i18n_sync_node_available_fields($type) {
$fields['cck']['#options'][$data['field_name']] = $data['widget']['label'];
}
}
-
+*/
// Give a chance to modules to change/remove/add their own fields
drupal_alter('i18n_sync_fields', $fields, $type);
diff --git a/i18n_taxonomy/i18n_taxonomy.module b/i18n_taxonomy/i18n_taxonomy.module
index 875eac1..93f0525 100644
--- a/i18n_taxonomy/i18n_taxonomy.module
+++ b/i18n_taxonomy/i18n_taxonomy.module
@@ -17,18 +17,6 @@
*/
/**
- * Modes for multilingual vocabularies.
- */
-// No multilingual options
-define('I18N_TAXONOMY_NONE', 0);
-// Run through the localization system
-define('I18N_TAXONOMY_LOCALIZE', 1);
-// Predefined language for all terms
-define('I18N_TAXONOMY_LANGUAGE', 2);
-// Multilingual terms, translatable
-define('I18N_TAXONOMY_TRANSLATE', 3);
-
-/**
* Implements hook_help().
*/
function i18n_taxonomy_help($path, $arg) {
@@ -53,13 +41,13 @@ function i18n_taxonomy_help($path, $arg) {
case 'admin/content/taxonomy/%':
$vocabulary = taxonomy_vocabulary_load($arg[3]);
switch (i18n_taxonomy_vocabulary_mode($vocabulary->vid)) {
- case I18N_TAXONOMY_LOCALIZE:
+ case I18N_MODE_LOCALIZE:
return '<p>'. t('%capital_name is a localizable vocabulary. You will be able to translate term names and descriptions using the <a href="@translate-interface">translate interface</a> pages.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name, '@translate-interface' => url('admin/build/translate'))) .'</p>';
- case I18N_TAXONOMY_LANGUAGE:
+ case I18N_MODE_LANGUAGE:
return '<p>'. t('%capital_name is a vocabulary with a fixed language. All the terms in this vocabulary will have %language language.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name, '%language' => i18n_language_property($vocabulary->language, 'name'))) .'</p>';
- case I18N_TAXONOMY_TRANSLATE:
+ case I18N_MODE_TRANSLATE:
return '<p>'. t('%capital_name is a full multilingual vocabulary. You will be able to set a language for each term and create translation relationships.', array('%capital_name' => drupal_ucfirst($vocabulary->name))) .'</p>';
}
@@ -71,10 +59,10 @@ function i18n_taxonomy_help($path, $arg) {
*/
function _i18n_taxonomy_vocabulary_options() {
return array(
- I18N_TAXONOMY_NONE => t('None. No multilingual options for this vocabulary.'),
- I18N_TAXONOMY_LOCALIZE => t('Localize terms. Terms are common for all languages, but their name and description may be localized.'),
- I18N_TAXONOMY_TRANSLATE => t('Per language terms. Different terms will be allowed for each language and they can be translated.'),
- I18N_TAXONOMY_LANGUAGE => t('Set language to vocabulary. The vocabulary will have a global language and it will only show up for pages in that language.'),
+ I18N_MODE_NONE => t('None. No multilingual options for this vocabulary.'),
+ I18N_MODE_LOCALIZE => t('Localize terms. Terms are common for all languages, but their name and description may be localized.'),
+ I18N_MODE_TRANSLATE => t('Per language terms. Different terms will be allowed for each language and they can be translated.'),
+ I18N_MODE_LANGUAGE => t('Set language to vocabulary. The vocabulary will have a global language and it will only show up for pages in that language.'),
);
}
@@ -119,7 +107,7 @@ function i18n_taxonomy_menu_alter(&$items) {
* Menu access callback. Show tab only for full multilingual vocabularies.
*/
function _i18n_taxonomy_translation_tab($vocabulary) {
- return i18n_taxonomy_vocabulary_mode($vocabulary->vid) == I18N_TAXONOMY_TRANSLATE;
+ return i18n_taxonomy_vocabulary_mode($vocabulary->vid) & I18N_MODE_TRANSLATE;
}
/**
@@ -148,7 +136,7 @@ function i18n_taxonomy_i18n_string_refresh($group) {
i18n_string_update("taxonomy:vocabulary:$vid:description", $vocabulary->help);
}
}
- if (i18n_taxonomy_vocabulary_mode($vid) == I18N_TAXONOMY_LOCALIZE) {
+ if (i18n_taxonomy_vocabulary_mode($vid) & I18N_MODE_LOCALIZE) {
foreach (taxonomy_get_tree($vid, 0) as $term) {
i18n_string_update("taxonomy:term:$term->tid:name", $term->name);
if ($term->description) {
@@ -199,7 +187,7 @@ function i18n_taxonomy_theme() {
function i18n_taxonomy_translate_term_name($tid, $name = '', $langcode = NULL) {
// If it is a term object we check for vocabulary options
if (is_object($tid)) {
- return i18n_taxonomy_vocabulary_mode($tid->vid) == I18N_TAXONOMY_LOCALIZE ? i18n_string_plain("taxonomy:term:$tid->tid:name", $tid->name, $langcode, TRUE) : check_plain($tid->name);
+ return i18n_taxonomy_vocabulary_mode($tid->vid) & I18N_MODE_LOCALIZE ? i18n_string_plain("taxonomy:term:$tid->tid:name", $tid->name, $langcode, TRUE) : check_plain($tid->name);
}
else {
return i18n_string("taxonomy:term:$tid:name", $name, $langcode);
@@ -271,9 +259,12 @@ function i18n_taxonomy_taxonomy_term_insert($term) {
* Implements hook_taxonomy_term_update()
*/
function i18n_taxonomy_taxonomy_term_update($term) {
- if (i18n_taxonomy_vocabulary_mode($term->vid) == I18N_TAXONOMY_LOCALIZE) {
+ if (i18n_taxonomy_vocabulary_mode($term->vid) & I18N_MODE_LOCALIZE) {
i18n_string_update(array('taxonomy', 'term', $term->tid, 'name'), $term->name);
- i18n_string_update(array('taxonomy', 'term', $term->tid, 'description'), $term->description, array('format' => $term->format));
+ // Sometimes, like when tagging content we have no description.
+ if (isset($term->description)) {
+ i18n_string_update(array('taxonomy', 'term', $term->tid, 'description'), $term->description, array('format' => $term->format));
+ }
}
}
@@ -297,10 +288,10 @@ function i18n_taxonomy_taxonomy_vocabulary_insert($vocabulary) {
function i18n_taxonomy_taxonomy_vocabulary_udpate($vocabulary) {
// Update language for related terms
switch ($vocabulary->i18n_mode) {
- case I18N_TAXONOMY_LANGUAGE:
+ case I18N_MODE_LANGUAGE:
$update['language'] = $vocabulary->language;
break;
- case I18N_TAXONOMY_NONE:
+ case I18N_MODE_NONE:
$update['language'] = '';
break;
}
@@ -332,10 +323,10 @@ function i18n_taxonomy_taxonomy_vocabulary_delete($vocabulary) {
*/
function i18n_taxonomy_taxonomy_term_presave($term) {
switch (i18n_taxonomy_vocabulary_mode($term->vid)) {
- case I18N_TAXONOMY_LANGUAGE; // Predefined language for all terms
+ case I18N_MODE_LANGUAGE; // Predefined language for all terms
$term->language = taxonomy_vocabulary_load($term->vid)->language;
break;
- case I18N_TAXONOMY_TRANSLATE: // Multilingual terms, translatable
+ case I18N_MODE_TRANSLATE: // Multilingual terms, translatable
if (!isset($term->language)) {
// The term may come from a node tags field, just if this is not a taxonomy form
$term->language = i18n_langcode();
@@ -354,7 +345,7 @@ function i18n_taxonomy_taxonomy_term_presave($term) {
function i18n_taxonomy_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {
$vocabulary = $form_state['vocabulary'];
drupal_add_js(drupal_get_path('module', 'i18n_taxonomy') . '/i18n_taxonomy.js');
- drupal_add_js(array('i18n_taxonomy_vocabulary_form' => array('I18N_TAXONOMY_LANGUAGE' => I18N_TAXONOMY_LANGUAGE)), 'setting');
+ drupal_add_js(array('i18n_taxonomy_vocabulary_form' => array('I18N_MODE_LANGUAGE' => I18N_MODE_LANGUAGE)), 'setting');
$form['i18n'] = array(
'#type' => 'fieldset',
'#title' => t('Multilingual options'),
@@ -374,7 +365,7 @@ function i18n_taxonomy_form_taxonomy_form_vocabulary_alter(&$form, &$form_state)
'#default_value' => $vocabulary && !empty($vocabulary->language) ? $vocabulary->language : '',
'#options' => array('' => '') + i18n_language_list(),
'#description' => t('Language for this vocabulary. If set, it will apply to all terms in this vocabulary.'),
- '#disabled' => ($vocabulary && $vocabulary->i18n_mode != I18N_TAXONOMY_LANGUAGE),
+ '#disabled' => ($vocabulary && $vocabulary->i18n_mode != I18N_MODE_LANGUAGE),
);
$form['#validate'][] = 'i18n_taxonomy_form_vocabulary_validate';
}
@@ -394,7 +385,7 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
// Add language field or not depending on taxonomy mode.
switch (i18n_taxonomy_vocabulary_mode($vocabulary->vid)) {
- case I18N_TAXONOMY_TRANSLATE:
+ case I18N_MODE_TRANSLATE:
$form['language'] = array(
'#type' => 'select',
'#title' => t('Language'),
@@ -404,7 +395,7 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
);
break;
- case I18N_TAXONOMY_LANGUAGE:
+ case I18N_MODE_LANGUAGE:
$form['language'] = array(
'#type' => 'value',
'#value' => $vocabulary->language
@@ -412,7 +403,7 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
$form['identification']['language_info'] = array('#value' => t('All terms in this vocabulary have a fixed language: %language', array('%language' => i18n_language_property($vocabulary->language, 'name'))));
break;
- case I18N_TAXONOMY_LOCALIZE:
+ case I18N_MODE_LOCALIZE:
$form['language'] = array(
'#type' => 'value',
'#value' => ''
@@ -421,7 +412,7 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
i18n_string_element_mark($form['description']);
break;
- case I18N_TAXONOMY_NONE:
+ case I18N_MODE_NONE:
default:
$form['language'] = array(
'#type' => 'value',
@@ -450,7 +441,7 @@ function i18n_taxonomy_form_alter(&$form, $form_state, $form_id) {
break;
case 'taxonomy_overview_terms':
- if (i18n_taxonomy_vocabulary_mode($form['#vocabulary']->vid) == I18N_TAXONOMY_TRANSLATE) {
+ if (i18n_taxonomy_vocabulary_mode($form['#vocabulary']->vid) & I18N_MODE_TRANSLATE) {
foreach (element_children($form) as $key) {
if (isset($form[$key]['#term']) && ($lang = $form[$key]['#term']->language)) {
$form[$key]['view']['#value'] .= '&nbsp;('. i18n_language_name($lang) .')';
@@ -477,10 +468,10 @@ function i18n_taxonomy_form_alter(&$form, $form_state, $form_id) {
function i18n_taxonomy_form_vocabulary_validate($form, &$form_state) {
$language = !empty($form_state['values']['language']) ? $form_state['values']['language'] : '';
$mode = $form_state['values']['i18n_mode'];
- if ($mode != I18N_TAXONOMY_LANGUAGE && $language) {
+ if ($mode != I18N_MODE_LANGUAGE && $language) {
form_set_error('language', t('Setting a vocabulary language only makes sense in the "Set language to vocabulary" translation mode. Either change to this mode or do not select a language.'));
}
- elseif ($mode == I18N_TAXONOMY_LANGUAGE && !$language ) {
+ elseif ($mode == I18N_MODE_LANGUAGE && !$language ) {
form_set_error('language', t('If selecting "Set language to vocabulary" you need to set a language to this vocabulary. Either change the translation mode or select a language.'));
}
}
@@ -502,7 +493,7 @@ function i18n_taxonomy_form_all_localize(&$item) {
$options[$vname] = $options[$vocabulary->name];
unset($options[$vocabulary->name]);
}
- if (i18n_taxonomy_vocabulary_mode($vid) == I18N_TAXONOMY_LOCALIZE) {
+ if (i18n_taxonomy_vocabulary_mode($vid) & I18N_MODE_LOCALIZE) {
$tree = taxonomy_get_tree($vid);
if ($tree && (count($tree) > 0)) {
foreach ($tree as $term) {
@@ -537,16 +528,16 @@ function i18n_taxonomy_node_form(&$form) {
// Special treatment for tags, add some help texts
foreach (element_children($form['taxonomy']['tags']) as $vid) {
$type = i18n_taxonomy_vocabulary_mode($vid);
- if ($type == I18N_TAXONOMY_LOCALIZE || $type == I18N_TAXONOMY_TRANSLATE) {
+ if ($type == I18N_MODE_LOCALIZE || $type == I18N_MODE_TRANSLATE) {
$form['taxonomy']['tags'][$vid]['#title'] = i18n_taxonomy_translate_vocabulary_name($vid, $form['taxonomy']['tags'][$vid]['#title']);
$form['taxonomy']['tags'][$vid]['#description'] = i18n_string("taxonomy:vocabulary:$vid:help", $form['taxonomy']['tags'][$vid]['#description']);
}
- if ($type == I18N_TAXONOMY_LOCALIZE) {
+ if ($type == I18N_MODE_LOCALIZE) {
$form['taxonomy']['tags'][$vid]['#description'] .= ' '. t('This is a localizable vocabulary, so only terms in %language are allowed here.', array('%language' => language_default('name')));
}
}
}
- elseif (is_numeric($vid) && i18n_taxonomy_vocabulary_mode($vid) == I18N_TAXONOMY_LOCALIZE) {
+ elseif (is_numeric($vid) && i18n_taxonomy_vocabulary_mode($vid) == I18N_MODE_LOCALIZE) {
// Rebuild this vocabulary's form.
$vocabulary = taxonomy_vocabulary_load($vid);
// Extract terms belonging to the vocabulary in question.
@@ -561,7 +552,7 @@ function i18n_taxonomy_node_form(&$form) {
$form['taxonomy'][$vid]['#required'] = $vocabulary->required;
$form['taxonomy'][$vid]['#description'] = i18n_string("taxonomy:vocabulary:$vid:help", $vocabulary->help);
}
- elseif (is_numeric($vid) && i18n_taxonomy_vocabulary_mode($vid) == I18N_TAXONOMY_TRANSLATE) {
+ elseif (is_numeric($vid) && i18n_taxonomy_vocabulary_mode($vid) == I18N_MODE_TRANSLATE) {
// Rebuild this vocabulary's form.
$vocabulary = taxonomy_vocabulary_load($vid);
$form['taxonomy'][$vid]['#title'] = i18n_taxonomy_translate_vocabulary_name($vid, $vocabulary->name);
@@ -764,7 +755,7 @@ function i18n_taxonomy_translate_terms($taxonomy, $langcode, $fullterms = TRUE)
$mode = i18n_taxonomy_vocabulary_mode($index);
// We translate just some vocabularies: translatable, fixed language
// Fixed language ones may have terms translated, though the UI doesn't support it
- if ($mode == I18N_TAXONOMY_LANGUAGE || $mode == I18N_TAXONOMY_TRANSLATE) {
+ if ($mode == I18N_MODE_LANGUAGE || $mode == I18N_MODE_TRANSLATE) {
$translation[$index] = i18n_taxonomy_translate_terms($tdata, $langcode, $filter, $fullterms);
}
elseif ($fullterms) {
@@ -817,7 +808,7 @@ function i18n_taxonomy_translate_terms($taxonomy, $langcode, $fullterms = TRUE)
function i18n_taxonomy_localize_terms($terms, $fields = array('name')) {
$terms = is_array($terms) ? $terms : array($terms);
foreach ($terms as $index => $term) {
- if (i18n_taxonomy_vocabulary_mode($term->vid) === I18N_TAXONOMY_LOCALIZE) {
+ if (i18n_taxonomy_vocabulary_mode($term->vid) === I18N_MODE_LOCALIZE) {
foreach ($fields as $property) {
$term->$property = i18n_string(array('taxonomy', 'term', $term->tid, $property), $term->$property);
}
diff --git a/i18n_taxonomy/i18n_taxonomy.pages.inc b/i18n_taxonomy/i18n_taxonomy.pages.inc
index 7259720..6655928 100644
--- a/i18n_taxonomy/i18n_taxonomy.pages.inc
+++ b/i18n_taxonomy/i18n_taxonomy.pages.inc
@@ -79,7 +79,7 @@ function theme_i18n_taxonomy_term_page($tids, $result) {
// Only display the description if we have a single term, to avoid clutter and confusion.
if (count($tids) == 1) {
$term = taxonomy_get_term($tids[0]);
- if (i18n_taxonomy_vocabulary($term->vid) == I18N_TAXONOMY_LOCALIZE) {
+ if (i18n_taxonomy_vocabulary($term->vid) & I18N_MODE_LOCALIZE) {
$description = i18n_string("taxonomy:term:$term->tid:description", $term->description);
}
else {
diff --git a/tests/i18n_blocks.test b/tests/i18n_blocks.test
index 12265fd..c1de304 100644
--- a/tests/i18n_blocks.test
+++ b/tests/i18n_blocks.test
@@ -66,7 +66,7 @@ class i18n_Blocks_Test extends Drupali18nTestCase {
$this->assertTrue(i18n_string_get_source("blocks:user:1:title"), "We have a string for the Navigation block title");
$this->assertTrue(i18n_string_get_source("blocks:block:$box2->bid:title", $box2->title), "The string for the second box title is still there.");
$this->assertTrue(i18n_string_get_source("blocks:block:$box2->bid:body", $box2->body), "The string for the second box body is still there.");
- // Test a block with filtering and input formats
+ // Test a block with filtering and text formats
$box3 = $this->i18nCreateBox(array(
'title' => '<div><script>alert(0)</script>Title</script>',
'body' => "One line\nTwo lines<script>alert(1)</script>",
diff --git a/tests/i18n_test.info b/tests/i18n_test.info
index e63aee1..f1df76c 100644
--- a/tests/i18n_test.info
+++ b/tests/i18n_test.info
@@ -6,3 +6,4 @@ dependencies[] = translation
dependencies[] = i18n
package = Testing
core = 6.x
+hidden = TRUE