You are here

function biblio_advanced_import_node_presave in Biblio Advanced Import 7

Implements hook_node_presave().

File

./biblio_advanced_import.module, line 40
Biblio add-on.

Code

function biblio_advanced_import_node_presave($node) {
  if ('biblio' == $node->type && empty($node->nid)) {
    $verbose_messages = (bool) variable_get('biblio_advanced_import_verbose_messages', '0');
    biblio_advanced_import_pitfall_workarounds($node);
    if (variable_get('biblio_auto_citekey', 1)) {

      // on new entries, override citekeys generated by parses, depending on settings
      $citekey = biblio_advanced_import_create_citekey($node);
      if ($citekey) {
        $node->biblio_citekey = $citekey;
      }
    }
    $query = db_select('biblio', 'b');
    $alias = $query
      ->innerJoin('node', 'n', 'b.nid = n.nid AND b.vid = n.vid');
    $query
      ->fields('b', array(
      'nid',
    ));
    $skip = FALSE;
    $revision = FALSE;
    switch (variable_get('biblio_advanced_import_duplicate_strategy', 'create duplicate')) {
      case 'create duplicate':
        if ($verbose_messages) {
          drupal_set_message(t('Creating duplicate of node %node_title', array(
            '%node_title' => $node->title,
          )));
        }
        return;
      case 'skip import':

        // There's no way to stop an already running node_save()
        // in a safe way without breaking a batch process.
        // So we do a little trick to realize the 'skip import':
        // We simply replace the current node to be saved by the
        // unmodified oldest duplicate and save this one instead
        $skip = TRUE;
        $query
          ->orderBy('b.nid', 'DESC')
          ->range(0, 1);
        break;
      case 'new rev latest':
        $revision = TRUE;
      case 'update latest':
        $query
          ->orderBy('b.nid', 'DESC')
          ->range(0, 1);
        break;
      case 'new rev oldest':
        $revision = TRUE;
      case 'update oldest':
        $query
          ->orderBy('b.nid', 'ASC')
          ->range(0, 1);
        break;
      case 'new rev all':
        $revision = TRUE;
      case 'update all':
        break;
    }
    $condition_exists = FALSE;
    $or_condition = db_or();
    foreach (variable_get('biblio_advanced_import_detect_duplicate_strategy', array(
      'md5' => 'md5',
    )) as $field) {
      switch ((string) $field) {
        case 'md5':
          $or_condition
            ->condition('b.biblio_md5', biblio_advanced_import_hash($node));
          $condition_exists = TRUE;
          break;
        case 'isbn':
        case 'issn':
        case 'doi':
          $field_property = 'biblio_' . $field;
          if (!empty($node->{$field_property})) {
            $or_condition
              ->condition('b.' . $field_property, $node->{$field_property});
            $condition_exists = TRUE;
          }
          break;
        case 'pubmed':
          if (module_exists('biblio_pm') && !empty($node->biblio_pubmed_id)) {
            $query
              ->innerJoin('biblio_pubmed', 'bp', 'b.nid = bp.nid');
            $or_condition
              ->condition('bp.biblio_pubmed_id', $node->biblio_pubmed_id);
            $condition_exists = TRUE;
          }
          break;
      }
    }
    if ($condition_exists) {
      $query
        ->condition($or_condition);
      $result = $query
        ->execute();
      $is_first_duplicate = TRUE;
      $node_new = (array) $node;
      while ($row = $result
        ->fetchObject()) {

        // there are duplicates:
        $node_old = node_load($row->nid);

        // we need to set this or the node module will throw notices
        // (if this node becomes the one to be really saved instead of the original one)
        $node_old->is_new = FALSE;
        if (!$skip) {

          // update an existing biblio node with new data
          if ($verbose_messages) {
            drupal_set_message(t('Updating node %node_title (node %nid)', array(
              '%nid' => $node_old->nid,
              '%node_title' => $node_old->title,
            )));
          }
          $merge = FALSE;
          foreach ($node_new as $key => $value) {
            if (strpos($key, 'biblio') === 0 && 'biblio_citekey' != $key || strpos($key, 'contributors') === 0 || 'title' == $key) {
              $strategy = variable_get('biblio_advanced_import_merge_strategy', 'override');
              if ('override' == $strategy || 'override but keep additional' == $strategy && !empty($value) || 'add new' == $strategy && !empty($value) && empty($node_old->{$key}) || 'override existing non empty' == $strategy && !empty($node_old->{$key}) || 'override existing non empty with non empty' == $strategy && !empty($value) && !empty($node_old->{$key})) {
                if (!property_exists($node_old, $key) || $node_old->{$key} != $value) {
                  $node_old->{$key} = $value;
                  $merge = TRUE;
                }
              }
            }
          }
          if ($revision && $merge) {
            $node_old->revision = TRUE;
            $node_old->log = t('New revision created automatically by Biblio Advanced Import.');
          }
        }
        else {

          // There's no way to stop an already running node_save()
          // in a safe way without breaking the batch process.
          // So we use a little trick to implement the 'skip import':
          // We replace the current node to be saved with the
          // unmodified first duplicate and let drupal save that one instead.
          if ($verbose_messages) {
            drupal_set_message(t('Skipping update of node %node_title (node %nid)', array(
              '%nid' => $node_old->nid,
              '%node_title' => $node_old->title,
            )));
          }
        }
        if ($is_first_duplicate) {

          // the content of the node being saved gets replaced with the values from the first duplicate node
          // (replacing the whole object with the loaded node did not seem to work
          // so we do it property by property ...)
          $is_first_duplicate = FALSE;

          // clear existing object
          foreach (get_object_vars($node) as $key => $value) {
            unset($node->{$key});
          }

          // copy values over
          foreach (get_object_vars($node_old) as $key => $value) {
            $node->{$key} = $value;
          }
        }
        else {

          // save any other existing duplicates, with values updated
          node_save($node_old);
        }
      }
    }
  }
}