Drupal - Delete a node after X weeks it was created

If you're looking for a developer-centric solution, you can invoke hook_cron() in a custom module to clean up old nodes:

function MYMODULE_cron() {

  // Other conditions can be altered/added as neeed
  $query = \Drupal::entityQuery('node')
    ->condition('created', strtotime('-2 week'), '<=');
  $nids = $query->execute();
  foreach ($nids as $nid) {
    $node = node_load($nid);
    $node->delete();
  }
}

Based off Shawn Conn's answer, here is the full solution for novices:

  1. Go to your root file directory and create folder "delete_old_nodes"

  2. Create a file in the folder you just created called: "delete_old_nodes.info.yml" and paste this code in it:

    name: Delete old nodes
    description: Deletes nodes older than 30 days.
    package: Custom
    type: module
    version: 1.0
    core: 8.x
    
  3. Create a file called "delete_old_nodes.module" and put this code into it:

    <?php
    
    function delete_old_nodes_cron() {
    
      $query = \Drupal::entityQuery('node')
        ->condition('created', strtotime('-2 week'), '<='); // Can change -2 week to -2 year or -3 day
      $nids = $query->execute();
      foreach ($nids as $nid) {
        $node = node_load($nid);
        $node->delete();
      }
    }
    
  4. Flush cache, then navigate to modules page — (yoursite.com/admin/modules) — and enable your module, (by searching for "delete old nodes", click the checkbox by the modules name and click save).

  5. Done! Whenever you run cron, the nodes/pages that were published -2 weeks, or whatever you have it at, from now will be deleted.

  6. Note: To schedule when cron runs, go to yoursite.com/admin/config/system/cron

Testing:

Create a node and change the published date, normally in the right sidebar, to -2 weeks or whatever you have it at. Manually run cron at yoursite.com/admin/config/system/cron and you should not be able to find your node.


I would use a hook_cron() implementation too, but using the following code.

function mymodule_cron() {
  $storage_handler = \Drupal::entityTypeManager()->getStorage('node');
  $query = \Drupal::entityQuery('node')->accessCheck(FALSE)
    ->condition('created', strtotime('-2 week'), '<=');
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

The code I used to delete the nodes is the one that the deprecation message for entity_delete_multiple() suggests to use.
I also used a call to accessCheck(FALSE) to avoid the entity query returns only the nodes to which the anonymous user has access. (Cron tasks run as anonymous user.)

If then there is the possibility the nodes to delete are too much, I would limit the number of nodes deleted each time cron tasks run.

function mymodule_cron() {
  $storage_handler = \Drupal::entityTypeManager()->getStorage('node');
  $query = \Drupal::entityQuery('node')->accessCheck(FALSE)
    ->condition('created', strtotime('-2 week'), '<=')
    ->range(0,30);
  $result = $query->execute();
  if (!empty($result)) {
    $nids = array_keys($result);
    $nodes = $storage_handler->loadMultiple($nids);
    $storage_handler->delete($nodes);
  }
}

Tags:

Nodes

8