Normally when a new node inserted to drupal, xmlsitemap should rebuild the sitemap on next cron task. but i found it never on 6.x-2.x-dev.
I look into the code and found function xmlsitemap_node_create_link(&$node) cause this issue.
note the line:
$node->xmlsitemap['access'] = $node->nid ? (bool) node_access('view', $node, drupal_anonymous_user()) : 1;
$node->xmlsitemap['access'] will always has a value '0' for new submitted node.
because when this function being called,the access data for this node is empty on the database.
why?
see the code from node_save($node)
// Call the node specific callback (if any).
node_invoke($node, $op);
node_invoke_nodeapi($node, $op);
// Update the node access table for this node.
node_access_acquire_grants($node);
Let me know if i am wrong.
xmlsitemap_node.module
function xmlsitemap_node_create_link(&$node) {
if (!isset($node->xmlsitemap)) {
$node->xmlsitemap = array();
}
$node->xmlsitemap += array(
'type' => 'node',
'id' => $node->nid,
'subtype' => $node->type,
'loc' => 'node/'. $node->nid,
'status' => variable_get('xmlsitemap_node_status_' . $node->type, 1),
'status_default' => variable_get('xmlsitemap_node_status_' . $node->type, 1),
'status_override' => 0,
'priority' => variable_get('xmlsitemap_node_priority_' . $node->type, 0.5),
'priority_default' => variable_get('xmlsitemap_node_priority_' . $node->type, 0.5),
'priority_override' => 0,
'changefreq' => $node->nid ? xmlsitemap_calculate_changefreq(xmlsitemap_node_get_timestamps($node)) : 0,
'changecount' => $node->nid ? count(xmlsitemap_node_get_timestamps($node)) - 1 : 0,
);
// The following values must always be checked because they are volatile.
$node->xmlsitemap['lastmod'] = isset($node->changed) ? $node->changed : REQUEST_TIME;
$node->xmlsitemap['access'] = $node->nid ? (bool) node_access('view', $node, drupal_anonymous_user()) : 1;
$node->xmlsitemap['language'] = isset($node->language) ? $node->language : '';
return $node->xmlsitemap;
}
Comments
Comment #1
dave reidHmm, not exactly critical since its not exposing secret nodes and the next time a node is saved the correct access value is saved, but I'm not sure how this could be fixed from XML sitemap. This would appear to be either by design or a core bug.
Comment #2
dave reidI filed a core issue at #690520: Calling node_access() from inside hook_node_save() results in wrong access for new nodes and I'll try and get some higher-ups involved in the issue to see what they recommend.
Comment #3
dave reidComment #4
ricsonhoo commentedI feel it is critical, since the access is always 0 for new node, then $flag will has value FALSE, then variable "xmlsitemap_regenerate_needed" will never has value TRUE. until someday, maybe 5 days maybe 3 month later you update a node. (I am not sure if update a node will trigger a "access" recheck on all nodes?)
THEN no matter how many new nodes you have posted, it will never trigger a sitemap rebuild action, 'cause the cron will break on varible xmlsitemap_regenerate_needed == FALSE,
call "node_access_acquire_grants($node); " inside function "xmlsitemap_node_create_link" will work,
Comment #5
dave reidCore and a good majority of users aren't using any kind of node access modules, so this function returns the proper values for them. This only returns the improper value if there are node access/grant modules enabled.
Comment #6
avpadernoCalling
node_access_acquire_grants(), which is already called from Drupal core modules, doesn't seem a correct work-around.Maybe it is better to first verify if there are modules implementing
hook_node_grants(), and then take the necessary actions; the node data could be marked as needing updats, and the module could verify later if the anonymous user has view access to the node.Comment #7
dave reidComment #8
dave reidI think #786484: Use a 'link update' queue for delayed link changes is going to be how we solve this problem. Instead of trying to update the links from within hook_node_update() or hook_node_insert(), we put them into a 'link update queue' and process them at the end of the page request or during cron.
Any alternative ideas are welcome, but I think that's our best option.
Comment #9
petrica.martinescu commentedTemporary solution: altering the query used for selecting elements that goes into sitemap.xml file, using an edited node access function. There is actually a left join with the node access table only for node items in the sitemap table (the access field is not taken into account anymore). Add the following code into a custom module.
Comment #10
alex_wang commentedI do a patch which can rebuild the xmlsitemap in every cron....
This is not a proper solution but at least can get a reliable result.
Comment #11
Anonymous (not verified) commented#10 is off topic for this issue. Please find or create an appropriate issue for it.
Comment #12
madmanmax commented#4 is actually onto something:
node_access_acquire_grantswill call in the endnode_access_write_grantswhich will first wipe all records fromnode_accessfor that given node. I agree it's not the best solution but for now it's just one line of code that temporary fixes the problem.Comment #13
nagba commentedThe issue with #4 is that it is possible to get a SQL Integrity error. Say, you have a site with a node access module enabled and you create a new node. With the change the node_access_acquire_grants will save a row into the table, and then later node_save will try to save the same thing again. The queue approach feels safer, also probably going to include less hacks.
Comment #14
mstef commentedI'm having this problem with Workbench moderation. In some cases, when hook_node_update() is invoked, xmlsitemap_node_view_access() will return the access based on the OLD node (obviously a big problem). It seems to me that the issue is the grants table being outdated at this point.
This is how I resolved for my case. Perhaps the solution might help for a "fix" for this module..
Comment #15
mstef commentedDoes seem a bit strange that the grants would be updated after the hooks... (in core)
Comment #16
kristen polThis has been a (difficult) long standing issue and there does not appear to be progress on the core bug side of things or on the 'link update' queue side of things so I've attached a patch with the temporary "fix" from @ricsonhoo on #4 so that non-coders can apply the patch to get this working. Thanks @ricsonhoo !
Comment #17
chrisdarke42 commentedThat patch in #16 based off #4 works great, node access now gets set to 1. I haven't tried anything beyond published/unpublished, but that is all I need right now, and for that it works perfectly.
Comment #18
rudi teschner commentedThanks for the patch. Even though "temporary", it solves the problems and the sitemap now regenerates properly.
Comment #19
djdevinConfirmed this is still an issue and this fixes the issue.
During node save, "access" was still being set to 0 even though anonymous users could view the content just fine once saved.
Comment #20
bwaindwain commentedhere's an updated version of #16 patch to work with latest 7.x-2.x. thanks @kristen-pol and @ricsonhoo
Comment #21
djdevinComment #25
djdevinFixed in #2986809: Update SA-CONTRIB-2018-053 in 7.x-2.x branch, saved nodes now end up in a queue that is processed later.