The module calls node_save() and passes it a node object not obtained from node_load().
That causes problems with modules adding property to the node objects in hook_nodeapi() because hook_nodeapi() is not being called with $op equal to 'load' (therefore the module cannot load the properties from its database table), but it's called with $op equal to 'insert', or 'update'.

When the module tries to save its own node properties (that should be already initialized) it fails.

CommentFileSizeAuthor
#13 feedapi_node_create.patch3.14 KBaron novak

Comments

avpaderno’s picture

Priority: Normal » Critical

I am changing the priority as this issue causes interference with other modules.

avpaderno’s picture

I am referring to the code at line 277 where the code is $node = new stdClass();; at line 355 the code is then node_save($node);.
The module calls node_object_prepare(), but that function calls node_invoke_nodeapi($node, 'prepare'), not node_invoke_nodeapi($node, 'load') (see the function documentation). In this way, all the node properties a module would add into the node are not initialized.

Anonymous’s picture

This is really murdering all of the data added to the node object during a node via hook_nodeapi. The xmlsitemap module doesn't have a chance since the updated node looses its data from the object before its saved. I'll look at uploading a patch soon.

avpaderno’s picture

Priority: Normal » Critical

I think that the problem is not limited to XML Sitemap, but it's common to all the modules that add additional data in hook_nodeapi('load'), and save them in hook_nodeapi('insert') (or hook_nodeapi('update')).

avpaderno’s picture

Checking better the code, the part of the code I am referring to is executed for content that the project modules import from a feed; being this the case, the module is not modifying an existing node, but it's creating a new node (therefore there should not be any lose of data added by third party modules).
I still think that the way used by the module to initialize the node object it creates is not the correct one.

aron novak’s picture

Priority: Critical » Normal

See this:
http://lists.drupal.org/pipermail/development/2008-March/029152.html
If you're ready to step up with a fast and sane way to create nodes (with a patch), i'd be the happiest to trash out the old code.

avpaderno’s picture

The code could simply add a call to node_invoke_nodeapi($node, 'load'). It doesn't resolve all the problems, but at least it would be more compatible with the modules that use hook_nodeapi('load'),and it would not break the modules that load their data in hook_nodeapi('load'), and save their data (after they are changed by the user) in hook_nodeapi('insert') (or hook_nodeapi('update')).

pillarsdotnet’s picture

Noticed this problem when my feedapi-created forum topics didn't show up in forum listings.

Tried adding a call to node_invoke_nodeapi($node, 'load') before the node_object_prepare() call.

No joy.

Tried adding a node_submit() call.

No joy.

lotsa-lotsa-lotsa debugging output -- gonna try creating a new content type and re-creating forums via views.

Wish me luck...

metamatsu’s picture

The uid in the {node_revisions} table is not getting set correctly for feedapi-created nodes.

It is always getting set to uid=0, even though the uid is set properly in the {node} table.

Could this be what is causing problems for other modules like pathauto?

http://drupal.org/node/201110#comment-1488576
http://drupal.org/node/432454#comment-1471514

hefox’s picture

A use case where basically they wanted to keep their feeds up to date but add extra information like taxonomy and cck.
However since feedapi was not calling node_load that data was being lost (calling node_invoke_nodeapi load for new nodes).
Here is part of the diff; we haven't had the time to update to newest feedapi so haven't had the time to make a real patch ATM.

> if (!$feed_item->nid) {
> $node = new stdClass();
> node_invoke_nodeapi($node, 'load');
> // Determines the node type.
> if (empty($settings['content_type'])) {
> $ct_types = node_get_types();
> $ct_options = array();
> if (is_array($ct_types)) {
> foreach ($ct_types as $key => $data) {
> if (!feedapi_enabled_type($key)) {
> $ct_options[$key] = $data->name;
> }
> }
> }
> if (array_key_exists('story', $ct_options)) {
> $node->type = 'story';
> }
> else {
> $node->type = current(array_keys($ct_options));
> }
> }
> else {
> $node->type = $settings['content_type'];
> }
>
> if (feedapi_enabled_type($node->type)) {
> if ($error_msg !== TRUE) {
> drupal_set_message(t('Please disable FeedAPI for !item content-type.', array('!item' => $node->type)), 'error');
> $error_msg = TRUE;
> }
> return FALSE;
> }
>
> // Get the default options from the cont
> $options = variable_get('node_options_'. $node->type, FALSE);
> if (is_array($options)) {
> $node->status = in_array('status', $options) ? 1 : 0;
> $node->promote = in_array('promote', $options) ? 1 : 0;
> $node->sticky = in_array('sticky', $options) ? 1 : 0;
> }
> else {
> $node->status = 1;
> }
> } else {
> $node = node_load($feed_item->nid);
> }

