To reproduce the problem:
1) Have upload image module installed and enable "Create attached images" and "Delete attached images" for the content type
to be added in step 2.
2) Add a child node to a node with "Create new ..." link in Link Operations.
3) Before submitting the new child attach an image to the new node.
4) Press submit. After this what should happen is 1) The new node will be saved 2) upload image module creates a new image node from the attached image. 3) Node relativity attaches the new node to its parent. All of this works ok, but additionally also the newly created image node is attached to the parent of the new node, which I think should not happen.

The cause of the problem is this code in relativity_nodeapi:

function relativity_nodeapi(&$node, $op, $teaser, $page) {
  if ($_GET['parent_node']) {
    $node->parent_node = $_GET['parent_node'] + 0;
  }
  elseif($_POST['parent_node']) {
    $node->parent_node = $_POST['parent_node'] + 0;
  }
}

The code does not take into account that after submit other modules may insert additional nodes resulting the hook_nodeapi
to be called more than once with different nodes as a parameter.
What happens after submit:
1) relativity_nodeapi gets called for the newly created node. Everything works fine.
2) upload_image_nodeapi get called for the newly created node. The function creates the new image node and calls node_submit and node_save. This causes the relativity_nodeapi to be called again for the created image-node. Even though
the image node type is not used in the node relationships, the code above causes the $node->parent_node field to be set.

For me the code below solved the problem. I think somethings like this is a good idea anyway. The current code adds an unnecessary field to all the nodes not using node relationships.

function relativity_nodeapi(&$node, $op, $teaser, $page) {
  if (! variable_get('relativity_type_'.$node->type, FALSE))
    return;
  if ($_GET['parent_node']) {
    $node->parent_node = $_GET['parent_node'] + 0;
  }
  elseif($_POST['parent_node']) {
    $node->parent_node = $_POST['parent_node'] + 0;
  }

Comments

darius’s picture

Your approach would not solve the problem if "image" was an allowed relativity type. We need something better. Ideas?

kerola’s picture

Damn. I guess that writing posts at night is not a good idea. I forgot to mention that my solution is partial as you stated.
Otherwise, I would have prepared a patch.

The problem is that I am totally new to PHP and Drupal so I can only guess around the right solution; I have
only spent a few days developing a web site and learning a bit about both. Here is one guess
with at least couple of assumptions which I am not sure that are correct:

The first assumption is that the case 'insert' in relativity_nodeapi needs only be reached after submit of a new node. That is that there is no correct way to reach it by using the API to insert a node, for example.

The second assumption is that $node->op is set to 'submit' in a case when node is created by user pressing submit. I could not
find documentation stating so but just by using print_r on a node this seems to be the case.

If these assumptions are correct adding an additional requirement of $node->op being 'submit' in the case: 'insert' might be the solution:

 case 'insert':
      if ($node->nid && $node->parent_node && $node->op === 'submit') {

This works for me anyway.

kerola’s picture

There is a small typo in the code. Submit should written with capital S

   case 'insert':
      if ($node->nid && $node->parent_node && $node->op === 'Submit') {
        if (is_array($node->parent_node)) {