Как исправить db_query_range() ?

Главные вкладки

Аватар пользователя Shizuku Shizuku 1 июля 2013 в 19:16

Небольшой код для удаления пользователей, неактивных более 90 дней.
Выдает ошибку: "Recoverable fatal error: Argument 4 passed to db_query_range() must be an array, integer given"


Помогите исправить для использования в Drupal 7 !

$query = db_query_range("SELECT uid FROM {users} WHERE access < %d", time() - 7776000, 0, 20);
while ($uid = db_result($query)) {
  user_delete(array(), $uid);
}
return array();

Комментарии

Аватар пользователя arrides arrides 1 июля 2013 в 19:44

Не совсем понятно, а почему только первых 20). Насколько я понимаю, запрос должен выглядеть примерно так:
$query = db_select('users', 'u');
$query->fields('u', array('uid'));
$query->condition('access', time() - 7776000, '>');
$select = $query->execute();
foreach ($select as $row) {
user_delete($row->uid);
}

Аватар пользователя Shizuku Shizuku 1 июля 2013 в 20:12

"arrides" wrote:
Не совсем понятно, а почему только первых 20

По идее он берет 20, а потом в цикле while "добирает". Не могу сказать, потому как по-любому у меня не сработало

Аватар пользователя Shizuku Shizuku 2 июля 2013 в 1:16

"arrides" wrote:
запрос должен выглядеть примерно так

Запрос работает, но Cron c этим скриптом положил мне сайт с ошибкой 500 (Internal Server Error)

"The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator to inform of the time the error occurred and of anything you might have done that may have caused the error."

Видимо, удаление пары тысяч пользователей сильно удивило наш сервер...

а вот что у нас в логах:

[Mon Jul 01 19:29:46 2013] [warn] [client 82.209.236.73] mod_fcgid: read data timeout in 45 seconds, referer: http://.../admin/reports/status
[Mon Jul 01 19:29:46 2013] [error] [client 82.209.236.73] Premature end of script headers: index.php, referer: http://.../admin/reports/status

И что-то не так с условием... Удалило вполне себе активных пользователей, в том числе супер-юзера (меня)!

И весь контент, мною добавленный, а это 90% страниц...

Теперь весело так сижу. Smile

База была восстановлена из копии, исходник выше я отредактировал - поменял ">" на "<". Теперь удаляет пользователей правильно! Но ошибки в логах остались. Видимо есть какая-то опция на сервере, которая обрубает длительные запросы, плюс блокирует повторный запуск cron на 45 секунд. За один раз успевает удалить 1-2 тысячи пользователей.

Аватар пользователя arrides arrides 1 июля 2013 в 23:08

я лишь повторил ваш запрос для drupal 7, да и удаление тысячами так не делается, вы бы написали, что вам нужно удалить огромное количество пользователей, плюс такие процедуры делаются сначала на копиях пару раз, а потому уже на реале

Аватар пользователя Shizuku Shizuku 1 июля 2013 в 23:34

"arrides" wrote:
я лишь повторил ваш запрос для drupal 7, да и удаление тысячами так не делается

Так я же не злюсь! Меня ржач от этой ситуевины разбирает! Не каждый день получается самому себе пинка под зад дать! )))

Копия уже восстанавливается, потом будет разбор полётов... Есть мысль, что удаление прервалось именно по причине удаления учётки, из которой было запущено задание. А на таймаут там было всего лишь предупреждение. А как надо было удалять тысячу пользователей? ))

Аватар пользователя kirill_dan kirill_dan 2 июля 2013 в 1:08

Значение даты в Д7 хранится в секундах от Гринвича, например такое значение - 1369403917. Поэтому нужно использовать не date() и тем более не time(), а UNIX_TIMESTAMP(NOW()). Ржача тут мало, не стоит проводить эксперименты, так как будете все время валить сайт. Можете для своей цели воспользоваться готовым модулем (правда аккаунт не удаляется, а отключается) - http://www.drupal.ru/node/101416.

Аватар пользователя Shizuku Shizuku 2 июля 2013 в 1:07

"kirill_dan" wrote:
Можете для своей цели воспользоваться готовым модулем

Не то. Этот модуль отключает аккаунт, если прошло определенное время с момента его создания. А я чищу от неактивных пользователей по дате последнего доступа... Мне подошел бы https://drupal.org/project/inactive_user , там даже есть dev для D7, но почему-то созданные в нем задания не выполняются!

Аватар пользователя kirill_dan kirill_dan 2 июля 2013 в 1:26

function mymodule_cron() {
$query = db_select('users', 'u');
$query->fields('u', array('uid'));
$query->condition('u.uid', 1, '>');
$query->where('UNIX_TIMESTAMP(NOW()) > :access', array(':access' => 'u.access+(86400*90)'));
$result = $query->execute();
foreach ($result as $key => $value) {
user_delete($value->uid);
}
}

Вставить в свой модуль. Вместо mymodule указать имя своего модуля. (86400*90) - это секунды в одном дне помноженные на количество неактивных дней. $query->condition('u.uid', 1, '>'); - не позволит удалить главного админа, который был создан при инсталляции Друпал.

При запуске крона Друпал будут удалены все аккаунты, которые старше, в данном случае 90 дней.

Аватар пользователя kirill_dan kirill_dan 2 июля 2013 в 1:30

Можно запрос еще чуть усложнить, и сделать проверку на права пользователей. Если админ, то не удалять, даже если аккаунт вышел за пределы срока.