Тьфу ты... а я через профиль выдавал... Теперь другой косяк  

  желтая и красная в одном посте, и править дает только желтую, а красную уже не трогает) соответственно удалив/изменив желтую, красная не удалится/изменится, надо удалять желтую, потом изменять/удалять красную
Добавлено спустя 1 час 7 минут:Не, все фигня, надо переделывать логику  
Добавлено спустя 55 минут 5 секунд:Все переделал в одну функцию :D
Логика такая, после add_warning, edit_warning, delete_warning, внутри tidy_warnings запускаем синхронизацию предупреждений. 
1. Смотрим, если последняя желтая, считаем желтые и лепим красную (копию последней желтой) если их 3 и больше.
2. Ищем максимальный срок среди красных и баним юзера на этот срок.
3. Удаляем баны у которых связь с несуществующим предупреждением.
- Код: Выделить всё
 <?
function warn_autoban__sync($user_id) {
   global $db, $phpbb_root_path, $phpEx, $cache;
   $cache->destroy('sql', WARNINGS_TABLE);
      $sql = 'SELECT *
      FROM ' . USERS_TABLE . '
      WHERE user_id = ' . (int)$user_id . '
      LIMIT 1';
   $result = $db->sql_query($sql);
   $user_row = $db->sql_fetchrow($result);
   if(!$user_row) return false;
   $sql = 'SELECT *
         FROM ' . WARNINGS_TABLE . '
         WHERE user_id = ' . $user_row['user_id'] . '
            AND warning_active = 1
            AND warning_type IN ("ban", "warning")
         ORDER BY warning_id DESC';
   $result = $db->sql_query($sql);
   $warnings = $db->sql_fetchrowset($result);
   if($warnings) {
      $last_warning_row = $warnings[0];
      if($last_warning_row['warning_type'] == 'warning') {
         // add red if last yellow and yellows >= 3
         $yellow_total = 0;
         foreach($warnings as $warning_row) {
            if($warning_row['warning_type'] == 'warning') {
               $yellow_total++;
               if($yellow_total >= 3) {
                  require_once("{$phpbb_root_path}includes/mcp/mcp_warn.$phpEx");
                  add_warning($user_row, 'Автоматический бан за 3 и более предупреждения', false, $last_warning_row['post_id'], $last_warning_row['warning_days'], 'ban');
                  break;
               }
            }
         }
      }
   }
   // add user ban by max red
   $sql = 'SELECT *
         FROM ' . WARNINGS_TABLE . '
         WHERE user_id = ' . $user_row['user_id'] . '
            AND warning_active = 1
            AND warning_type = "ban"
         ORDER BY warning_id DESC';
   $result = $db->sql_query($sql);
   $warnings = $db->sql_fetchrowset($result);
   if($warnings) {
      $red_max = array(
          'warning_time' => 0,
          'warning_days' => 0,
      );
      foreach($warnings as $warning_row) {
         if($warning_row['warning_type'] == 'ban') {
              if($red_max['warning_time'] + $red_max['warning_days'] * 86400 < $warning_row['warning_time'] + $warning_row['warning_days'] * 86400) {
                  $red_max = $warning_row;
              }
         }
      }
      if($red_max['warning_time'] + $red_max['warning_days'] * 86400 > time()) {
            require_once("{$phpbb_root_path}includes/functions_user.$phpEx");
         $ban_len = ceil(($red_max['warning_time'] + $red_max['warning_days'] * 86400 - time()) / 60);
         if($ban_len > 0) user_ban('user', $user_row['username'], $ban_len, '', 0, $red_max['warning_text'], $red_max['warning_text'], $red_max['warning_id']);
      }
   }
   // delete bans without warnings
   $sql = 'DELETE FROM ' . BANLIST_TABLE . '
      WHERE ban_userid = ' . $user_row['user_id'] . '
         AND ban_warning_id != 0
         AND ban_warning_id NOT IN (
            SELECT warning_id
            FROM ' . WARNINGS_TABLE . '
            WHERE warning_type = "ban"
               AND user_id = ' . $user_row['user_id'] . '
         )';
   $db->sql_query($sql);
}
?>
Во всех функциях просто запуск warn_autoban__sync($user_id]);
Просьба проверить на адекватность) Надо только подумать как исключить удаление юзеров, добавленных в бан ручками...
Добавлено спустя 49 минут 9 секунд:Подумал...
- Код: Выделить всё
          // One or more entities are already banned/excluded, delete the existing bans, so they can be re-inserted with the given new length
/*
         $sql = 'DELETE FROM ' . BANLIST_TABLE . '
            WHERE ' . $db->sql_in_set($type, $banlist_ary_tmp) . '
               AND ban_exclude = ' . (int) $ban_exclude;
*/
         // dr.death warning autoban
         $sql_where = '';
         if($mode == 'user') $sql_where .= (int)$warning_id ? " AND ban_warning_id != 0 " : " AND ban_warning_id = 0 ";
          $sql = 'DELETE FROM ' . BANLIST_TABLE . '
            WHERE ' . $db->sql_in_set($type, $banlist_ary_tmp) . '
               ' . $sql_where . '
               AND ban_exclude = ' . (int) $ban_exclude;