Early Bird Registration for DrupalCon Portland 2024 is open! Register by 23:59 PST on 31 March 2024, to get $100 off your ticket.
By yan on
I wrote a small custom module to delete uncategorized nodes of a defined type that have no taxonomy terms set. I called it "Flush Feeds" since the node type is a feed item. Generally, this is the code:
function flush_feeds_cron() {
flush_feeds('feed_item');
}
function flush_feeds($contenttype) {
$expired_time = strtotime('-30 days');
$query = db_query("SELECT nid, title FROM {node} WHERE type = '%s' AND created <= '%s' ORDER BY nid ASC", $contenttype, $expired_time);
while ($del = db_fetch_object($query)) {
// Check if node has a taxonomy term assigned
$query_term = db_query("SELECT DISTINCT nid FROM {term_node} WHERE nid = '%s'", $del->nid);
$check = mysql_num_rows($query_term);
if ($check == 0){
// Solve permission problem since cron runs as anonymous user
global $user;
$temp_user = $user;
$user = user_load(array('uid' => 1));
// Delete node
node_delete($del->nid);
// Set watchdog message
watchdog('Flush Feeds', 'Feed item deleted: <em>' . check_plain($del->title) . '</em> (' . $del->nid . ')');
// Set back $user to what it was before
$user = $temp_user;
}
}
}
Since node_delete() checks for access permissions and cron is working as anonymous user, I temporarily change the user to get delete permissions. Now I'm wondering if that is safe. If some people with more knowledge told me if this is safe, I'd appreciate it a lot.
Comments
Safe or not, the code can be
I've seen this user_load() trick done before, and have even used it, but I don't like it. Too much opportunity for something to go wrong and end up assigning UID1 permissions to heck knows what/whom.
Safe or not, the code can be improved :).
1. You can just run one JOIN'ed query instead of two separate ones.
2. The user_load() and temporary user switch should happen outside the while() loop (no need to do this for every node you get in the query).
3. As an alternative to the user_load() trick, I would just copy the code from node_delete() and remove the access check:
---
Yuriy Babenko | Technical Consultant & Senior Developer
http://yuriybabenko.com
You could set up a grants
You could set up a grants system using hook_node_access_records() and hook_node_grants(), whereby the anonymous user is given node deletion grants under specific conditions. You could then set up that condition to exist somehow during the cron run. How this may be good is that without node edit grants, a regular anonymous user could never get to the screen with the delete button, so they wouldn't be able to accidentally delete something, but cron on the other hand could delete without needing to get to the node edit screen, since it is just calling the function node_delete().
All theory though - I've not done this.
Great, thanks a lot!
Great, thanks a lot!
See Safely Impersonating
See Safely Impersonating Another User for general info on user switching (not saying it is the best in this case).
Ceterum censeo, API functions shouldn't check user perms.
D7 version of this code
This is the D7 code I use:
Note: In my case, the content type to delete is called
feed_item
and the taxonomy field is calledfield_data_taxonomy_vocabulary_1
.