Удалить узел через X недель он был создан

14

Как удалить узел, например, через 2 недели после его создания?

Robinson
источник

Ответы:

18

Если вы ищете решение, ориентированное на разработчика, вы можете вызвать hook_cron()пользовательский модуль для очистки старых узлов:

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();
  }
}
Шон Конн
источник
Как это можно сделать с правилами в drupal 8?
РобинСон
1
Это было намеренно отличным подходом от подхода на основе конструктора сайтов / правил. Я бы попросил @UnsettlingTrend обновить его ответ соответственно. Я еще не опробовал правила в D8, поэтому я могу поговорить с решением, основанным на этом модуле.
Шон Конн
7
Использование $ node = $ storage-> loadMultiple ($ nids), а затем $ storage-> deleteMultiple ($ node) немного быстрее, но если вы не удаляете десятки узлов, это не является большой проблемой.
Бердир
@SiMoNe ты пока не можешь. Модуль планировщика правил пока отсутствует, плюс Правила 8 не готовы к производству.
Нет Sssweat
1
Я хотел бы создать подход на основе очереди для масштабирования. Вам не нужны правила.
Кевин
4

Исходя из ответа Шона Конна, вот полное решение для новичков:

  1. Перейдите в корневой каталог файлов и создайте папку «delete_old_nodes»
  2. Создайте файл в только что созданной папке с именем: "delete_old_nodes.info.yml" и вставьте в него этот код:

    name: Delete old nodes
    description: Deletes nodes older than 30 days.
    package: Custom
    type: module
    version: 1.0
    core: 8.x
    
  3. Создайте файл с именем «delete_old_nodes.module» и вставьте в него этот код:

    <?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. Очистите кэш, затем перейдите на страницу модулей - (yoursite.com/admin/modules) - и включите ваш модуль (в поиске «удалить старые узлы» установите флажок по имени модуля и нажмите «Сохранить»).

  5. Выполнено! Всякий раз, когда вы запускаете cron, узлы / страницы, которые были опубликованы через 2 недели, или что бы то ни было, будут удалены.

  6. Примечание. Чтобы запланировать запуск cron, перейдите на yoursite.com/admin/config/system/cron.

Тестирование:

Создайте узел и измените опубликованную дату, обычно на правой боковой панели, на -2 недели или любую другую дату. Запустите cron вручную на yoursite.com/admin/config/system/cron, и вы не сможете найти свой узел.

Крис Хэппи
источник
Вам не нужно закрытие? Это приведет к ошибкам при некоторых настройках сервера. Я бы посоветовал иметь более структурированную настройку с использованием QueueAPI, поэтому, если есть тысячи или даже сотни узлов для удаления, это не повредит систему в cron op выше. sitepoint.com/…
Кевин
Да. Когда у меня не было?>, Код не работал бы для меня.
Крис Хэппи
2

Я бы тоже использовал hook_cron()реализацию, но используя следующий код.

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);
  }
}

Код, который я использовал для удаления узлов, - это код, для которого entity_delete_multiple()предлагается использовать сообщение об устаревании .
Я также использовал вызов, чтобы accessCheck(FALSE)избежать запроса сущности, который возвращает только узлы, к которым имеет доступ анонимный пользователь. (Задачи Cron запускаются как анонимный пользователь.)

Если есть вероятность, что удаляемые узлы слишком велики, я бы ограничил количество удаляемых узлов при каждом запуске задач cron.

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);
  }
}
киамлалуно
источник
Я знаю, что этот вопрос старый, но @kiamlaluno ваш ответ сэкономил мое время! и вместо того, чтобы публиковать новый вопрос, который будет дубликатом этого, не могли бы вы подробнее рассказать о том, как ограничить удаление узлов типом узла article , спасибо
Эли
Последняя hook_cron()показанная реализация уже делает это, как это называется range(), иначе, чем предыдущая реализация.
kiamlaluno
Как range()я понимаю, будет ограничивать количество узлов, удаляемых при каждом запуске задач cron. Но скажем, у меня на сайте 30 узлов типов pageи articleс датой создания более 2 недель назад ... Как удалить только узлы типа articleбез удаления узла типа page? ... Извините за мои скромные навыки PHP, но я не мог видеть такую ​​реализацию в приведенном выше коде! Спасибо
Эли
0

Я бы попробовал сделать это так:

  1. Создайте представление всех узлов старше 2 недель
  2. Создайте системное правило для запуска на обслуживании Cron
  3. В конфигурации правила создайте цикл для перебора этих результатов просмотра.
  4. Удалить каждый узел

Я попытаюсь проверить это, когда у меня будет шанс, потому что я не совсем уверен, насколько легко / возможно будет использовать такое представление в 3., но это определенно то, с чего я бы начал. Конечно, это связано с предупреждением о том, что он не будет удалять узлы, когда им станет ровно 2 недели, но будет зависеть от того, когда Cron будет работать в вашей системе; но я предполагаю, что в течение 3 часов или около того все еще достаточно.

(Я только что заметил, что это было для D8; я думаю, что процесс все еще звучит.)

UnsettlingTrend
источник
Я не понял D8, пока не набрал это. Я просто знаю, что правила в альфа стабильны для D8; еще не пробовал.
UnsettlingTrend
Я пошел с версией правил Dev. Для того, что я пытался, оно показалось стабильным, но я застрял в том факте, что, похоже, нет - не планировалось иначе - версия D8 модуля «Правила представления», которую можно использовать для циклического просмотра результатов просмотра. Если есть способ получить представления в правиле, о котором я не могу думать, это может сработать. В противном случае я не уверен.
UnsettlingTrend