| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* @file
|
| 4 |
* i18n taxonomy module
|
| 5 |
*
|
| 6 |
* Internationalization (i18n) package
|
| 7 |
*
|
| 8 |
* This module groups together all existing i18n taxonomy functionality
|
| 9 |
* providing several options for taxonomy translation
|
| 10 |
*
|
| 11 |
* Translates taxonomy term for selected vocabularies running them through the localization system
|
| 12 |
* It also translates terms for views filters and views results
|
| 13 |
*
|
| 14 |
* @author Jose A. Reyero, 2004
|
| 15 |
*/
|
| 16 |
|
| 17 |
/**
|
| 18 |
* Modes for multilingual vocabularies
|
| 19 |
*/
|
| 20 |
// No multilingual options
|
| 21 |
define('I18N_TAXONOMY_NONE', 0);
|
| 22 |
// Run through the localization system
|
| 23 |
define('I18N_TAXONOMY_LOCALIZE', 1);
|
| 24 |
// Predefined language for all terms
|
| 25 |
define('I18N_TAXONOMY_LANGUAGE', 2);
|
| 26 |
// Multilingual terms, translatable
|
| 27 |
define('I18N_TAXONOMY_TRANSLATE', 3);
|
| 28 |
|
| 29 |
/**
|
| 30 |
* Implementation of hook_help().
|
| 31 |
*/
|
| 32 |
function i18ntaxonomy_help($section, $arg) {
|
| 33 |
switch ($section) {
|
| 34 |
case 'admin/help#i18ntaxonomy' :
|
| 35 |
$output = '<p>'.t('This module adds support for for multilingual taxonomy. You can set up multilingual options for each vocabulary:').'</p>';
|
| 36 |
$output .= '<ul>';
|
| 37 |
$output .= '<li>'.t('A language can be assigned globaly for a vocabulary').'</li>';
|
| 38 |
$output .= '<li>'.t('Different terms for each language with translation relationships.').'</li>';
|
| 39 |
$output .= '<li>'.t('Terms can be common to all languages but may be localized.').'</li>';
|
| 40 |
$output .= '</ul>';
|
| 41 |
$output .= '<p>'. t('For more information please read the <a href="@i18n">on-line help pages</a>.', array('@i18n' =>'http://drupal.org/node/31631')) .'</p>';
|
| 42 |
return $output;
|
| 43 |
case 'admin/settings/i18n':
|
| 44 |
$output = '<ul>';
|
| 45 |
$output .= '<li>'.t('To set up multilingual options for vocabularies go to !configure_taxonomy', array('!configure_taxonomy' => l(t('Taxonomy configuration page'), 'admin/content/taxonomy'))).'</li>';
|
| 46 |
$output . '</ul>';
|
| 47 |
return $output;
|
| 48 |
case 'admin/content/taxonomy/%':
|
| 49 |
$vocabulary = taxonomy_vocabulary_load($arg[3]);
|
| 50 |
switch (i18ntaxonomy_vocabulary($vocabulary->vid)) {
|
| 51 |
case I18N_TAXONOMY_LOCALIZE:
|
| 52 |
return '<p>'. t('%capital_name is a localizable vocabulary. You will be able to translate term names and descriptions using the localization interface.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name)) .'</p>';
|
| 53 |
case I18N_TAXONOMY_LANGUAGE:
|
| 54 |
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>';
|
| 55 |
case I18N_TAXONOMY_TRANSLATE:
|
| 56 |
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>';
|
| 57 |
}
|
| 58 |
|
| 59 |
}
|
| 60 |
}
|
| 61 |
|
| 62 |
/**
|
| 63 |
* Returns list of vocabulary modes
|
| 64 |
*/
|
| 65 |
function _i18ntaxonomy_vocabulary_options() {
|
| 66 |
return array(
|
| 67 |
I18N_TAXONOMY_NONE => t('None. No multilingual options for this vocabulary'),
|
| 68 |
I18N_TAXONOMY_LOCALIZE => t('Localize terms. Terms are common for all languages but their name and description may be localized.'),
|
| 69 |
I18N_TAXONOMY_TRANSLATE => t('Per language terms. Different terms will be allowed for each language and they can be translated.'),
|
| 70 |
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.'),
|
| 71 |
);
|
| 72 |
}
|
| 73 |
/**
|
| 74 |
* Implementation of hook_menu().
|
| 75 |
*/
|
| 76 |
function i18ntaxonomy_menu() {
|
| 77 |
$items['admin/content/taxonomy/%taxonomy_vocabulary/translation'] = array(
|
| 78 |
'title' => 'Translation',
|
| 79 |
'page callback' => 'i18ntaxonomy_page_vocabulary',
|
| 80 |
'page arguments' => array(3, 5, 6),
|
| 81 |
'access callback' => '_i18ntaxonomy_translation_tab',
|
| 82 |
'access arguments' => array(3),
|
| 83 |
'type' => MENU_LOCAL_TASK,
|
| 84 |
'parent' => 'admin/content/taxonomy/%taxonomy_vocabulary',
|
| 85 |
'file' => 'i18ntaxonomy.admin.inc',
|
| 86 |
);
|
| 87 |
return $items;
|
| 88 |
}
|
| 89 |
|
| 90 |
/**
|
| 91 |
* Implementation of hook_menu_alter().
|
| 92 |
*
|
| 93 |
* Take over the taxonomy pages
|
| 94 |
*/
|
| 95 |
function i18ntaxonomy_menu_alter(&$items) {
|
| 96 |
// Taxonomy term page. Localize terms
|
| 97 |
$items['taxonomy/term/%']['module'] = 'i18ntaxonomy';
|
| 98 |
$items['taxonomy/term/%']['page callback'] = 'i18ntaxonomy_term_page';
|
| 99 |
$items['taxonomy/term/%']['file'] = 'i18ntaxonomy.pages.inc';
|
| 100 |
// Localize autocomplete
|
| 101 |
$items['taxonomy/autocomplete']['module'] = 'i18ntaxonomy';
|
| 102 |
$items['taxonomy/autocomplete']['page callback'] = 'i18ntaxonomy_autocomplete';
|
| 103 |
$items['taxonomy/autocomplete']['file'] = 'i18ntaxonomy.pages.inc';
|
| 104 |
}
|
| 105 |
|
| 106 |
/**
|
| 107 |
* Menu access callback. Show tab only for full multilingual vocabularies
|
| 108 |
*/
|
| 109 |
function _i18ntaxonomy_translation_tab($vocabulary) {
|
| 110 |
return i18ntaxonomy_vocabulary($vocabulary->vid) == I18N_TAXONOMY_TRANSLATE;
|
| 111 |
}
|
| 112 |
|
| 113 |
/**
|
| 114 |
* Implementation of hook_locale().
|
| 115 |
*/
|
| 116 |
function i18ntaxonomy_locale($op = 'groups') {
|
| 117 |
switch ($op) {
|
| 118 |
case 'groups':
|
| 119 |
return array('taxonomy' => t('Taxonomy'));
|
| 120 |
}
|
| 121 |
}
|
| 122 |
/**
|
| 123 |
* Implementation of hook_alter_translation_link().
|
| 124 |
*
|
| 125 |
* Replaces links with pointers to translated versions of the content.
|
| 126 |
*/
|
| 127 |
function i18ntaxonomy_translation_link_alter(&$links, $path) {
|
| 128 |
if (preg_match("/^(taxonomy\/term\/)([^\/]*)(.*)$/", $path, $matches)) {//or at a taxonomy-listing?
|
| 129 |
foreach ($links as $langcode => $link) {
|
| 130 |
if ($str_tids = i18ntaxonomy_translation_tids($matches[2], $langcode)) {
|
| 131 |
$links[$langcode]['href'] = "taxonomy/term/$str_tids". $matches[3];
|
| 132 |
}
|
| 133 |
}
|
| 134 |
}
|
| 135 |
}
|
| 136 |
|
| 137 |
/**
|
| 138 |
* Get translated term's tid
|
| 139 |
*
|
| 140 |
* @param $tid
|
| 141 |
* Node nid to search for translation
|
| 142 |
* @param $language
|
| 143 |
* Language to search for the translation, defaults to current language
|
| 144 |
* @param $default
|
| 145 |
* Value that will be returned if no translation is found
|
| 146 |
* @return
|
| 147 |
* Translated term tid if exists, or $default
|
| 148 |
*/
|
| 149 |
function i18ntaxonomy_translation_term_tid($tid, $language = NULL, $default = NULL) {
|
| 150 |
$translation = db_result(db_query("SELECT t.tid FROM {term_data} t INNER JOIN {term_data} a ON t.trid = a.trid AND t.tid != a.tid WHERE a.tid = %d AND t.language = '%s' AND t.trid", $tid, $language ? $language : i18n_get_lang()));
|
| 151 |
return $translation ? $translation : $default;
|
| 152 |
}
|
| 153 |
|
| 154 |
/**
|
| 155 |
* Returns an url for the translated taxonomy-page, if exists
|
| 156 |
*/
|
| 157 |
function i18ntaxonomy_translation_tids($str_tids, $lang) {
|
| 158 |
if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str_tids)) {
|
| 159 |
$separator = '+';
|
| 160 |
// The '+' character in a query string may be parsed as ' '.
|
| 161 |
$tids = preg_split('/[+ ]/', $str_tids);
|
| 162 |
}
|
| 163 |
else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str_tids)) {
|
| 164 |
$separator = ',';
|
| 165 |
$tids = explode(',', $str_tids);
|
| 166 |
}
|
| 167 |
else {
|
| 168 |
return;
|
| 169 |
}
|
| 170 |
$translated_tids = array();
|
| 171 |
foreach ($tids as $tid) {
|
| 172 |
if ($translated_tid = i18ntaxonomy_translation_term_tid($tid, $lang)) {
|
| 173 |
$translated_tids[] = $translated_tid;
|
| 174 |
}
|
| 175 |
}
|
| 176 |
return implode($separator, $translated_tids);
|
| 177 |
}
|
| 178 |
/**
|
| 179 |
* Implementation of hook_taxonomy
|
| 180 |
*
|
| 181 |
* $edit parameter may be an array or an object !!
|
| 182 |
*/
|
| 183 |
function i18ntaxonomy_taxonomy($op, $type, $edit = NULL) {
|
| 184 |
$edit = (array)$edit;
|
| 185 |
switch ("$type/$op") {
|
| 186 |
case 'term/insert':
|
| 187 |
case 'term/update':
|
| 188 |
$tid = $edit['tid'];
|
| 189 |
$language = isset($edit['language']) ? $edit['language'] : '';
|
| 190 |
db_query("UPDATE {term_data} SET language='%s' WHERE tid=%d", $language, $tid);
|
| 191 |
// From translation module
|
| 192 |
if (!$language && !empty($edit['trid'])) {
|
| 193 |
// Removed language, remove trid
|
| 194 |
db_query('UPDATE {term_data} SET trid = 0 WHERE tid = %d', $tid);
|
| 195 |
if(db_affected_rows()) drupal_set_message(t('Removed translation information from term'));
|
| 196 |
}
|
| 197 |
// Update strings for localizable vocabulary
|
| 198 |
if (i18ntaxonomy_vocabulary($edit['vid']) == I18N_TAXONOMY_LOCALIZE) {
|
| 199 |
tt("taxonomy:term:$tid:name", $edit['name'], NULL, TRUE);
|
| 200 |
tt("taxonomy:term:$tid:description", $edit['description'], NULL, TRUE);
|
| 201 |
}
|
| 202 |
break;
|
| 203 |
case 'vocabulary/insert':
|
| 204 |
case 'vocabulary/update':
|
| 205 |
$vid = $edit['vid'];
|
| 206 |
// Update vocabulary settings
|
| 207 |
if (isset($edit['i18nmode'])) {
|
| 208 |
i18ntaxonomy_vocabulary($vid, $edit['i18nmode']);
|
| 209 |
|
| 210 |
$language = isset($edit['language']) ? $edit['language'] : '';
|
| 211 |
db_query("UPDATE {vocabulary} SET language='%s' WHERE vid = %d", $language, $edit['vid']);
|
| 212 |
if ($language && $op == 'update') {
|
| 213 |
db_query("UPDATE {term_data} SET language='%s' WHERE vid = %d", $edit['language'], $edit['vid']);
|
| 214 |
drupal_set_message(t('Reset language for all terms.'));
|
| 215 |
}
|
| 216 |
// Always add vocabulary translation if !$language
|
| 217 |
if (!$language) {
|
| 218 |
tt("taxonomy:vocabulary:$vid:name", $edit['name'], NULL, TRUE);
|
| 219 |
}
|
| 220 |
}
|
| 221 |
break;
|
| 222 |
}
|
| 223 |
}
|
| 224 |
|
| 225 |
/**
|
| 226 |
* Implementation of hook_db_rewrite_sql()
|
| 227 |
*/
|
| 228 |
function i18ntaxonomy_db_rewrite_sql($query, $primary_table, $primary_key){
|
| 229 |
// No rewrite for administration pages
|
| 230 |
if (arg(0) == 'admin') return;
|
| 231 |
|
| 232 |
switch ($primary_table) {
|
| 233 |
case 't':
|
| 234 |
case 'v':
|
| 235 |
// Taxonomy queries
|
| 236 |
// When loading specific terms, vocabs, language conditions shouldn't apply
|
| 237 |
if (preg_match("/WHERE.* $primary_table\.tid\s*(=\s*\d|IN)/", $query)) return;
|
| 238 |
// Taxonomy for specific node
|
| 239 |
if (preg_match("/WHERE r\.nid = \%d/", $query)) return;
|
| 240 |
$result['where'] = i18n_db_rewrite_where($primary_table, 'taxonomy');
|
| 241 |
return $result;
|
| 242 |
}
|
| 243 |
}
|
| 244 |
|
| 245 |
/**
|
| 246 |
* Implementation of hook_form_alter
|
| 247 |
*
|
| 248 |
* This is the place to add language fields to all forms
|
| 249 |
*
|
| 250 |
* @ TO DO The vocabulary form needs some javascript
|
| 251 |
*/
|
| 252 |
function i18ntaxonomy_form_alter(&$form, $form_state, $form_id) {
|
| 253 |
switch($form_id){
|
| 254 |
case 'taxonomy_overview_vocabularies':
|
| 255 |
$vocabularies = taxonomy_get_vocabularies();
|
| 256 |
$languages = locale_language_list('name');
|
| 257 |
foreach ($vocabularies as $vocabulary) {
|
| 258 |
if ($vocabulary->language) {
|
| 259 |
$form[$vocabulary->vid]['types']['#value'] .= ' ('.$languages[$vocabulary->language].')';
|
| 260 |
}
|
| 261 |
}
|
| 262 |
break;
|
| 263 |
case 'taxonomy_overview_terms':
|
| 264 |
$mode = i18ntaxonomy_vocabulary($form['#vocabulary']['vid']);
|
| 265 |
if ($mode == I18N_TAXONOMY_TRANSLATE) {
|
| 266 |
$languages = locale_language_list('name');
|
| 267 |
foreach (element_children($form) as $key) {
|
| 268 |
if (isset($form[$key]['#term']) && ($lang = $form[$key]['#term']['language'])) {
|
| 269 |
$form[$key]['view']['#value'] .= ' ('.$languages[$lang].')';
|
| 270 |
}
|
| 271 |
}
|
| 272 |
}
|
| 273 |
break;
|
| 274 |
case 'taxonomy_form_vocabulary': // Taxonomy vocabulary
|
| 275 |
if ($form['vid']['#value']) {
|
| 276 |
$vocabulary = taxonomy_vocabulary_load($form['vid']['#value']);
|
| 277 |
$mode = i18ntaxonomy_vocabulary($vocabulary->vid);
|
| 278 |
} else {
|
| 279 |
$vocabulary = NULL;
|
| 280 |
$mode = I18N_TAXONOMY_NONE;
|
| 281 |
}
|
| 282 |
$form['i18n'] = array(
|
| 283 |
'#type' => 'fieldset',
|
| 284 |
'#title' => t('Multilingual options'),
|
| 285 |
'#collapsible' => TRUE,
|
| 286 |
'#weight' => 0,
|
| 287 |
);
|
| 288 |
$form['i18n']['i18nmode'] = array(
|
| 289 |
'#type' => 'radios',
|
| 290 |
'#title' => t('Translation mode'),
|
| 291 |
'#options' => _i18ntaxonomy_vocabulary_options(),
|
| 292 |
'#default_value' => $mode,
|
| 293 |
);
|
| 294 |
$form['identification']['language'] = array(
|
| 295 |
'#type' => 'select',
|
| 296 |
'#title' => t('Language'),
|
| 297 |
'#default_value' => $vocabulary && !empty($vocabulary->language) ? $vocabulary->language : '',
|
| 298 |
'#options' => array('' => '') + locale_language_list('name'),
|
| 299 |
'#description' => t('Language for this vocbulary. If set, it will apply to all terms in this vocabulary.'),
|
| 300 |
'#disabled' => ($mode != I18N_TAXONOMY_LANGUAGE),
|
| 301 |
);
|
| 302 |
break;
|
| 303 |
|
| 304 |
case 'taxonomy_form_term': // Taxonomy term
|
| 305 |
$vocabulary = (object)$form['#vocabulary'];
|
| 306 |
$term = (object)$form['#term'];
|
| 307 |
// Add language field or not depending on taxonomy mode
|
| 308 |
switch (i18ntaxonomy_vocabulary($vocabulary->vid)) {
|
| 309 |
case I18N_TAXONOMY_TRANSLATE:
|
| 310 |
$form['identification']['language'] = array(
|
| 311 |
'#type' => 'select',
|
| 312 |
'#title' => t('Language'),
|
| 313 |
'#default_value' => isset($term) && !empty($term->language) ? $term->language : '',
|
| 314 |
'#options' => array('' => '') + locale_language_list('name'),
|
| 315 |
'#description' => t('This term belongs to a multilingual vocabulary. You can set a language for it.'),
|
| 316 |
);
|
| 317 |
break;
|
| 318 |
case I18N_TAXONOMY_LANGUAGE:
|
| 319 |
$form['language'] = array('#type' => 'value', '#value' => $vocabulary->language);
|
| 320 |
$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'))));
|
| 321 |
break;
|
| 322 |
case I18N_TAXONOMY_LOCALIZE:
|
| 323 |
$form['language'] = array('#type' => 'value', '#value' => '');
|
| 324 |
$form['identification']['name']['#description'] .= ' <strong>'.t('This name be localizable').'</strong>';
|
| 325 |
$form['identification']['description']['#description'] .= ' <strong>'.t('This description will be localizable').'</strong>';
|
| 326 |
break;
|
| 327 |
case I18N_TAXONOMY_NONE:
|
| 328 |
default:
|
| 329 |
$form['language'] = array('#type' => 'value', '#value' => '');
|
| 330 |
break;
|
| 331 |
}
|
| 332 |
break;
|
| 333 |
default:
|
| 334 |
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id
|
| 335 |
&& ($node = $form['#node']) && isset($form['taxonomy']) ) {
|
| 336 |
// Node form. Translate vocabularies
|
| 337 |
i18ntaxonomy_node_form($form);
|
| 338 |
}
|
| 339 |
}
|
| 340 |
}
|
| 341 |
|
| 342 |
/**
|
| 343 |
* Handle node form taxonomy
|
| 344 |
*/
|
| 345 |
function i18ntaxonomy_node_form(&$form) {
|
| 346 |
$node = $form['#node'];
|
| 347 |
if (!isset($node->taxonomy)) {
|
| 348 |
if (!empty($node->nid)) {
|
| 349 |
$terms = taxonomy_node_get_terms($node->nid);
|
| 350 |
}
|
| 351 |
else {
|
| 352 |
$terms = array();
|
| 353 |
}
|
| 354 |
}
|
| 355 |
else {
|
| 356 |
$terms = $node->taxonomy;
|
| 357 |
}
|
| 358 |
// Regenerate the whole field for translatable vocabularies
|
| 359 |
foreach (element_children($form['taxonomy']) as $vid) {
|
| 360 |
if (is_numeric($vid) && i18ntaxonomy_vocabulary($vid) == I18N_TAXONOMY_LOCALIZE) {
|
| 361 |
// Rebuild this vocabulary's form
|
| 362 |
$vocabulary = taxonomy_vocabulary_load($vid);
|
| 363 |
// Extract terms belonging to the vocabulary in question.
|
| 364 |
$default_terms = array();
|
| 365 |
foreach ($terms as $term) {
|
| 366 |
if ($term->vid == $vid) {
|
| 367 |
$default_terms[$term->tid] = $term;
|
| 368 |
}
|
| 369 |
}
|
| 370 |
|
| 371 |
$form['taxonomy'][$vid] = i18ntaxonomy_vocabulary_form($vocabulary->vid, array_keys($default_terms));
|
| 372 |
$form['taxonomy'][$vid]['#weight'] = $vocabulary->weight;
|
| 373 |
$form['taxonomy'][$vid]['#required'] = $vocabulary->required;
|
| 374 |
}
|
| 375 |
}
|
| 376 |
}
|
| 377 |
|
| 378 |
/**
|
| 379 |
* Generate a form element for selecting terms from a vocabulary.
|
| 380 |
* Translates all translatable strings.
|
| 381 |
*/
|
| 382 |
function i18ntaxonomy_vocabulary_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
|
| 383 |
$vocabulary = taxonomy_vocabulary_load($vid);
|
| 384 |
$help = $vocabulary->help ? tt("taxonomy:vocabulary:$vid:help", $vocabulary->help) : '';
|
| 385 |
if ($vocabulary->required) {
|
| 386 |
$blank = 0;
|
| 387 |
}
|
| 388 |
else {
|
| 389 |
$blank = '<'. t('none') .'>';
|
| 390 |
}
|
| 391 |
|
| 392 |
return _i18ntaxonomy_term_select(check_plain(tt("taxonomy:vocabulary:$vid:name", $vocabulary->name)), $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
|
| 393 |
}
|
| 394 |
|
| 395 |
// Produces translated tree
|
| 396 |
function _i18ntaxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
|
| 397 |
$tree = taxonomy_get_tree($vocabulary_id);
|
| 398 |
$options = array();
|
| 399 |
|
| 400 |
if ($blank) {
|
| 401 |
$options[0] = $blank;
|
| 402 |
}
|
| 403 |
if ($tree) {
|
| 404 |
foreach ($tree as $term) {
|
| 405 |
if (!in_array($term->tid, $exclude)) {
|
| 406 |
$choice = new stdClass();
|
| 407 |
$choice->option = array($term->tid => str_repeat('-', $term->depth) . tt("taxonomy:term:$term->tid:name", $term->name));
|
| 408 |
$options[] = $choice;
|
| 409 |
}
|
| 410 |
}
|
| 411 |
if (!$blank && !$value) {
|
| 412 |
// required but without a predefined value, so set first as predefined
|
| 413 |
$value = $tree[0]->tid;
|
| 414 |
}
|
| 415 |
}
|
| 416 |
|
| 417 |
return array('#type' => 'select',
|
| 418 |
'#title' => $title,
|
| 419 |
'#default_value' => $value,
|
| 420 |
'#options' => $options,
|
| 421 |
'#description' => $description,
|
| 422 |
'#multiple' => $multiple,
|
| 423 |
'#size' => $multiple ? min(9, count($options)) : 0,
|
| 424 |
'#weight' => -15,
|
| 425 |
'#theme' => 'taxonomy_term_select',
|
| 426 |
);
|
| 427 |
}
|
| 428 |
/**
|
| 429 |
* Returns a list for terms for vocabulary, language
|
| 430 |
*/
|
| 431 |
function i18ntaxonomy_vocabulary_get_terms($vid, $lang, $status = 'all') {
|
| 432 |
switch($status){
|
| 433 |
case 'translated':
|
| 434 |
$andsql = ' AND trid > 0';
|
| 435 |
break;
|
| 436 |
case 'untranslated':
|
| 437 |
$andsql = ' AND trid = 0';
|
| 438 |
break;
|
| 439 |
default:
|
| 440 |
$andsql = '';
|
| 441 |
}
|
| 442 |
$result = db_query("SELECT * FROM {term_data} WHERE vid=%d AND language='%s' $andsql", $vid, $lang);
|
| 443 |
$list = array();
|
| 444 |
while ($term = db_fetch_object($result)) {
|
| 445 |
$list[$term->tid] = $term->name;
|
| 446 |
}
|
| 447 |
return $list;
|
| 448 |
}
|
| 449 |
|
| 450 |
/**
|
| 451 |
* Multilingual Taxonomy
|
| 452 |
*
|
| 453 |
*/
|
| 454 |
|
| 455 |
/**
|
| 456 |
* Get term translations
|
| 457 |
*
|
| 458 |
* @return
|
| 459 |
* An array of the from lang => Term
|
| 460 |
*/
|
| 461 |
function i18ntaxonomy_term_get_translations($params, $getall = TRUE) {
|
| 462 |
foreach($params as $field => $value) {
|
| 463 |
$conds[] = "i.$field = '%s'";
|
| 464 |
$values[] = $value;
|
| 465 |
}
|
| 466 |
if(!$getall){ // If not all, a parameter must be tid
|
| 467 |
$conds[] = "t.tid != %d";
|
| 468 |
$values[] = $params['tid'];
|
| 469 |
}
|
| 470 |
$conds[] = "t.trid != 0";
|
| 471 |
$sql = 'SELECT t.* FROM {term_data} t INNER JOIN {term_data} i ON t.trid = i.trid WHERE '. implode(' AND ', $conds);;
|
| 472 |
$result = db_query($sql, $values);
|
| 473 |
$items = array();
|
| 474 |
while ($data = db_fetch_object($result)) {
|
| 475 |
$items[$data->language] = $data;
|
| 476 |
}
|
| 477 |
return $items;
|
| 478 |
}
|
| 479 |
|
| 480 |
|
| 481 |
/**
|
| 482 |
* Like nat_get_terms() but without caching
|
| 483 |
*/
|
| 484 |
function i18ntaxonomy_nat_get_terms($nid) {
|
| 485 |
$return = array();
|
| 486 |
|
| 487 |
$result = db_query("SELECT td.* FROM {nat} n INNER JOIN {term_data} td USING (tid) WHERE n.nid = %d", $nid);
|
| 488 |
while ($term = db_fetch_object($result)) {
|
| 489 |
$return[$term->tid] = $term;
|
| 490 |
}
|
| 491 |
|
| 492 |
return $return;
|
| 493 |
}
|
| 494 |
|
| 495 |
|
| 496 |
/**
|
| 497 |
* Implementation of hook_nodeapi()
|
| 498 |
*
|
| 499 |
* Prepare node for translation
|
| 500 |
*/
|
| 501 |
function i18ntaxonomy_nodeapi(&$node, $op) {
|
| 502 |
switch ($op) {
|
| 503 |
case 'view':
|
| 504 |
// This runs after taxonomy:nodeapi, so we just localize terms here
|
| 505 |
if ($op == 'view' && array_key_exists('taxonomy', $node)) {
|
| 506 |
$node->taxonomy = i18ntaxonomy_localize_terms($node->taxonomy);
|
| 507 |
}
|
| 508 |
break;
|
| 509 |
case 'prepare translation':
|
| 510 |
$source = $node->translation_source;
|
| 511 |
// Taxonomy translation
|
| 512 |
if (is_array($source->taxonomy)) {
|
| 513 |
// Set translated taxonomy terms
|
| 514 |
$node->taxonomy = i18ntaxonomy_translate_terms($source->taxonomy, $node->language);
|
| 515 |
}
|
| 516 |
break;
|
| 517 |
}
|
| 518 |
}
|
| 519 |
|
| 520 |
/**
|
| 521 |
* Translate an array of taxonomy terms
|
| 522 |
*
|
| 523 |
* Translates all terms with language, just passing over terms without it
|
| 524 |
*/
|
| 525 |
function i18ntaxonomy_translate_terms($taxonomy, $langcode) {
|
| 526 |
$translation = array();
|
| 527 |
foreach ($taxonomy as $index => $term) {
|
| 528 |
if ($term->language && $term->language != $langcode) {
|
| 529 |
$translated_terms = i18ntaxonomy_term_get_translations(array('tid' => $term->tid));
|
| 530 |
if ($translated_terms && $newterm = $translated_terms[$langcode]) {
|
| 531 |
$translation[$newterm->tid] = $newterm;
|
| 532 |
}
|
| 533 |
} else {
|
| 534 |
// Term has no language. Should be ok
|
| 535 |
$translation[$index] = $term;
|
| 536 |
}
|
| 537 |
}
|
| 538 |
return $translation;
|
| 539 |
}
|
| 540 |
|
| 541 |
/**
|
| 542 |
* Implementation of hook_views_pre_view().
|
| 543 |
*
|
| 544 |
* Translate table header for taxonomy fields
|
| 545 |
* //field[i][id] = term_node_1.name, translate table header
|
| 546 |
* and replace handler for that field
|
| 547 |
*/
|
| 548 |
function i18ntaxonomy_views_pre_view(&$view, &$items) {
|
| 549 |
//var_dump($view);
|
| 550 |
$translate = variable_get('i18ntaxonomy_vocabularies', array());
|
| 551 |
foreach($view->field as $index => $data) {
|
| 552 |
$matches = array();
|
| 553 |
if($data['id'] == 'term_node.name') {
|
| 554 |
// That's a full taxonomy box
|
| 555 |
$view->field[$index]['handler'] = 'i18ntaxonomy_views_handler_field_allterms';
|
| 556 |
} elseif(preg_match("/term_node_(\d+)\.name/", $data['id'], $matches)) {
|
| 557 |
$vid = $matches[1];
|
| 558 |
if ($translate[$vid]) {
|
| 559 |
// Set new handler for this field
|
| 560 |
$view->field[$index]['handler'] = 'i18ntaxonomy_views_handler_field_allterms';
|
| 561 |
}
|
| 562 |
}
|
| 563 |
}
|
| 564 |
|
| 565 |
}
|
| 566 |
|
| 567 |
/**
|
| 568 |
* Field handler for taxonomy term fields
|
| 569 |
*
|
| 570 |
* Remake of views_handler_field_allterms with term name translation
|
| 571 |
*/
|
| 572 |
function i18ntaxonomy_views_handler_field_allterms($fieldinfo, $fielddata, $value, $data) {
|
| 573 |
if ($fieldinfo['vocabulary']) {
|
| 574 |
$terms = taxonomy_node_get_terms_by_vocabulary($data->nid, $fieldinfo['vocabulary']);
|
| 575 |
}
|
| 576 |
else {
|
| 577 |
$terms = taxonomy_node_get_terms($data->nid);
|
| 578 |
}
|
| 579 |
// Translate all these terms
|
| 580 |
_i18ntaxonomy_translate_terms($terms);
|
| 581 |
|
| 582 |
if ($fielddata['options'] == 'nolink') {
|
| 583 |
foreach ($terms as $term) {
|
| 584 |
$links[] = check_plain($term->name);
|
| 585 |
}
|
| 586 |
$links = !empty($links) ? implode(' | ', $links) : '';
|
| 587 |
}
|
| 588 |
else {
|
| 589 |
$node = new stdClass();
|
| 590 |
$node->taxonomy = $terms;
|
| 591 |
$links = theme('links', taxonomy_link('taxonomy terms', $node));
|
| 592 |
}
|
| 593 |
return $links;
|
| 594 |
}
|
| 595 |
|
| 596 |
/**
|
| 597 |
* Localize taxonomy terms for localizable vocabularies
|
| 598 |
*
|
| 599 |
* @param $terms
|
| 600 |
* Array of term objects
|
| 601 |
* @param $fields
|
| 602 |
* Object properties to localize
|
| 603 |
* @return
|
| 604 |
* Array of terms with the right ones localized
|
| 605 |
*/
|
| 606 |
function i18ntaxonomy_localize_terms($terms, $fields = array('name')) {
|
| 607 |
$localize = i18ntaxonomy_vocabulary(NULL, I18N_TAXONOMY_LOCALIZE);
|
| 608 |
foreach ($terms as $index => $term) {
|
| 609 |
if (in_array($term->vid, $localize)) {
|
| 610 |
foreach ($fields as $property) {
|
| 611 |
$terms[$index]->$property = tt("taxonomy:term:$term->tid:$property", $term->name);
|
| 612 |
}
|
| 613 |
}
|
| 614 |
}
|
| 615 |
return $terms;
|
| 616 |
}
|
| 617 |
|
| 618 |
// Get a list of vocabularies and terms
|
| 619 |
function _i18ntaxonomy_vocabulary_terms($vid = NULL, $fullname = TRUE) {
|
| 620 |
$tids = array();
|
| 621 |
if (is_numeric($vid)) {
|
| 622 |
$where = "WHERE td.vid = $vid";
|
| 623 |
} elseif(is_array($vid)) {
|
| 624 |
$where = "WHERE td.vid IN(".implode(',', $vid).')';
|
| 625 |
}
|
| 626 |
$result = db_query("SELECT DISTINCT(td.tid), td.name, td.weight, v.name as vocabname, v.weight FROM {term_data} td LEFT JOIN {vocabulary} v ON v.vid = td.vid $where ORDER BY v.weight, v.name, td.weight, td.name");
|
| 627 |
while ($obj = db_fetch_object($result)) {
|
| 628 |
$tids[$obj->tid] = $fullname ? t($obj->vocabname).': '.t($obj->name) : t($obj->name);
|
| 629 |
}
|
| 630 |
|
| 631 |
return $tids;
|
| 632 |
}
|
| 633 |
|
| 634 |
/**
|
| 635 |
* Taxonomy vocabulary settings
|
| 636 |
*
|
| 637 |
* - If $vid and not $value, returns mode for vid
|
| 638 |
* - If $vid and $value, sets mode for vid
|
| 639 |
* - If !$vid and !$value returns all settings
|
| 640 |
* - If !$vid and $value returns all vids for this mode
|
| 641 |
*
|
| 642 |
* @param $vid
|
| 643 |
* Vocabulary id
|
| 644 |
* @param $value
|
| 645 |
* Vocabulary mode
|
| 646 |
*
|
| 647 |
*/
|
| 648 |
function i18ntaxonomy_vocabulary($vid = NULL, $mode = NULL) {
|
| 649 |
$options = variable_get('i18ntaxonomy_vocabulary', array());
|
| 650 |
if ($vid && $mode) {
|
| 651 |
$options[$vid] = $mode;
|
| 652 |
variable_set('i18ntaxonomy_vocabulary', $options);
|
| 653 |
} elseif ($vid) {
|
| 654 |
return array_key_exists($vid, $options) ? $options[$vid] : I18N_TAXONOMY_NONE;
|
| 655 |
} elseif ($mode) {
|
| 656 |
return array_keys($options, $mode);
|
| 657 |
} else {
|
| 658 |
return $options;
|
| 659 |
}
|
| 660 |
}
|