You are here

function lingotek_process_entity_xml in Lingotek Translation 7.7

Same name and namespace in other branches
  1. 7.4 lingotek.api.inc \lingotek_process_entity_xml()
  2. 7.5 lingotek.remote.inc \lingotek_process_entity_xml()
  3. 7.6 lingotek.remote.inc \lingotek_process_entity_xml()
2 calls to lingotek_process_entity_xml()
lingotek_entity_download in ./lingotek.module
lingotek_process_field_collection_xml in ./lingotek.remote.inc

File

./lingotek.remote.inc, line 119

Code

function lingotek_process_entity_xml($xml, &$entity, $entity_type, $langcode, $node_based_translation = FALSE, $url_alias_translation = 0) {
  $enabled_with_translation = FALSE;
  $language_list = language_list('language');
  $source_entity = $entity;
  global $language;
  $source_language = $language->language;
  $hook_params = array(
    'entity_type' => $entity_type,
    'entity' => $entity,
    'xml' => $xml,
    'langcode' => $langcode,
  );

  // First allow other modules to manipulate the downloaded content.
  drupal_alter('lingotek_entity_download', $hook_params);

  // Special handling of menu links
  if ($entity_type == 'menu_link') {
    $translation_set = lingotek_get_translation_set($entity->mlid, $entity->menu_name);
    lingotek_process_menu_link_xml($xml, $entity, $entity_type, $langcode, $translation_set);
    return;
  }

  // Set $node_based_translation only if the entity type is a node, inherit otherwise.
  // (The entity could be a field collection or other entity type, underneath)
  if ($entity_type == 'node') {
    $node_based_translation = lingotek_uses_node_translation($entity) ? TRUE : FALSE;
    if ($node_based_translation) {
      $source_entity = lingotek_get_source_node($entity);
    }
  }
  list($id, $vid, $bundle) = lingotek_entity_extract_ids($entity_type, $entity);
  $fields_arrays = array();
  $delta = 0;
  $last_field_name = NULL;
  foreach ($xml as $field_name => $content) {

    // URL alias translation (currently available for nodes only).
    if ($entity_type == 'node') {

      // Check if we use normal title instead of field title.
      if (variable_get('lingotek_translate_original_node_titles', FALSE) && $field_name == 'title' && $node_based_translation) {

        // Special characters comes encoded from Lingotek. Decode them here.
        $target = decode_entities(htmlspecialchars_decode($content));
        $filtered_target = filter_xss($target);
        $entity->title_field[$langcode][$delta]['value'] = $filtered_target;
        $entity->title_field[$langcode][$delta]['safe_value'] = $filtered_target;
        $entity->title = $filtered_target;
        $entity->current_title = $filtered_target;
        db_update('node')
          ->fields(array(
          'title' => $filtered_target,
        ))
          ->condition('nid', $id)
          ->execute();
        db_update('node_revision')
          ->fields(array(
          'title' => $filtered_target,
        ))
          ->condition('vid', $vid)
          ->execute();

        // Set URL alias.
        if ($url_alias_translation == 2 && module_exists('pathauto') && $entity->language != LANGUAGE_NONE) {
          module_load_include('inc', 'pathauto');
          $uri = entity_uri('node', $entity);
          $entity_unchanged = entity_load_unchanged('node', $id);
          pathauto_create_alias('node', 'update', $uri['path'], array(
            'node' => clone $entity_unchanged,
          ), $entity->type, $langcode);
        }
      }
      elseif ($field_name == 'url_alias' && $url_alias_translation == 1) {
        lingotek_save_url_alias($content, $entity, $langcode);
        $last_field_name = $field_name;
        continue;
      }
    }

    // Handle multiple instances of the same field (handled in Drupal using 'delta')
    $delta = $field_name == $last_field_name ? ++$delta : 0;

    // Get field info or skip if not found
    $field_info = field_info_field($field_name);
    $field_type = $field_info['type'];
    $field_module = $field_info['module'];
    if (empty($field_info)) {
      LingotekLog::warning('Invalid field downloaded from Lingotek: @field_name.  The field may no longer exist; or if you have upgraded the Lingotek module since you last uploaded the document, the document format may have changed.  You should re-upload @entity_type #@entity_id', array(
        '@field_name' => $field_name,
        '@entity_type' => $entity_type,
        '@entity_id' => $id,
      ));
      $last_field_name = $field_name;
      continue;
    }
    $translatable_field = !empty($field_info['translatable']);
    $field_language = $node_based_translation && !$translatable_field ? LANGUAGE_NONE : $langcode;

    // Field-Collection Fields: Pull the underlying entities and recurse.
    if (module_exists('field_collection') && $field_info['type'] == 'field_collection') {
      lingotek_process_field_collection_xml($content, $entity_type, $entity, $field_name, $delta, $langcode, $node_based_translation);
      $last_field_name = $field_name;
      continue;
    }

    // Field-Collection Entities: Set all field-collection fields to translatable,
    // if the parent node is not using node-based translation.
    if ($entity_type == 'field_collection_item' && !$node_based_translation && $field_info['translatable'] != 1) {
      $field_info['translatable'] = 1;
      field_update_field($field_info);
    }

    // Handle individual fields from here down.
    $insert_array = array(
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'entity_id' => $id,
      'revision_id' => $vid === NULL || $entity_type == 'comment' ? $id : $vid,
      'language' => $field_language,
      'delta' => $delta,
      'deleted' => '0',
    );
    foreach ($content as $column_name => $text) {
      $db_column_name = $field_info['field_name'] . '_' . $column_name;
      $unfiltered_text = lingotek_unfilter_placeholders(decode_entities((string) $text->element));
      $insert_array[$db_column_name] = $unfiltered_text;

      // Truncate too-long title fields
      if ($db_column_name == 'title_field_value' && strlen($insert_array[$db_column_name]) > 254) {
        $insert_array[$db_column_name] = substr($insert_array[$db_column_name], 0, 254);
        $unfiltered_text = $insert_array[$db_column_name];
        $langcode = $insert_array['language'];
        LingotekLog::info('The @lang (@langcode) title was truncated, since the translation exceeded the maximum of 255 characters.', array(
          '@lang' => $language_list[$langcode]->name,
          '@langcode' => Lingotek::convertDrupal2Lingotek($langcode),
        ));
      }
      $curr_field_data =& $entity->{$field_name};
      $curr_field_data[$field_language][$delta][$column_name] = $unfiltered_text;
    }

    // Try to carry over untranslated columns.
    try {
      $source_field_data = field_get_items($entity_type, $source_entity, $field_name);
    } catch (EntityMalformedException $e) {
      $source_field_data = array();
    }
    $curr_field_data =& $entity->{$field_name};
    lingotek_add_untranslated_source_fields($insert_array, $source_field_data, $curr_field_data, $field_info, $entity->language, $delta);
    if ($field_type === 'link_field' && $field_module === 'link') {
      $db_column_name = $field_info['field_name'] . '_' . $column_name;
      $link_attributes_serialized = lingotek_process_link_field_attributes($curr_field_data, $insert_array, $db_column_name);
      $insert_array[$db_column_name] = $link_attributes_serialized;
    }
    if (module_exists('entity_translation')) {
      $source_published_setting = LingotekSync::getEntityTranslationPublishedSetting($id);
      $enabled_with_translation = entity_translation_enabled_bundle($entity_type, $bundle);
    }

    // Save to both field_data tables and field_revision tables
    $field_table_names = array(
      'field_revision_' . $field_name,
      'field_data_' . $field_name,
    );
    foreach ($field_table_names as $fname) {

      // Node-based translations within a field-based translation system by default
      // should also have the language-neutral fields saved for normalization if
      // underneath a field collection. This prevents source-language content
      // from blocking out translated content from being shown.
      if ($node_based_translation && $entity_type == 'field_collection_item' && $field_language != LANGUAGE_NONE) {
        $insert_array['language'] = LANGUAGE_NONE;
        lingotek_save_field_record($fname, $insert_array);
        $insert_array['language'] = $field_language;
      }
      else {
        lingotek_save_field_record($fname, $insert_array);
      }
    }
    if (module_exists('entity_translation') && $insert_array['language'] !== $source_language && $enabled_with_translation) {
      $new_status = lingotek_set_translation_published_state($id, $entity_type, $insert_array['language'], $source_published_setting);
      if (!is_null($new_status)) {
        $entity->status = $new_status;
      }
    }

    // After every field insert, reset the caches and reload the entity
    // TODO: Do we really need to do this every time we save a field, or
    // can we just do this once at the end?
    cache_clear_all('field:' . $entity_type . ':' . $id, 'cache_field');
    entity_get_controller($entity_type)
      ->resetCache(array(
      $id,
    ));

    //Set URL alias
    if ($field_name == 'title_field' && $url_alias_translation == 2 && module_exists('pathauto') && $entity->language != LANGUAGE_NONE) {
      lingotek_save_pathauto_alias($entity_type, $entity, $langcode);
    }
    $last_field_name = $field_name;
  }

  // Update changed timestamp for nodes
  if ($node_based_translation && $entity_type === 'node') {
    $entity->changed = time();
    entity_save($entity_type, $entity);
  }
}