Drupal - How to resave all my nodes
What you are asking for is included in core Views, unless I am mistaken.
In a new Content view you will be able to add a "Content: Node operations bulk form" field and that offers you an option for "Save content".
You could even use the default "Content" view...
that already offers that option out of the box:
Update: I just created Resave All Nodes. For now it only contains a form to trigger a batch process to resave all nodes of selected node types. Currently in alpha. I plan to add a Drush command (beta) and some tests (stable) as well.
For everybody coming here to find a code snippet (to be placed in MYMODULE.install
):
use \Drupal\node\Entity\Node;
/**
* Resave all pages.
*/
function MYMODULE_update_8001(&$sandbox) {
// Get an array of all 'page' node IDs.
$nids = \Drupal::entityQuery('node')
->condition('type', 'page')
->execute();
// Load all the nodes.
$nodes = Node::loadMultiple($nids);
foreach ($nodes as $node) {
$node->save();
}
}
Problem with this, of course, is you can reach your memory limit pretty fast when re-saving many thousands of nodes that way. So you have to implement a batch process.
Thankfully hook_update_N(&$sandbox)
already has this capability built-in. Follow the link for sample code.
If running your update all at once could possibly cause PHP to time out, use the
$sandbox
parameter to indicate that the Batch API should be used for your update. In this case, your update function acts as an implementation ofcallback_batch_operation()
, and$sandbox
acts as the batch context parameter. In your function, read the state information from the previous run from$sandbox
(or initialize), run a chunk of updates, save the state in$sandbox
, and set$sandbox['#finished']
to a value between0
and1
to indicate the percent completed, or1
if it is finished (you need to do this explicitly in each pass).