public function match(array $post, $condition, $match) { $condition = strtolower($condition); switch ($condition) { case 'custom': if (!is_callable($match)) { error('Custom condition for filter is not callable!'); } return $match($post); case 'flood-match': if (!is_array($match)) { error('Filter condition "flood-match" must be an array.'); } // Filter out "flood" table entries which do not match this filter. $flood_check_matched = array(); foreach ($this->flood_check as $flood_post) { foreach ($match as $flood_match_arg) { switch ($flood_match_arg) { case 'ip': if ($flood_post['ip'] != $_SERVER['REMOTE_ADDR']) { continue 3; } break; case 'body': if ($flood_post['posthash'] != make_comment_hex($post['body_nomarkup'])) { continue 3; } break; case 'file': if (!isset($post['filehash'])) { return false; } if ($flood_post['filehash'] != $post['filehash']) { continue 3; } break; case 'board': if ($flood_post['board'] != $post['board']) { continue 3; } break; case 'isreply': if ($flood_post['isreply'] == $post['op']) { continue 3; } break; default: error('Invalid filter flood condition: ' . $flood_match_arg); } } $flood_check_matched[] = $flood_post; } $this->flood_check = $flood_check_matched; return !empty($this->flood_check); case 'flood-time': foreach ($this->flood_check as $flood_post) { if (time() - $flood_post['time'] <= $match) { return true; } } return false; case 'flood-count': $count = 0; foreach ($this->flood_check as $flood_post) { if (time() - $flood_post['time'] <= $this->condition['flood-time']) { ++$count; } } return $count >= $match; case 'name': return preg_match($match, $post['name']); case 'trip': return $match === $post['trip']; case 'email': return preg_match($match, $post['email']); case 'subject': return preg_match($match, $post['subject']); case 'body': return preg_match($match, $post['body_nomarkup']); case 'filehash': return $match === $post['filehash']; case 'filename': if (!$post['has_file']) { return false; } return preg_match($match, $post['filename']); case 'extension': if (!$post['has_file']) { return false; } return preg_match($match, $post['body']); case 'ip': return preg_match($match, $_SERVER['REMOTE_ADDR']); case 'op': return $post['op'] == $match; case 'has_file': return $post['has_file'] == $match; default: error('Unknown filter condition: ' . $condition); } }
function insertFloodPost(array $post) { global $board; $query = prepare("INSERT INTO ``flood`` VALUES (NULL, :ip, :board, :time, :posthash, :filehash, :isreply)"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board['uri']); $query->bindValue(':time', time()); $query->bindValue(':posthash', make_comment_hex($post['body_nomarkup'])); if ($post['has_file']) { $query->bindValue(':filehash', $post['filehash']); } else { $query->bindValue(':filehash', null, PDO::PARAM_NULL); } $query->bindValue(':isreply', !$post['op'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); }
function mod_debug_recent_posts() { global $pdo, $config; $limit = 500; $boards = listBoards(); // Manually build an SQL query $query = 'SELECT * FROM ('; foreach ($boards as $board) { $query .= sprintf('SELECT *, %s AS `board` FROM ``posts_%s`` UNION ALL ', $pdo->quote($board['uri']), $board['uri']); } // Remove the last "UNION ALL" seperator and complete the query $query = preg_replace('/UNION ALL $/', ') AS `all_posts` ORDER BY `time` DESC LIMIT ' . $limit, $query); $query = query($query) or error(db_error()); $posts = $query->fetchAll(PDO::FETCH_ASSOC); // Fetch recent posts from flood prevention cache $query = query("SELECT * FROM ``flood`` ORDER BY `time` DESC") or error(db_error()); $flood_posts = $query->fetchAll(PDO::FETCH_ASSOC); foreach ($posts as &$post) { $post['snippet'] = pm_snippet($post['body']); foreach ($flood_posts as $flood_post) { if ($flood_post['time'] == $post['time'] && $flood_post['posthash'] == make_comment_hex($post['body_nomarkup']) && $flood_post['filehash'] == $post['filehash']) { $post['in_flood_table'] = true; } } } mod_page(_('Debug: Recent posts'), 'mod/debug/recent_posts.html', array('posts' => $posts, 'flood_posts' => $flood_posts)); }