This does not address the issue picking up data /changes to the form during hook_form_alter. Drupal execute would do that, but that'd defiantly be a lot slower. (I've used it a few times to create /update nodes). Could patch it for drupal execute and batchapi also for when running manual refresh (personally I've only used modules patched for batch api so not to knowledgeable about it).

My suggestion is for those with that problem figure out what changes the modules in conflict are doing and mock it in presave or such :/.

socialnicheguru’s picture

Priority: Critical » Normal

where does this snippet go? I'd be willing to test if I knew which file and approx line number and approx what it will replace.

hefox’s picture

Ooops, sorry for not putting it.

At home and my set up is lacking and don't have the altered file in front of me, so I'm based off the above, memory, and looking at a fresh copy of feedapi.

It's in feedapi_node => feedapi_node.module
The function is function _feedapi_node_save
Around the area where it says "Constructs the node object."

(That function is both update and save; is called by _feedapi_node_update with nid in the $feed_item of the old node).

I haven't looked to see if they've changed anything specifically here (since I was using an old version), so I suggest just redoing what I did instead of that snippit;
in an if not nid, move everything related to creating a new node together including a new call near the top to node_invoke_nodeapi($node, 'load') if nid isn't supplied
else node_load($feed_item->nid)

aron novak’s picture

Status: Active » Needs review
StatusFileSize
new3.14 KB

Let's give drupal_execute a try. I know that it's slow but if people have so many headaches with the current situation, maybe it's worth to try.
Here is a patch. The patch: does not support cross-feed deduping and feedapi_inherit.
Please try it out and tell if your node-related problems have gone or not.
If you can confirm that this approach is seamless (but slow), we can consider to make this as the default way to create nodes.

aron novak’s picture

The patch is okay at the moment, but likely won't apply soon (because of planned commits)
Here is a ready-to-use package, which includes the patch of #13 : http://aron.novaak.net/files/feedapi.zip
The tests and the feedbacks are really welcomed!

avpaderno’s picture

I still find easier to make third-party modules kick in by adding a code line like node_invoke_nodeapi($node, 'load').

aron novak’s picture

#15: as i know, for example CCK field default values are not propagated by only this line

avpaderno’s picture

Looking at the code implemented by cck.module I would think that calling node_invoke_nodeapi() is enough to populate the node object with data coming from the CCK fields.

Maybe I misunderstood the following code, taken by that module:

/**
 * Load data for a node type's fields.
 * Implementation of hook_nodeapi 'load' op.
 *
 * When loading one of the content.module nodes, we need to let each field handle
 * its own loading. This can make for a number of queries in some cases, so we
 * cache the loaded object structure and invalidate it during the update process.
 */
function content_load(&$node) {
  $cid = 'content:'. $node->nid .':'. $node->vid;
  if ($cached = cache_get($cid, content_cache_tablename())) {
    foreach ($cached->data as $key => $value) {
      $node->$key = $value;
    }
  }
  else {
    $default_additions = _content_field_invoke_default('load', $node);
    if ($default_additions) {
      foreach ($default_additions as $key => $value) {
        $node->$key = $value;
      }
    }
    $additions = _content_field_invoke('load', $node);
    if ($additions) {
      foreach ($additions as $key => $value) {
        $node->$key = $value;
        $default_additions[$key] = $value;
      }
    }
    cache_set($cid, $default_additions, content_cache_tablename());
  }
}
aron novak’s picture

#17 - Kiam, it seems that you're right. i will double check if it works correctly. In fact drupal_execute is somewhat hackish, so i'd be really happy to use only one line to solve many problems :)

alex_b’s picture

Status: Needs review » Needs work

drupal_execute() is going to be too slow.

The core issue is that if feedapi does an update, there is no node_load() before it does a node_save(). drupal_execute() would slow down insert and update.

Why don't we add a node_load() when in updateing a node and make it optional with a hidden but documented drupal variable?

aron novak’s picture

"The core issue is that if feedapi does an update, there is no node_load() before it does a node_save()." - just a note: this is not only about the updates. This is a problem at the node create process as well, for example CCK fields are not populated with the default values.
See this: http://drupal.org/node/489046

pillarsdotnet’s picture

I haven't used feedapi in a long time. Is this still an issue, or should it be closed?

Anonymous’s picture

The maintainer will have to answer but if no patching w.r.t. the invalid object being passed to node_save, then it is still a bug. That said however based on the project page this module is replaced by the feeds module so the bug may forever reside as a "known issue" in this queue until D6 is no longer supported.

pillarsdotnet’s picture

Status: Needs work » Closed (won't fix)