i18n_taxonomy.admin.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /**
  3. * @file
  4. * Helper functions for taxonomy administration.
  5. */
  6. /**
  7. * This is the callback for taxonomy translations.
  8. *
  9. * Gets the urls:
  10. * admin/content/taxonomy/%taxonomy_vocabulary/translation
  11. * admin/content/taxonomy/i18n/term/xx
  12. * admin/content/taxonomy/i18n/term/new/xx
  13. * admin/content/taxonomy/vid/translation/op/trid
  14. */
  15. function i18n_taxonomy_page_vocabulary($vocabulary, $op = NULL, $tid = NULL) {
  16. switch ($op) {
  17. case 'edit':
  18. drupal_set_title(t('Edit term translations'));
  19. $output = drupal_get_form('i18n_taxonomy_translation_term_form', $vocabulary, $tid);
  20. break;
  21. default:
  22. $output = i18n_taxonomy_translation_overview($vocabulary);
  23. }
  24. return $output;
  25. }
  26. /**
  27. * Produces a vocabulary translation form.
  28. */
  29. function i18n_taxonomy_translation_term_form($form, $form_state, $vocabulary, $translation_set = NULL, $source = NULL) {
  30. $form['translation_set'] = array('#type' => 'value', '#value' => $translation_set);
  31. $translations = $translation_set ? $translation_set->get_translations() : array();
  32. $form['vocabulary'] = array('#type' => 'value', '#value' => $vocabulary);
  33. $form['translations'] = array(
  34. '#type' => 'fieldset',
  35. '#title' => t('Select translations'),
  36. '#description' => t('Select existing terms or type new ones that will be created for each language.'),
  37. '#tree' => TRUE
  38. );
  39. // List of terms for languages.
  40. foreach (i18n_language_list() as $lang => $langname) {
  41. if ($source && $source->language == $lang) {
  42. // This is the source term, we don't change it
  43. $form['source_term'] = array('#type' => 'value', '#value' => $source);
  44. $form['translations'][$lang] = array(
  45. '#title' => $langname,
  46. '#type' => 'item',
  47. '#markup' => $source->name,
  48. '#langcode' => $lang,
  49. );
  50. }
  51. else {
  52. $form['translations'][$lang] = array(
  53. '#title' => $langname,
  54. '#type' => 'textfield',
  55. '#default_value' => isset($translations[$lang]) ? $translations[$lang]->name : '',
  56. '#autocomplete_path' => 'i18n/taxonomy/autocomplete/vocabulary/' . $vocabulary->machine_name . '/' . $lang,
  57. '#langcode' => $lang,
  58. '#maxlength' => 1024,
  59. '#element_validate' => array('i18n_taxonomy_autocomplete_validate'),
  60. );
  61. }
  62. }
  63. $form['submit'] = array(
  64. '#type' => 'submit',
  65. '#value' => t('Save')
  66. );
  67. if ($translation_set) {
  68. $form['delete'] = array(
  69. '#type' => 'submit',
  70. '#value' => t('Delete')
  71. );
  72. }
  73. return $form;
  74. }
  75. /**
  76. * Form element validate handler for taxonomy term autocomplete element.
  77. */
  78. function i18n_taxonomy_autocomplete_validate($element, &$form_state) {
  79. // Autocomplete widgets do not send their tids in the form, so we must detect
  80. // them here and process them independently.
  81. $value = array();
  82. if ($tags = $element['#value']) {
  83. // Collect candidate vocabularies.
  84. $vocabulary = $form_state['values']['vocabulary'];
  85. $vocabularies[$vocabulary->vid] = $vocabulary;
  86. // Translate term names into actual terms.
  87. $typed_terms = drupal_explode_tags($tags);
  88. foreach ($typed_terms as $typed_term) {
  89. // See if the term exists in the chosen vocabulary and return the tid;
  90. // otherwise, create a new 'autocreate' term for insert/update.
  91. if ($possibilities = taxonomy_term_load_multiple(array(), array('name' => trim($typed_term), 'vid' => $vocabulary->vid, 'language' => $element['#langcode']))) {
  92. $term = array_pop($possibilities);
  93. }
  94. else {
  95. $vocabulary = reset($vocabularies);
  96. $term = array(
  97. 'tid' => 'autocreate',
  98. 'vid' => $vocabulary->vid,
  99. 'name' => $typed_term,
  100. 'vocabulary_machine_name' => $vocabulary->machine_name,
  101. 'language' => $element['#langcode'],
  102. );
  103. }
  104. $value[] = (array)$term;
  105. }
  106. }
  107. form_set_value($element, $value, $form_state);
  108. }
  109. /**
  110. * Form callback: Process vocabulary translation form.
  111. */
  112. function i18n_taxonomy_translation_term_form_submit($form, &$form_state) {
  113. $translation_set = $form_state['values']['translation_set'];
  114. $vocabulary = $form_state['values']['vocabulary'];
  115. switch ($form_state['values']['op']) {
  116. case t('Save'):
  117. $term_translations = array_filter($form_state['values']['translations']);
  118. foreach ($term_translations as $lang => $lang_terms) {
  119. $item = reset($lang_terms);
  120. if ($item['tid'] == 'autocreate') {
  121. $term = (object) $item;
  122. unset($term->tid);
  123. taxonomy_term_save($term);
  124. }
  125. else {
  126. $term = (object) $item;
  127. }
  128. $translations[$lang] = $term;
  129. }
  130. if (!empty($form_state['values']['source_term'])) {
  131. $term = $form_state['values']['source_term'];
  132. $translations[$term->language] = $term;
  133. }
  134. if (!empty($translations)) {
  135. $translation_set = $translation_set ? $translation_set : i18n_translation_set_create('taxonomy_term', $vocabulary->machine_name);
  136. $translation_set
  137. ->reset_translations($translations)
  138. ->save(TRUE);
  139. drupal_set_message(t('Term translations have been updated.'));
  140. }
  141. else {
  142. drupal_set_message(t('There are no translations to be saved.'), 'error');
  143. }
  144. break;
  145. case t('Delete'):
  146. $translation_set->delete(TRUE);
  147. drupal_set_message(t('The term translation has been deleted.'));
  148. $form_state['redirect'] = 'admin/structure/taxonomy/' . $form_state['values']['vocabulary']->machine_name . '/translation';
  149. break;
  150. }
  151. }
  152. /**
  153. * Generate a tabular listing of translations for vocabularies.
  154. */
  155. function i18n_taxonomy_translation_sets_overview($vocabulary) {
  156. module_load_include('admin.inc', 'i18n_translation');
  157. drupal_set_title($vocabulary->name);
  158. $query = db_select('i18n_translation_set', 't')
  159. ->condition('t.bundle', $vocabulary->machine_name);
  160. return i18n_translation_admin_overview('taxonomy_term', $query);
  161. }
  162. /**
  163. * Callback for term translation tab.
  164. */
  165. function i18n_taxonomy_translation_term_overview($term) {
  166. if ($term->i18n_tsid) {
  167. // Already part of a set, grab that set.
  168. $i18n_tsid = $term->i18n_tsid;
  169. $translation_set = i18n_translation_set_load($term->i18n_tsid);
  170. $translation_set->get_translations();
  171. $translations = $translation_set->get_translations();
  172. }
  173. else {
  174. // We have no translation source nid, this could be a new set, emulate that.
  175. $i18n_tsid = $term->tid;
  176. $translations = array($term->language => $term);
  177. }
  178. $type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
  179. $header = array(t('Language'), t('Title'), t('Operations'));
  180. foreach (i18n_language_list() as $langcode => $language_name) {
  181. $options = array();
  182. if (isset($translations[$langcode])) {
  183. // Existing translation in the translation set: display status.
  184. // We load the full node to check whether the user can edit it.
  185. $translation_term = taxonomy_term_load($translations[$langcode]->tid);
  186. $path = 'taxonomy/term/' . $translation_term->tid;
  187. $title = l($translation_term->name, $path);
  188. $options['edit'] = array(
  189. '#type' => 'link',
  190. '#title' => t('edit'),
  191. '#href' => $path . '/edit',
  192. '#options' => array(
  193. 'query' => drupal_get_destination(),
  194. ),
  195. );
  196. if ($translation_term->tid == $i18n_tsid) {
  197. $language_name = t('<strong>@language_name</strong> (source)', array('@language_name' => $language_name));
  198. }
  199. }
  200. else {
  201. // No such translation in the set yet: help user to create it.
  202. $title = t('n/a');
  203. $options['add'] = array(
  204. '#type' => 'link',
  205. '#title' => t('add translation'),
  206. '#href' => 'admin/structure/taxonomy/' . $term->vocabulary_machine_name . '/add',
  207. '#options' => array(
  208. 'query' => array('translation' => $term->tid, 'target' => $langcode) + drupal_get_destination()
  209. ),
  210. );
  211. }
  212. $rows[$langcode] = array(
  213. 'language' => $language_name,
  214. 'title' => $title,
  215. 'operations' => array('data' => $options),
  216. );
  217. }
  218. drupal_set_title(t('Translations of term %title', array('%title' => $term->name)), PASS_THROUGH);
  219. $build['translation_overview'] = array(
  220. '#theme' => 'table',
  221. '#header' => $header,
  222. '#rows' => $rows,
  223. );
  224. return $build;
  225. }