This seems like such a straightforward, common requirement and I haven't been able to find or come up with a solution. It also seems like something that would be needed by a newspaper site. I'm sure once there is a solution out in cyberspace it will be appreciated.
Publish one node per day
Allow the user to create as many nodes as s/he wants, whenever s/he wants.
The system will publish one of these nodes per day.
I've seen the question asked:
eg: http://drupal.org/node/374592
and have tried all the solutions I can think of using Nodequeue, Triggered Rules/Rules, Flag, Workflow, Scheduler, VBO.
My thinking has been:
- with a triggered rule, when new content is created, add it to a nodequeue
- with ??, at each cron run (set at midnight), remove the oldest node from the nodequeue
I haven't found a solution using Triggered Rules (or Rules or Actions or Trigger) because content arguments are not available to cron triggers.
So, I thought maybe on cron, programmatically calling the nodequeue_admin_remove($queue, $subqueue, $pos) function from the nodequeue.module. I can't get this to work either.
I'm stumped.
Comments
Solution
As usual, the solution is simple.
As usual, the solution is simple.
Modules: Nodequeue and Triggered Rules
Create an unlimited nodequeue
Create a triggered rule that fires on 'After saving new content'. Add a condition for 'Node has type' and specify the appropriate content type(s). Add an action 'Add to nodequeues' and specify the appropriate nodequeue.
Create a second triggered rule that fires on 'Cron maintenance tasks are performed'. Add an action 'Execute custom PHP code'. Your custom PHP code will be a query:
db_query("DELETE FROM
nodequeue_nodes
WHEREnodequeue_nodes
.qid
= 1 ANDnodequeue_nodes
.position
= 1 LIMIT 1");*obviously replace qid with the qid of your nodequeue.
Add a second action 'Execute custom PHP code' with another query:
$count = db_query("SELECT COUNT(*) FROM
nodequeue_nodes
WHEREnodequeue_nodes
.qid
= 4 ANDnodequeue_nodes
.sqid
= 4");for ($i = 2; $i <= $count; $i++) {
$position = $i - 1;
db_query("UPDATE
nodequeue_nodes
SETposition
= $position WHEREnodequeue_nodes
.qid
=1 ANDnodequeue_nodes
.sqid
=1 ANDnodequeue_nodes
.position
=$i LIMIT 1");}
Only this simple if you don't need cron to run more often
If you need cron to run more frequently (e.g. for updating the site's search index, or any other scheduled task that you need to happen sooner than once per day at midnight), then you'll have problems with this approach.
In the following (untested!!) code snippet, I used the variables table to keep track of whether publishing has happened in the current period (day). If not, then do it.
<?php
// use the variables table to keep track of the last time we published
// a "period" is one day (60 seconds times 60 minutes times 24 hours),
// but you can change this next value to use a longer or shorter period
$secs_per_period = 60*60*24;
$this_period= (int)time()/$secs_per_period;
$last_publish_period = variable_get('last_nodequeue_publish_period');
if($last_publish_period != $this_period) {
// we haven't published yet in this period, go ahead and publish
$count = db_query("SELECT COUNT(*) FROM nodequeue_nodes WHERE nodequeue_nodes.qid = 4 AND nodequeue_nodes.sqid = 4");
for ($i = 2; $i <= $count; $i++) {
$position = $i - 1;
db_query("UPDATE nodequeue_nodes SET position = $position WHERE nodequeue_nodes.qid =1 AND nodequeue_nodes.sqid =1 AND nodequeue_nodes.position =$i LIMIT 1");
// we have now published, so we can reset 'last_nodequeue_publish_period' to this period
variable_set('last_nodequeue_publish_period', $this_period);
}
?>
Very true
Very true, this would cause problems if cron had to run more frequently. Thankfully it doesn't in my case. Thanks for the code snippet, I'm sure there will come a day that I run into this and come digging for a solution like yours. ;)
How do you add the action 'Add to nodequeues' to Rules?
I don't have the action 'Add to nodequeues' in the Rules module. Even though I created an advanced action 'Add to nodequeues' via the core actions module, I don't have this action in Rules available.
I tried:
disabling and enabling the modules
clearing my cache
What am I missing?