entity_translation.taxonomy.inc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <?php
  2. /**
  3. * @file
  4. * The taxonomy specific translation functions and hook implementations.
  5. */
  6. /**
  7. * Returns whether the given taxonomy vocabulary has support for translations.
  8. *
  9. * @return bool
  10. * TRUE if translation is enabled, FALSE otherwise.
  11. */
  12. function entity_translation_taxonomy_term_enabled_vocabulary($vocabulary_name) {
  13. $info = variable_get('entity_translation_taxonomy', array());
  14. return !empty($info[$vocabulary_name]);
  15. }
  16. /**
  17. * Taxonomy-term-specific menu alterations.
  18. */
  19. function entity_translation_taxonomy_term_menu_alter(&$items, $backup) {
  20. if (isset($backup['taxonomy_term'])) {
  21. $item = $backup['taxonomy_term'];
  22. // Preserve the menu router item defined by other modules.
  23. $callback['page callback'] = $item['page callback'];
  24. $callback['file'] = $item['file'];
  25. $callback['module'] = $item['module'];
  26. $access_arguments = array_merge(array(2, $item['access callback']), $item['access arguments']);
  27. $page_arguments = array_merge(array('taxonomy_term', 2, $callback), $item['page arguments']);
  28. }
  29. else {
  30. $access_arguments = array(2);
  31. $page_arguments = array('taxonomy_term', 2);
  32. }
  33. $items['taxonomy/term/%taxonomy_term/translate']['page callback'] = 'entity_translation_overview';
  34. $items['taxonomy/term/%taxonomy_term/translate']['page arguments'] = $page_arguments;
  35. $items['taxonomy/term/%taxonomy_term/translate']['access arguments'] = $access_arguments;
  36. $items['taxonomy/term/%taxonomy_term/translate']['access callback'] = 'entity_translation_taxonomy_term_tab_access';
  37. $items['taxonomy/term/%taxonomy_term/translate']['file'] = 'entity_translation.admin.inc';
  38. $items['taxonomy/term/%taxonomy_term/translate']['module'] = 'entity_translation';
  39. // Delete translation callback.
  40. $items['taxonomy/term/%taxonomy_term/translate/delete/%entity_translation_language']['access arguments'] = $access_arguments;
  41. }
  42. /**
  43. * Taxonomy term specific access callback.
  44. */
  45. function entity_translation_taxonomy_term_tab_access() {
  46. $args = func_get_args();
  47. $term = array_shift($args);
  48. if (entity_translation_enabled('taxonomy_term', $term)) {
  49. return entity_translation_tab_access('taxonomy_term', $term);
  50. }
  51. else {
  52. $function = array_shift($args);
  53. return $function ? call_user_func_array($function, $args) : FALSE;
  54. }
  55. }
  56. /**
  57. * Implements hook_form_FORM_ID_alter()
  58. */
  59. function entity_translation_form_taxonomy_form_vocabulary_alter(&$form, &$form_state) {
  60. if (entity_translation_enabled('taxonomy_term')) {
  61. $name = $form_state['vocabulary']->machine_name;
  62. if (isset($form['i18n_translation']['i18n_mode'])) {
  63. $args = array('!url' => url('admin/config/regional/entity_translation'));
  64. $form['i18n_translation']['i18n_mode']['#options'][I18N_MODE_ENTITY_TRANSLATION] = t('Field translation. Term fields will be translated through the <a href="!url">Entity translation</a> module.', $args);
  65. if (entity_translation_enabled_bundle('taxonomy_term', $name)) {
  66. $form['i18n_translation']['i18n_mode']['#default_value'] = I18N_MODE_ENTITY_TRANSLATION;
  67. }
  68. }
  69. else {
  70. $form['entity_translation_taxonomy'] = array(
  71. '#title' => t('Enable field translation'),
  72. '#type' => 'checkbox',
  73. '#prefix' => '<label>' . t('Translation') . '</label>',
  74. '#default_value' => entity_translation_enabled('taxonomy_term', $name),
  75. );
  76. }
  77. $form['#submit'][] = 'entity_translation_form_taxonomy_form_vocabulary_submit';
  78. }
  79. }
  80. /**
  81. * Submit handler for the taxonomy vocabulary form.
  82. */
  83. function entity_translation_form_taxonomy_form_vocabulary_submit($form, &$form_state) {
  84. if (!empty($form_state['values']['i18n_mode']) && $form_state['values']['i18n_mode'] == I18N_MODE_ENTITY_TRANSLATION) {
  85. $form_state['values']['entity_translation_taxonomy'] = TRUE;
  86. }
  87. $info = variable_get('entity_translation_taxonomy', array());
  88. $info[$form_state['vocabulary']->machine_name] = !empty($form_state['values']['entity_translation_taxonomy']);
  89. variable_set('entity_translation_taxonomy', $info);
  90. }
  91. /**
  92. * Returns a translated label for the specified taxonomy term.
  93. *
  94. * @param object $term
  95. * A taxonomy term object.
  96. * @param string $langcode
  97. * The language the label should be translated in.
  98. *
  99. * @return string
  100. * The translated taxonomy term label.
  101. *
  102. * @internal This is supposed to be used only by the ET taxonomy integration
  103. * code, as it might be removed/replaced in any moment of the ET lifecycle.
  104. */
  105. function _entity_translation_taxonomy_label($term, $langcode) {
  106. $entity_type = 'taxonomy_term';
  107. if (function_exists('title_entity_label')) {
  108. $label = title_entity_label($term, $entity_type, $langcode);
  109. }
  110. else {
  111. $label = entity_label($entity_type, $term);
  112. }
  113. return (string) $label;
  114. }
  115. /**
  116. * Implements entity_translation_form_field_ui_field_edit_WIDGET_TYPE_form_alter().
  117. *
  118. * {@inheritdoc}
  119. */
  120. function entity_translation_form_field_ui_field_edit_taxonomy_autocomplete_form_alter(&$form, &$form_state) {
  121. $key = 'entity_translation_taxonomy_autocomplete_translate';
  122. $instance = $form['#instance'];
  123. $field_name = $instance['field_name'];
  124. $entity_type = $instance['entity_type'];
  125. $field = field_info_field($field_name);
  126. $translatable = field_is_translatable($entity_type, $field);
  127. $bundle = !empty($field['settings']['allowed_values'][0]['vocabulary']) ? $field['settings']['allowed_values'][0]['vocabulary'] : NULL;
  128. $access = variable_get('entity_translation_taxonomy_autocomplete', FALSE);
  129. // Add a checkbox to toggle in-place translation for autocomplete widgets.
  130. $form['instance']['settings'][$key] = array(
  131. '#type' => 'checkbox',
  132. '#title' => t('Enable in-place translation of terms'),
  133. '#description' => t('Check this option if you wish to use translation forms to perform in-place translation for terms entered in the original language.'),
  134. '#default_value' => !$translatable && !empty($form['#instance']['settings'][$key]),
  135. '#access' => $access && (!$form_state['field_has_data'] || !$translatable) && entity_translation_enabled('taxonomy_term', $bundle),
  136. '#states' => array(
  137. 'visible' => array(':input[name="field[translatable]"]' => array('checked' => FALSE)),
  138. ),
  139. '#weight' => -8,
  140. );
  141. }
  142. /**
  143. * Checks whether in-place translation is enabled for the autocomplete widget.
  144. *
  145. * @param array $element
  146. * The widget form element.
  147. * @param array $form_state
  148. * The form state array.
  149. *
  150. * @return bool
  151. * TRUE if in-place translation is enabled, FALSE otherwise.
  152. */
  153. function _entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state) {
  154. $field = field_info_field($element['#field_name']);
  155. if (field_is_translatable($element['#entity_type'], $field)) {
  156. return FALSE;
  157. }
  158. list($id, , $bundle) = entity_extract_ids($element['#entity_type'], $element['#entity']);
  159. if (!$id) {
  160. return FALSE;
  161. }
  162. $entity_type = 'taxonomy_term';
  163. $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
  164. $active_langcode = $parent_handler->getActiveLanguage();
  165. $translations = $parent_handler->getTranslations();
  166. $entity_langcode = isset($translations->original) ? $translations->original : LANGUAGE_NONE;
  167. $instance = field_info_instance($element['#entity_type'], $field['field_name'], $bundle);
  168. // We need to make sure that we are not dealing with a translation form.
  169. // However checking the active language is not enough, because the user may
  170. // have changed the entity language.
  171. return
  172. (isset($form_state['entity_translation']['is_translation']) ?
  173. $form_state['entity_translation']['is_translation'] : ($active_langcode != $entity_langcode)) &&
  174. !empty($instance['settings']['entity_translation_taxonomy_autocomplete_translate']) &&
  175. (user_access('translate any entity') || user_access("translate $entity_type entities"));
  176. }
  177. /**
  178. * Implements hook_field_widget_WIDGET_TYPE_form_alter().
  179. *
  180. * {@inheritdoc}
  181. */
  182. function entity_translation_field_widget_taxonomy_autocomplete_form_alter(&$element, &$form_state, $context) {
  183. // The autocomplete widget is also displayed in the field configuration form,
  184. // in which case we do not need to perform any alteration. To preserve BC, by
  185. // default we enable our taxonomy autocomplete override only on new sites.
  186. if (!isset($element['#entity']) || !variable_get('entity_translation_taxonomy_autocomplete', FALSE)) {
  187. return;
  188. }
  189. // We will need to translate term names, if Title is enabled and configured
  190. // for this vocabulary.
  191. $entity_type = 'taxonomy_term';
  192. $field = field_widget_field($element, $form_state);
  193. $bundle = !empty($field['settings']['allowed_values'][0]['vocabulary']) ? $field['settings']['allowed_values'][0]['vocabulary'] : NULL;
  194. if ($bundle && entity_translation_enabled($entity_type, $bundle)) {
  195. $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
  196. $langcode = $parent_handler->getActiveLanguage();
  197. $terms = array_values(_entity_translation_taxonomy_autocomplete_widget_get_terms($element));
  198. // If we are using the regular autocomplete behavior also in translation
  199. // forms, we need to set our custom callback.
  200. if (!_entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state)) {
  201. $element['#autocomplete_path'] = 'entity_translation/' . $entity_type . '/autocomplete/' . $langcode . '/' . $element['#field_name'];
  202. $translations = $parent_handler->getTranslations();
  203. if (isset($translations->original) && $translations->original != $langcode) {
  204. $labels = array();
  205. foreach ($terms as $delta => $term) {
  206. $labels[] = _entity_translation_taxonomy_label($term, $langcode);
  207. }
  208. $element['#default_value'] = implode(', ', $labels);
  209. }
  210. }
  211. // Otherwise we just provide the in-place translation widget.
  212. else {
  213. $element['#type'] = 'fieldset';
  214. $element['#description'] = t('Enter one translation for each term');
  215. $element['#access'] = (bool) $terms;
  216. foreach ($terms as $delta => $term) {
  217. $element[$delta] = array(
  218. '#type' => 'textfield',
  219. '#default_value' => _entity_translation_taxonomy_label($term, $langcode),
  220. '#required' => TRUE,
  221. '#tid' => $term->tid,
  222. );
  223. }
  224. $element['#process'][] = 'entity_translation_taxonomy_autocomplete_process';
  225. }
  226. // The native term save logic is performed at widget validation level, so we
  227. // just replace the validation handler to provide our logic instead.
  228. $element['#element_validate'] = array_values(array_diff($element['#element_validate'], array('taxonomy_autocomplete_validate')));
  229. $element['#element_validate'][] = 'entity_translation_taxonomy_autocomplete_validate';
  230. }
  231. }
  232. /**
  233. * Returns the terms referenced by the taxonomy autocomplete widget field.
  234. *
  235. * @param array $element
  236. * The taxonomy autocomplete form element.
  237. *
  238. * @return object[]
  239. * An associative array of taxonomy term object keyed by their identifiers.
  240. */
  241. function _entity_translation_taxonomy_autocomplete_widget_get_terms($element) {
  242. $items = isset($element['#entity']->{$element['#field_name']}[$element['#language']]) ?
  243. $element['#entity']->{$element['#field_name']}[$element['#language']] : array();
  244. $tids = array_map(function ($item) { return $item['tid']; }, $items);
  245. return taxonomy_term_load_multiple($tids);
  246. }
  247. /**
  248. * Process callback for the ET taxonomy autocomplete widget.
  249. *
  250. * {@inheritdoc}
  251. */
  252. function entity_translation_taxonomy_autocomplete_process($element) {
  253. // The in-place translation widget makes sense only for untranslatable field,
  254. // which may have the "(all languages)" label suffix. In this case it would be
  255. // confusing so we need to revert that.
  256. $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
  257. $element['#title'] = check_plain($instance['label']);
  258. return $element;
  259. }
  260. /**
  261. * Entity translation taxonomy autocomplete callback.
  262. *
  263. * @param string $langcode
  264. * The input language.
  265. * @param string $field_name
  266. * The name of the term reference field.
  267. * @param string $tags_typed
  268. * (optional) A comma-separated list of term names entered in the
  269. * autocomplete form element. Only the last term is used for autocompletion.
  270. * Defaults to an empty string.
  271. *
  272. * @see taxonomy_autocomplete()
  273. */
  274. function entity_translation_taxonomy_term_autocomplete($langcode = NULL, $field_name = '', $tags_typed = '') {
  275. // If the request has a '/' in the search text, then the menu system will have
  276. // split it into multiple arguments, recover the intended $tags_typed.
  277. $args = func_get_args();
  278. // Shift off the $langcode and $field_name arguments.
  279. array_shift($args);
  280. array_shift($args);
  281. $tags_typed = implode('/', $args);
  282. // Make sure the field exists and is a taxonomy field.
  283. if (!($field = field_info_field($field_name)) || $field['type'] !== 'taxonomy_term_reference') {
  284. // Error string. The JavaScript handler will realize this is not JSON and
  285. // will display it as debugging information.
  286. print t('Taxonomy field @field_name not found.', array('@field_name' => $field_name));
  287. exit;
  288. }
  289. // The user enters a comma-separated list of tags. We only autocomplete the
  290. // last tag.
  291. $tags_typed = drupal_explode_tags($tags_typed);
  292. $tag_last = drupal_strtolower(array_pop($tags_typed));
  293. $term_matches = array();
  294. if ($tag_last != '') {
  295. if (!isset($langcode) || $langcode == LANGUAGE_NONE) {
  296. $langcode = $GLOBALS['language_content']->language;
  297. }
  298. // Part of the criteria for the query come from the field's own settings.
  299. $vocabulary = _entity_translation_taxonomy_reference_get_vocabulary($field);
  300. $entity_type = 'taxonomy_term';
  301. $query = new EntityFieldQuery();
  302. $query->addTag('taxonomy_term_access');
  303. $query->entityCondition('entity_type', $entity_type);
  304. // If the Title module is enabled and the taxonomy term name is replaced for
  305. // the current bundle, we can look for translated names, otherwise we fall
  306. // back to the regular name property.
  307. if (module_invoke('title', 'field_replacement_enabled', $entity_type, $vocabulary->machine_name, 'name')) {
  308. $name_field = 'name_field';
  309. $language_group = 0;
  310. // Do not select already entered terms.
  311. $column = 'value';
  312. if (!empty($tags_typed)) {
  313. $query->fieldCondition($name_field, $column, $tags_typed, 'NOT IN', NULL, $language_group);
  314. }
  315. $query->fieldCondition($name_field, $column, $tag_last, 'CONTAINS', NULL, $language_group);
  316. $query->fieldLanguageCondition($name_field, array($langcode, LANGUAGE_NONE), NULL, NULL, $language_group);
  317. }
  318. else {
  319. $name_field = 'name';
  320. // Do not select already entered terms.
  321. if (!empty($tags_typed)) {
  322. $query->propertyCondition($name_field, $tags_typed, 'NOT IN');
  323. }
  324. $query->propertyCondition($name_field, $tag_last, 'CONTAINS');
  325. }
  326. // Select rows that match by term name.
  327. $query->propertyCondition('vid', $vocabulary->vid);
  328. $query->range(0, 10);
  329. $result = $query->execute();
  330. // Populate the results array.
  331. $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
  332. $terms = !empty($result[$entity_type]) ? taxonomy_term_load_multiple(array_keys($result[$entity_type])) : array();
  333. foreach ($terms as $tid => $term) {
  334. $name = _entity_translation_taxonomy_label($term, $langcode);
  335. $n = $name;
  336. // Term names containing commas or quotes must be wrapped in quotes.
  337. if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
  338. $n = '"' . str_replace('"', '""', $name) . '"';
  339. }
  340. $term_matches[$prefix . $n] = check_plain($name);
  341. }
  342. }
  343. drupal_json_output($term_matches);
  344. }
  345. /**
  346. * Returns the vocabulary enabled for the specified taxonomy reference field.
  347. *
  348. * @param array $field
  349. * A field definition.
  350. *
  351. * @return object|null
  352. * A vocabulary object or NULL if none is found.
  353. */
  354. function _entity_translation_taxonomy_reference_get_vocabulary($field) {
  355. $vocabulary = NULL;
  356. if (!empty($field['settings']['allowed_values'])) {
  357. $vids = array();
  358. $vocabularies = taxonomy_vocabulary_get_names();
  359. foreach ($field['settings']['allowed_values'] as $tree) {
  360. $vids[] = $vocabularies[$tree['vocabulary']]->vid;
  361. }
  362. $vocabulary = taxonomy_vocabulary_load(reset($vids));
  363. }
  364. return $vocabulary;
  365. }
  366. /**
  367. * Form element validate handler for taxonomy term autocomplete element.
  368. *
  369. * {@inheritdoc}
  370. *
  371. * @see taxonomy_autocomplete_validate()
  372. */
  373. function entity_translation_taxonomy_autocomplete_validate($element, &$form_state) {
  374. $value = array();
  375. list($id) = entity_extract_ids($element['#entity_type'], $element['#entity']);
  376. $is_new = !isset($id);
  377. // This is the language of the parent entity, that we will be applying to new
  378. // terms.
  379. $parent_handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
  380. $langcode = !empty($form_state['entity_translation']['form_langcode']) ?
  381. $form_state['entity_translation']['form_langcode'] : $parent_handler->getActiveLanguage();
  382. // Handle in-place translation.
  383. if (_entity_translation_taxonomy_autocomplete_translation_enabled($element, $form_state)) {
  384. // The referenced terms cannot change, so we just need to collect their term
  385. // identifiers. We also build a map of the corresponding deltas for later
  386. // use.
  387. $deltas = array();
  388. foreach (element_children($element) as $delta) {
  389. $tid = $element[$delta]['#tid'];
  390. $deltas[$tid] = $delta;
  391. $value[$delta]['tid'] = $tid;
  392. }
  393. // Save term translations.
  394. $entity_type = 'taxonomy_term';
  395. $name_field = 'name_field';
  396. $source_langcode = $parent_handler->getSourceLanguage();
  397. // This is a validation handler, so we must defer the actual save to the
  398. // submit phase.
  399. $terms_to_save = &$form_state['entity_translation']['taxonomy_autocomplete'][$element['#entity_type']][$id][$element['#field_name']];
  400. foreach (taxonomy_term_load_multiple(array_keys($deltas)) as $term) {
  401. // This is also the right context to perform validation.
  402. $term_translation = $element[$deltas[$term->tid]]['#value'];
  403. if (!$term_translation) {
  404. $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
  405. drupal_set_message(t('The translations for %field_label cannot be empty.', array('%field_label' => $instance['label'])), 'error', FALSE);
  406. continue;
  407. }
  408. $handler = entity_translation_get_handler($entity_type, $term);
  409. $translations = $handler->getTranslations();
  410. $term_langcode = $handler->getLanguage();
  411. $typed_langcode = $term_langcode != LANGUAGE_NONE ? $langcode : $term_langcode;
  412. // Create a new translation in the active language, if it is missing.
  413. if (!isset($translations->data[$typed_langcode]) && $typed_langcode != LANGUAGE_NONE) {
  414. $translation = array(
  415. 'language' => $typed_langcode,
  416. 'source' => $source_langcode,
  417. 'uid' => $GLOBALS['user']->uid,
  418. 'status' => 1,
  419. 'created' => REQUEST_TIME,
  420. 'changed' => REQUEST_TIME,
  421. );
  422. $translation_values = array(
  423. $name_field => array($typed_langcode => array(array('value' => $term_translation))),
  424. );
  425. $handler->setTranslation($translation, $translation_values);
  426. $terms_to_save[] = $term;
  427. }
  428. // Otherwise we just update the existing translation, if it has changed.
  429. // If the term is language-neutral, we just update its main value. This is
  430. // expected to happen normally, but could when referencing existing terms.
  431. elseif ($term_translation != _entity_translation_taxonomy_label($term, $typed_langcode)) {
  432. $term->{$name_field}[$typed_langcode][0]['value'] = $term_translation;
  433. $terms_to_save[] = $term;
  434. }
  435. }
  436. }
  437. // Autocomplete widgets do not send their tids in the form, so we must detect
  438. // them here and process them independently.
  439. elseif ($tags = $element['#value']) {
  440. $entity_type = 'taxonomy_term';
  441. $field = field_widget_field($element, $form_state);
  442. $vocabulary = _entity_translation_taxonomy_reference_get_vocabulary($field);
  443. $typed_tags = drupal_explode_tags($tags);
  444. // Collect existing terms by name.
  445. $existing_terms = array();
  446. foreach (_entity_translation_taxonomy_autocomplete_widget_get_terms($element) as $term) {
  447. $name = _entity_translation_taxonomy_label($term, $langcode);
  448. $existing_terms[$name] = $term;
  449. }
  450. // Select terms that match by the (translated) name.
  451. $query = new EntityFieldQuery();
  452. $query->addTag('taxonomy_term_access');
  453. $query->entityCondition('entity_type', $entity_type);
  454. $query->propertyCondition('vid', $vocabulary->vid);
  455. if ($langcode != LANGUAGE_NONE && module_invoke('title', 'field_replacement_enabled', $entity_type, $vocabulary->machine_name, 'name')) {
  456. $language_group = 0;
  457. // Do not select already entered terms.
  458. $name_field = 'name_field';
  459. $column = 'value';
  460. $query->fieldCondition($name_field, $column, $typed_tags, NULL, NULL, $language_group);
  461. // When we are creating a new entity, we cannot filter by active language,
  462. // as that may have not be applied to the autocomplete query.
  463. if (!$is_new) {
  464. $query->fieldLanguageCondition($name_field, array($langcode, LANGUAGE_NONE), NULL, NULL, $language_group);
  465. }
  466. }
  467. else {
  468. $query->propertyCondition('name', $typed_tags);
  469. }
  470. $result = $query->execute();
  471. // When we are creating a new entity, the language used for the autocomplete
  472. // query is the current content language, so we should use that to update
  473. // the map of existing terms.
  474. if (!empty($result[$entity_type])) {
  475. $typed_langcode = !$is_new ? $langcode : $GLOBALS['language_content']->language;
  476. foreach (taxonomy_term_load_multiple(array_keys($result[$entity_type])) as $term) {
  477. $name = _entity_translation_taxonomy_label($term, $typed_langcode);
  478. $existing_terms[$name] = $term;
  479. }
  480. }
  481. // Now collect the identifiers for the various terms and update the taxonomy
  482. // reference field values.
  483. foreach ($typed_tags as $delta => $typed_tag) {
  484. // See if the term exists in the chosen vocabulary and return the tid.
  485. // Otherwise create a new 'autocreate' term for insert/update.
  486. if (isset($existing_terms[$typed_tag])) {
  487. $term = $existing_terms[$typed_tag];
  488. }
  489. else {
  490. $term = (object) array(
  491. 'tid' => 'autocreate',
  492. 'vid' => $vocabulary->vid,
  493. 'name' => $typed_tag,
  494. 'vocabulary_machine_name' => $vocabulary->machine_name,
  495. );
  496. $handler = entity_translation_get_handler($entity_type, $term);
  497. $handler->setOriginalLanguage($langcode);
  498. $handler->initTranslations();
  499. }
  500. $value[] = (array) $term;
  501. }
  502. }
  503. form_set_value($element, $value, $form_state);
  504. }
  505. /**
  506. * Term-specific implementation of hook_field_attach_submit().
  507. */
  508. function entity_translation_taxonomy_term_field_attach_submit($entity_type, $entity, $form, &$form_state) {
  509. // Finally save in-place translations
  510. if (!empty($form_state['entity_translation']['taxonomy_autocomplete'])) {
  511. foreach ($form_state['entity_translation']['taxonomy_autocomplete'] as $entity_type => $entity_type_data) {
  512. foreach ($entity_type_data as $id => $field_name_data) {
  513. foreach ($field_name_data as $field_name => $term_data) {
  514. if (!is_array($term_data)) {
  515. continue;
  516. }
  517. foreach ($term_data as $term) {
  518. entity_translation_entity_save('taxonomy_term', $term);
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }