drupal_goto in nodeapi 'view' stops CCK data saving

Morbus Iff - March 29, 2007 - 12:15
Project:Content Construction Kit (CCK)
Version:5.x-1.x-dev
Component:content.module
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active (needs more info)
Description

Everything was working beautifully in 1.2 (I think), and I just upgraded to 5.x-dev. Now, my original code (which integrated CCK nodes as user profiles) is failing for various reasons. The basic goal is to have user/#/profile map to a CCK profile node, editting only. Users can never view /node/# if # is a user_profile node. Here's my menu hook:

if ((arg(0) == 'user' && is_numeric(arg(1)) && arg(1) > 0)) {
  $access = ($user->uid == arg(1)) ? 1 : user_access('administer users');
  $nid  = db_result(db_query("SELECT nid FROM {node} WHERE type = '%s' AND uid = %d", 'user_profile', arg(1)));

  $items[] = array(
    'access'             => $access,
    'callback'           => 'drupal_get_form',
    'callback arguments' => array('user_profile_node_form', node_load($nid)),
    'path'               => 'user/'. arg(1) .'/profile',
    'title'              => t('Profile'),
    'type'               => MENU_LOCAL_TASK,
  );
}

The above works beautifully - saving and so forth happens magically. I use $form['#redirect'] to make sure any submits get sent back to user/#/profile. Now, to stop users from viewing the nodes directory, I use the following in nodeapi 'view':

  switch ($op) {
    case 'view':
      if ($node->type == 'user_profile') {
        // no direct viewing of the profile node.
        drupal_goto('user/'. $node->uid .'/profile');
      break;
  }

Kablooey! While the redirect functions properly, this seems to blow up CCK I/O somehow: I can still see the node data in user/#/profile, but no changes are actually saved when the form is submitted. This also happens if I hit node/#/edit manually: any use of drupal_goto just seems to cause CCK to not save data. Why is this happening?

With the above drupal_goto in place, the following also fails:

      $node = new stdClass;
      $node->type  = 'user_profile';
      $node->uid   = 5;
      $node->title = 'whee 2';
      $node->status  = 1; $node->comment = 0;
      $node->promote = 0; $node->sticky = 0;
      $node->field_country  = array('key' => 'us');
      $node->field_zip_code  = array('0' => array('value' => 'monkey'));
      node_save($node);

If I remove the drupal_goto, the zip_code is saved properly, but not the field_country.

#1

Morbus Iff - March 29, 2007 - 12:20
Title:drupal_goto in 'view'; no saves occur, node_save broken?» drupal_goto in nodeapi 'view' stops CCK data saving

Update: field_country IS saving properly when I remove the drupal_goto.

Nutshell: drupal_goto in hook_nodeapi 'view' stops CCK from saving data. Why?

#2

RobRoy - April 5, 2007 - 02:12

<?php
 
switch ($op) {
    case
'view':
      if (
$node->type == 'user_profile') {
       
// no direct viewing of the profile node.
       
drupal_goto('user/'. $node->uid .'/profile');
      break;
  }
?>

In that code snippet it looks like you're missing a }.

#3

Morbus Iff - April 9, 2007 - 14:26

Typo in transcription only.

#4

deelight - June 18, 2007 - 13:47

I have the exact same problem.
It seems that a call to node_save() triggers the hook_nodeapi() function, with operation 'view'.

I personnaly have a loop to create nodes, but only one gets created because of the redirection.

#5

deelight - June 18, 2007 - 14:02

further investigation lead me to the content_pathauto_node() function in cck/content_pathauto.inc.

This is what happens (if i'm right) :

node_get_placeholders() (pathauto/pathauto_node.inc) gets called when updating a node. At the end of this function, we have a call to :

module_invoke_all('pathauto_node', 'values', $node);

This triggers the implementation of hook_pathauto_node() we have in cck/content_pathauto.inc.

In this function, we can see :

// Allow modules to change $node->body before viewing.
node_invoke_nodeapi($node, 'view', false, false);

If i'm still right, this triggers the "view" operation of hook_nodeapi for that node.

#6

moshe weitzman - April 17, 2008 - 13:17
Project:Content Construction Kit (CCK)» Pathauto
Version:5.x-1.x-dev» 6.x-1.x-dev
Component:General» Code

Yes, that pathauto logic has bitten me badly as well. Not sure how it could be improved.

#7

greggles - April 19, 2008 - 19:41

Me neither.

And without a simplified test case and since I haven´t seen this before I don´t know what more to do.

That actually came from before I took over - perhaps mikeryan will know what to do.

#8

Morbus Iff - April 19, 2008 - 20:47

greggles: there's a simplified test case in the issue above.

a) Take the second code block in the description as the hook_nodeapi().

b) Take the third code block as the creation of a CCK node with two custom fields, programatically.

#9

greggles - April 20, 2008 - 23:02
Version:6.x-1.x-dev» 5.x-2.x-dev

I just tried to look into the advice from deelight in #5 and cannot find those lines of code in pathauto-node.inc for 5.x-2.x (nor the 6.x branch which is based on 5.x-2.x).

Morbus - which version are you using? And which version of Token? And which of CCK? There are several pieces here all moving at the moment...

#10

Morbus Iff - April 21, 2008 - 00:15

greggles: unfortunately, I'm no longer working on that particular codebase (nor have access to it) :(

#11

greggles - April 21, 2008 - 21:19
Status:active» active (needs more info)

Aha. Well then...I guess I'm not sure what to do here.

One other thought I had before seeing your response, I think that a drupal_goto is the wrong thing to do and instead setting the $_REQUEST['destination'] instead. Right?

@moshe? is there something you specifically desire to have happen?

#12

mikeryan - April 21, 2008 - 22:21
Project:Pathauto» Content Construction Kit (CCK)
Version:5.x-2.x-dev» 5.x-1.x-dev
Component:Code» content.module

Don't have time right now to build a reproducible case, but looking at the source the issue appears to be in CCK's content_pathauto.inc hook under Drupal 5 - it's building a node for viewing in order to pluck out the field values for substitution (and doing it twice!). The Drupal 6 version of CCK calls drupal_render() to accomplish the same thing, that looks cleaner to me...

 
 

Drupal is a registered trademark of Dries Buytaert.