Löschen Sie einen Knoten nach X Wochen, nachdem er erstellt wurde

15

Wie kann ich einen Knoten löschen, nachdem er beispielsweise 2 Wochen erstellt wurde?

RobinSon
quelle

Antworten:

18

Wenn Sie eine entwicklerorientierte Lösung suchen, können Sie hook_cron()in einem benutzerdefinierten Modul alte Knoten bereinigen:

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();
  }
}
Shawn Conn
quelle
Wie geht das mit Regeln in Drupal 8?
RobinSon
1
Dies war absichtlich ein anderer Ansatz als der auf Site Builder / Regeln basierende Ansatz. Ich würde @UnsettlingTrend bitten, seine Antwort entsprechend zu aktualisieren. Ich habe Rules in D8 noch nicht ausprobiert, daher kann ich mit einer Lösung sprechen, die auf diesem Modul basiert.
Shawn Conn
7
Die Verwendung von $ node = $ storage-> loadMultiple ($ nids) und dann von $ storage-> deleteMultiple ($ node) ist etwas schneller, aber es sei denn, Sie löschen Dutzende von Knoten. Dies ist kein großes Problem.
Berdir
@SiMoNe kannst du noch nicht. Es gibt noch kein Rules-Scheduler-Modul und Rules 8 ist noch nicht produktionsbereit.
Kein Sssweat
1
Ich würde einen warteschlangenbasierten Ansatz für die Skalierung erstellen. Du brauchst keine Regeln.
Kevin
4

Basierend auf Shawn Conns Antwort ist hier die vollständige Lösung für Anfänger:

  1. Gehe in dein Root-Dateiverzeichnis und erstelle den Ordner "delete_old_nodes"
  2. Erstellen Sie eine Datei in dem soeben erstellten Ordner "delete_old_nodes.info.yml" und fügen Sie diesen Code ein:

    name: Delete old nodes
    description: Deletes nodes older than 30 days.
    package: Custom
    type: module
    version: 1.0
    core: 8.x
  3. Erstellen Sie eine Datei mit dem Namen "delete_old_nodes.module" und fügen Sie diesen Code ein:

    <?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. Cache leeren, dann zur Modulseite (yoursite.com/admin/modules) navigieren und das Modul aktivieren (indem Sie nach "Alte Knoten löschen" suchen, auf das Kontrollkästchen neben dem Modulnamen klicken und auf Speichern klicken).

  5. Erledigt! Wann immer Sie cron ausführen, werden die Knoten / Seiten, die in -2 Wochen veröffentlicht wurden oder auf denen Sie sie haben, von nun an gelöscht.

  6. Hinweis: Um zu planen, wann cron ausgeführt wird, rufen Sie yoursite.com/admin/config/system/cron auf

Testen:

Erstellen Sie einen Knoten und ändern Sie das Veröffentlichungsdatum, normalerweise in der rechten Seitenleiste, auf -2 Wochen oder wie auch immer. Führen Sie cron manuell unter yoursite.com/admin/config/system/cron aus, und Sie sollten Ihren Knoten nicht finden können.

Chris glücklich
quelle
Sie brauchen das Closing nicht?>. Dies führt bei einigen Serverkonfigurationen zu Fehlern. Ich würde empfehlen, ein strukturierteres Setup mit QueueAPI zu haben. Wenn auf diese Weise Tausende oder sogar Hunderte von Knoten gelöscht werden müssen, wird das System innerhalb des obigen Cron-Ops nicht hängen bleiben. sitepoint.com/…
Kevin
Huh. Wenn ich das?> Nicht hätte, würde der Code für mich nicht funktionieren.
Chris Happy
2

Ich würde auch eine hook_cron()Implementierung verwenden, aber den folgenden Code verwenden.

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

Der Code, den ich zum Löschen der Knoten verwendet habe, ist der, für den die entity_delete_multiple()Verfallsnachricht die Verwendung vorschlägt.
Ich habe auch einen Aufruf verwendet, um accessCheck(FALSE)zu vermeiden, dass die Entitätsabfrage nur die Knoten zurückgibt, auf die der anonyme Benutzer Zugriff hat. (Cron-Tasks werden als anonymer Benutzer ausgeführt.)

Wenn dann die Möglichkeit besteht, dass die zu löschenden Knoten zu groß sind, würde ich die Anzahl der Knoten begrenzen, die jedes Mal gelöscht werden, wenn Cron-Tasks ausgeführt werden.

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
quelle
Ich weiß, diese Frage ist alt, aber @ kiamlaluno Ihre Antwort hat mir Zeit gespart! und anstatt eine neue Frage zu posten, die ein Duplikat dieser Frage sein wird, könnten Sie bitte näher erläutern, wie das Löschen von Knoten auf Knotentypen beschränkt werden article kann. Vielen Dank
Elie Masaad,
Die letzte hook_cron()gezeigte Implementierung unterscheidet sich bereits range()von der vorherigen Implementierung.
kiamlaluno
Die range()wie ich es verstehe, wird die Anzahl der Knoten begrenzen jedes Mal Cron - Tasks ausführen gelöscht. Angenommen, ich habe auf der Site 30 Typknoten page& articlemit Erstellungsdatum vor mehr als 2 Wochen ... Wie löschearticlepage ich nur die Typknoten, ohne den Typknoten zu löschen ? ... Entschuldigen Sie meine bescheidenen PHP-Fähigkeiten, aber ich konnte eine solche Implementierung im obigen Code nicht sehen! Vielen Dank
Elie Masaad
0

Ich würde versuchen, es als solches zu tun:

  1. Erstellen Sie eine Ansicht aller Knoten, die älter als 2 Wochen sind
  2. Erstellen Sie eine Systemregel, die bei der Cron-Wartung ausgeführt werden soll
  3. Erstellen Sie in der Regelkonfiguration eine Schleife, um diese Ansichtsergebnisse zu durchlaufen
  4. Löschen Sie jeden Knoten

Ich werde versuchen, es zu testen, wenn ich die Gelegenheit dazu bekomme, da ich nicht ganz sicher bin, wie einfach / möglich es sein wird, die Ansicht in 3. so zu nutzen, aber das ist definitiv der Punkt, an dem ich anfangen würde. Dies ist natürlich mit dem Vorbehalt verbunden, dass Knoten nicht gelöscht werden, wenn sie GENAU 2 Wochen alt sind, sondern davon abhängen, wann Cron auf Ihrem System ausgeführt wird. aber ich nehme an, innerhalb von 3 stunden reicht das noch aus.

(Ich habe gerade erst gemerkt, dass dies für D8 war; ich denke, der Prozess ist immer noch gut.)

Beunruhigender Trend
quelle
Ich habe D8 erst realisiert, nachdem ich das eingegeben habe. Ich weiß nur, dass die Regeln für D8 in Alpha für Stable sind. habe es noch nicht ausprobiert.
UnsettlingTrend
Ich habe mich für die Dev-Version von Rules entschieden. Für das, was ich versucht habe, schien es stabil zu sein, aber ich bin fest davon überzeugt, dass es anscheinend keine - ansonsten geplante - D8-Version des Moduls "Ansichtsregeln" gibt, mit der die Ansichtsergebnisse durchlaufen werden können. Wenn es eine Möglichkeit gibt, Ansichten in einer Regel abzurufen, die mir nicht einfällt, funktioniert dies möglicherweise. Ansonsten bin ich mir nicht sicher.
UnsettlingTrend