Usuń węzeł po utworzeniu X tygodni

14

Jak mogę usunąć węzeł, na przykład po 2 tygodniach od jego utworzenia?

RobinSon
źródło

Odpowiedzi:

18

Jeśli szukasz rozwiązania zorientowanego na programistę, możesz wywołać hook_cron()w niestandardowym module, aby wyczyścić stare węzły:

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
źródło
Jak to zrobić z regułami w Drupal 8?
RobinSon,
1
To celowo było inne podejście niż podejście oparte na kreatorze witryn / regułach. Poprosiłbym @UnsettlingTrend o odpowiednią aktualizację jego odpowiedzi. Nie wypróbowałem jeszcze zasad w D8, więc mogę porozmawiać z rozwiązaniem opartym na tym module.
Shawn Conn
7
Używanie $ nodes = $ storage-> loadMultiple ($ nids), a następnie $ storage-> deleteMultiple ($ nodes) jest nieco szybsze, ale chyba że usuwasz dziesiątki węzłów, nie jest to duży problem.
Berdir
@SiMoNe nie możesz jeszcze. Nie ma jeszcze modułu harmonogramu reguł, a Reguły 8 nie są gotowe do produkcji.
Bez Sssweat
1
Stworzyłbym podejście oparte na kolejce do skalowania. Nie potrzebujesz reguł.
Kevin,
4

Na podstawie odpowiedzi Shawna Conna, oto pełne rozwiązanie dla nowicjuszy:

  1. Przejdź do katalogu głównego pliku i utwórz folder „delete_old_nodes”
  2. Utwórz plik w właśnie utworzonym folderze o nazwie: „delete_old_nodes.info.yml” i wklej w nim ten kod:

    name: Delete old nodes
    description: Deletes nodes older than 30 days.
    package: Custom
    type: module
    version: 1.0
    core: 8.x
    
  3. Utwórz plik o nazwie „delete_old_nodes.module” i umieść w nim ten kod:

    <?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. Opróżnij pamięć podręczną, a następnie przejdź do strony modułów - (yoursite.com/admin/modules) - i włącz moduł (wyszukując „usuń stare węzły”, kliknij pole wyboru obok nazwy modułów i kliknij przycisk Zapisz).

  5. Gotowy! Za każdym razem, gdy uruchomisz crona, węzły / strony, które zostały opublikowane -2 tygodnie lub cokolwiek masz, od teraz zostaną usunięte.

  6. Uwaga: Aby zaplanować uruchomienie crona, przejdź do yoursite.com/admin/config/system/cron

Testowanie:

Utwórz węzeł i zmień datę publikacji, zwykle na prawym pasku bocznym, na -2 tygodnie lub cokolwiek masz. Ręcznie uruchom crona na yoursite.com/admin/config/system/cron, a znalezienie twojego węzła nie powinno być możliwe.

Chris Happy
źródło
Nie potrzebujesz zamknięcia?>. Spowoduje to błędy w niektórych konfiguracjach serwera. Radziłbym mieć bardziej ustrukturyzowaną konfigurację przy użyciu QueueAPI, w ten sposób, jeśli do usunięcia są tysiące, a nawet setki węzłów, nie zawiesi systemu w ramach powyższej operacji cron. sitepoint.com/…
Kevin
Huh Gdybym nie miał?>, Kod nie działałby dla mnie.
Chris Happy
2

Chciałbym również użyć hook_cron()implementacji, ale używając następującego kodu.

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

Kod, którego użyłem do usunięcia węzłów, to ten, który entity_delete_multiple()sugeruje użycie komunikatu o wycofaniu .
Użyłem również wywołania, aby accessCheck(FALSE)uniknąć zapytania o jednostkę zwracającego tylko te węzły, do których użytkownik anonimowy ma dostęp. (Zadania Crona są uruchamiane jako anonimowy użytkownik).

Jeśli zatem istnieje możliwość, że węzły do ​​usunięcia są zbyt duże, ograniczę liczbę węzłów usuwanych przy każdym uruchomieniu zadań crona.

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
źródło
Wiem, że to pytanie jest stare, ale @kiamlaluno twoja odpowiedź pozwoliła mi zaoszczędzić czas! i zamiast opublikować nowe pytanie, które będzie duplikatem tego, czy mógłbyś bardziej szczegółowo wyjaśnić, w jaki sposób ograniczyć usuwanie węzłów do węzła typu article , dziękuję
Elie Masaad
Ostatnia hook_cron()pokazana implementacja już to robi, jak to wywołuje range(), inaczej niż poprzednia.
kiamlaluno
range()Jak rozumiem, ograniczy liczbę węzłów usunięte każdorazowo zadania cron uruchomić. Ale powiedz, że mam na stronie 30 węzłów typów pagei articledatę utworzenia ponad 2 tygodnie temu ... Jak usunąć tylko węzły typu articlebez usuwania węzła typu page? ... Przepraszam za moje skromne umiejętności php, ale nie widziałem takiej implementacji w powyższym kodzie! Dzięki
Elie Masaad,
0

Spróbowałbym to zrobić w ten sposób:

  1. Utwórz widok wszystkich węzłów, które mają ponad 2 tygodnie
  2. Utwórz regułę systemową, aby działała w ramach konserwacji Cron
  3. W konfiguracji reguły utwórz pętlę, aby iterować te wyniki widoku
  4. Usuń każdy węzeł

Spróbuję go przetestować, kiedy będę miał szansę, ponieważ nie jestem do końca pewien, jak łatwe / możliwe będzie wykorzystanie takiego widoku w 3., ale na pewno od tego bym zaczął. Oczywiście wiąże się to z zastrzeżeniem, że nie usunie węzłów, gdy osiągną DOKŁADNIE 2 tygodnie, ale będzie zależało od tego, kiedy Cron uruchomi się w twoim systemie; ale zakładam, że w ciągu około 3 godzin nadal to wystarcza.

(Dopiero co zauważyłem, że dotyczy to D8; myślę jednak, że proces ten jest nadal dobry).

UnsettlingTrend
źródło
Nie zdawałem sobie sprawy z D8, dopóki tego nie napisałem. Wiem tylko, że reguły są w wersji alfa dla stabilnego dla D8; jeszcze tego nie próbowałem.
UnsettlingTrend
Poszedłem z wersją Dev regulaminu. Wydawało mi się, że to, co próbowałem, jest stabilne, ale utknąłem w tym, że wydaje się, że nie ma - inaczej zaplanowanej - wersji D8 modułu Widoki, której można by użyć do przeglądania wyników. Jeśli istnieje sposób na uzyskanie widoków w regule, o której nie mogę myśleć, może to zadziałać. W przeciwnym razie nie jestem pewien.
UnsettlingTrend