Once a referenced not gets deleted, the edit form field on the referenced node gets trashed.
I think the "normal" thing to do is delete all references to that deleted node.

I have a bare idea of how to do it but dont have the in-deep knowledge on CCK to make it.
My pseudo-php-code looks like:

function nodereference_nodeapi($node, $op) {
    switch ($op) {
      case 'delete':
         foreach( nodereferences fields  as $field) {
              if ($field->stored_as_table) {
                  sql(delete from $field->table where $field->referencednode_nid=$node->nid);
              } else {
                  sql(update $field->table set $field->referencednode_nid=null where $field->referencednode_nid=$node->nid;
              }
         }
    } 
}

I guess there is much more to do (update/clear caches, update reference values indexes,...)

CommentFileSizeAuthor
#2 nodereference_delete_dead_references.patch2.15 KBdman

Comments

dman’s picture

Here's one for my needs.

/**
 * Ensure that pointers are not left dangling when a nodereference target is
 * deleted.
 * Going straight at the Database because I can't see any API for this type of
 * housekeeping.
 */
function nodereference_nodeapi(&$node, $op, $teaser, $page) {
  switch ($op) {
    case 'delete' :
      $nodereferences = db_query("SELECT field_name FROM {node_field} WHERE type='nodereference'; ");
      // Find all possible nodereference types, and wipe all uses that mention this node
      foreach (db_fetch_object($nodereferences) as $nodereference ) {
        db_query('DELETE FROM content_%s WHERE %s_nid = %d', $nodereference->field_name, $nodereference->field_name, $node->nid);
      }
  }
}

This still seems to be an issue in the latest (5) checkout today.

In the patch here I also added a thing to stop dead links show up when editing the original pointer. In theory you won't need both these fixes at the same time ... but choose which repair-job approach you prefer.

dman’s picture

Category: feature » task
Status: Active » Needs review
StatusFileSize
new2.15 KB

I did attach the patch, really!

ali27’s picture

Component: nodereference.module » content.module
Assigned: Unassigned » ali27
Category: task » feature
Priority: Normal » Critical

i resouled the problem by this code in content.module from line 446 to 510

    case 'update':
      if ($field['multiple']) {
        // Delete and insert, rather than update, in case a field was added.
	db_query('DELETE FROM {'. $db_info['table'] .'} WHERE nid = %d',$node->nid); // line 449
        db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid);
      }

      foreach ($node_field as $delta => $item) {
        $data = array();
        $column_names = array();
        $column_placeholders = array();
        $column_assignments = array();
        foreach ($db_info['columns'] as $column => $attributes) {
          $column_names[] = $attributes['column'];
          if ($item[$column] == '' && !$attributes['not null'] && !$field['required']) {
            $column_placeholders[] = '%s';
            $column_assignments[] = $attributes['column'] .' = %s';
            $item[$column] = 'NULL';
          }
          else {
            switch ($attributes['type']) {
            case 'int':
            case 'mediumint':
            case 'tinyint':
            case 'bigint':
              $column_placeholders[] = '%d';
              $column_assignments[] = $attributes['column'] .' = %d';
              break;
            case 'float':
              $column_placeholders[] = '%f';
              $column_assignments[] = $attributes['column'] .' = %f';
              break;
            default:
              $column_placeholders[] = "'%s'";
              $column_assignments[] = $attributes['column'] ." = '%s'";
            }
          }
          $data[] = $item[$column];
        }
        $data[] = $node->vid;
        $data[] = $node->nid;
        if ($field['multiple']) {
          $data[] = $delta;
        }

        if ($field['multiple']) {
              db_query('INSERT INTO {'. $db_info['table'] .'} ('. implode(', ', $column_names) .', vid, nid, delta) VALUES ('. implode(', ', $column_placeholders) .', %d, %d, %d)', $data);

        }
        else {
          if (db_result(db_query('SELECT COUNT(*) FROM {'. $db_info['table'] .'} WHERE vid = %d AND nid = %d', $node->vid, $node->nid))) {
            db_query('UPDATE {'. $db_info['table'] .'} SET '. implode(', ', $column_assignments) .' WHERE vid = %d AND nid = %d', $data);

          }
          else {
             //delete the old data 
    	    db_query('DELETE FROM {'. $db_info['table'] .'} WHERE nid = %d',$node->nid); // line 504 
            db_query('INSERT INTO {'. $db_info['table'] .'} ('. implode(', ', $column_names) .', vid, nid) VALUES ('. implode(', ', $column_placeholders) .', %d, %d)', $data);

          }
        }
      }
electricmonk’s picture

Did this issue get incorporated into CCK for D5 or D6? I find it to be extremely critical

catorghans’s picture

I need this too for D5. is the code from #3 tested already?

markus_petrux’s picture

Status: Needs review » Closed (duplicate)

This is the oldest issue I've found on the subject: #83929: referential integrity

socialnicheguru’s picture

I think this is causing major issues on my test server