Jak usunąć 1600 użytkowników i 2500 postów?

10

Kilka lat temu skonfigurowałem witrynę z Drupal 6.9, a potem zapomniałem o tym. Mam 160 stron użytkowników, którzy są wszyscy spamerami i muszę usunąć wszystkie oprócz 3. Robienie tej jednej strony jest boleśnie powolne z powodu wywołań MySQL (tak mi się wydaje). Mam również około 2500 postów na forum do usunięcia.

Trochę boję się bezpośrednio usunąć rekordy z bazy danych.

Widziałem moduł o nazwie „masowe usuwanie”, ale jest on dla Drupala w wersji 5 i nie jest dostępny dla wersji 6.

John R.
źródło

Odpowiedzi:

17

Możesz użyć widoku Bulk Operations , modułu, który pozwala na wykonywanie operacji zbiorczych na węzłach, użytkownikach, komentarzach; pozwala także zastosować wybraną operację do wszystkich węzłów, użytkowników lub komentarzy za pomocą Batch API . Wsadowy interfejs API umożliwia rozłożenie przetwarzania formularzy na kilka żądań stron, zapewniając w ten sposób, że przetwarzanie nie zostanie przerwane z powodu przekroczenia limitu czasu PHP, jednocześnie umożliwiając użytkownikowi otrzymywanie informacji zwrotnych o postępach bieżących operacji.

kiamlaluno
źródło
1
Wybieranie wszystkich elementów do usunięcia jest znów bardzo powolne - W opcjach VBO widoku dostępne jest ustawienie umożliwiające select allprzycisk wyboru wszystkich elementów na wszystkich stronach - kliknij go i Kill-em-all!
AyeshK
3

Ten sposób zabijania węzłów jest bardzo wolny, ale najbardziej bezpieczny

function MYMODULE_menu(){
  $items['admin/mymodule/killnodes/%'] = array(
      'title' => 'Kill nodes',
      'page callback' => 'kill_nodes',
      'page arguments' => array(3),
      'type' => MENU_CALLBACK,
      'access arguments' => array('administer site configuration'),
  );
  return $items;
}

function kill_nodes($type){
  $query = "SELECT node.nid AS nid FROM {node} node WHERE node.type IN ('%s')";
  $result = db_query($query, $type);
  $count = 0;
  while($row = db_fetch_object($result)){
    node_delete($row->nid);
    $count++;
  }
  $message = t('!count nodes has been killed. Pif-Paf!', array('!count' => $count));
  drupal_set_message($message);
  return t("That's all folks");
}

Czy dla użytkowników możesz programowo określić użytkownika, którego chcesz usunąć? Jeśli to możliwe, możesz użyć poprzedniej funkcji jako przykładu, aby usunąć niepotrzebnych użytkowników.

dobeerman
źródło
3
Sugerowałbym zawinięcie go w partia Batch API, aby zapobiec przekroczeniu limitu czasu.
Odszyfruj
Na pewno. To prosty przykład.
dobeerman
3

Zamiast tworzyć niestandardowy moduł dla tego zadania, możesz użyć prostego skryptu i uruchomić go za pomocą Drusha . Ponieważ musisz przetworzyć wielu użytkowników i węzłów, zalecane jest użycie interfejsu API Batch (i można go używać z Drush ).

Pierre Buyle
źródło
2

Jeśli, podobnie jak ja, wolisz podejście w języku Python (prawdopodobnie tutaj rzadko, ale nadal), jest to przejrzysty i skuteczny sposób rozwiązania tego problemu:

import os

# Build up a variable containing the usernames
# This list was built using drush sql-cli, then
# SELECT name FROM users 
#   where $your-where-condition 
#   order by uid asc 
#   INTO 
#     OUTFILE '/tmp/users.csv' 
#     FIELDS TERMINATED BY ',' 
#     ENCLOSED BY '"' 
#     lines terminated by ', ' ;
users = [result from SQL goes here]

for user in users:
    print("Deleting spam user: %s..." % user),
    os.system('drush --yes -r $your-path-to-drupal -l $your-site-url user-cancel --delete-content %s > /dev/null' % user) 
    print 'Done'

Kroki są w zasadzie:

  1. Zaloguj się do swojej bazy danych za pomocą drush sql-cli -r $your-path-to-drupal -l $your-site-url
  2. Uruchom powyższy kod SQL z własnym warunkiem i wklej wyniki do zmiennej users.
  3. Zaktualizuj swoją ścieżkę drupala i nazwę witryny do polecenia drush
  4. Uruchom skrypt za pomocą python delete-users.py

Jestem pewien, że jest na to lepszy sposób, ale to jest moje zhakowane rozwiązanie, które działa dobrze.

mlissner
źródło
1
Możesz to zrobić również jako liniowiec. for i in `drush sql-query 'SELECT list of usernames'`; do drush --yes user-cancel --delete-content $i; done.
David L
1

Wdrożyłem niestandardowy moduł do usuwania wszystkich użytkowników indrupal 7. W obszarze admin / people znajduje się nowy formularz do wykonania tej operacji.

Zbyt drush.

To projekt piaskownicy. Dziękuję

Link do projektu.

Grgr
źródło
1

Użyj zaawansowanego modułu użytkownika . Ten moduł dodaje zakładkę „zaawansowane” do strony zarządzania użytkownikami. Na tej karcie możesz filtrować użytkowników według dowolnego atrybutu (rola, status itp.) I zaznacz wszystko. Jeśli wybierzesz metodę usuwania użytkowników jako usuń użytkownika i usuń całą zawartość, możesz również usunąć całą utworzoną przez nich zawartość.

Sinan Erdem
źródło
0

Jeśli masz dostęp do Drush i chcesz szybkiego rozwiązania, które pozwoli zachować użytkowników na białej liście i nie wymaga instalowania dodatkowych modułów:

drush @example.org sqlq "SELECT name FROM users WHERE name NOT IN ('keepthisuser1', 'andthisuser2')" | while read NAME; do
  drush -y @example.org user-cancel $NAME ; 
done

Przed wklejeniem skoryguj zarówno @example.orglistę użytkowników, jak i listę użytkowników.('keepthisuser1', 'andthisuser2')

Chris Burgess
źródło
To pozostawi ogony, takie jak pola użytkownika i wszystko.
niksmac
1
Czy możesz podać szczegóły, co masz na myśli? Właśnie przetestowałem to na najnowszym Drupal 7 i nie pozostawiło danych w polach użytkowników. Nie rozumiem, co rozumiesz przez „ogony”.
Chris Burgess,
1
Widzę, że ta odpowiedź powiela podobną zapakowaną w Python powyżej.
Chris Burgess,
1
Odwróciłem głosowanie nad tą odpowiedzią, ponieważ faktycznie działa ona zgodnie z wymaganiami. Poleć @niksmac zmień głosuj w dół, aby głosować w górę. Zauważ, że nie jest to odpowiedź SQL i używa drush.
Christian
0

Przydałby się moduł Usuń wszystko .

Po zainstalowaniu możesz na przykład:

drush delete-all articles

lub

drush delete-all users

Wersja Drupal 6 w dev, ale z notatek:

Wszystko powinno działać poprawnie, z wyjątkiem szybkiego usuwania.

Mauro Sardu
źródło
0

Pierwotne pytanie dotyczy 6, ale użycie odpowiedzi Chrisa Burgessa można zastosować do Drupala 8;

drush sqlq "SELECT name FROM users_field_data WHERE name NOT IN ('admin')" | while read NAME; 
  do drush -y user:cancel --delete-content $NAME; 
done
chrześcijanin
źródło