diff options
| -rw-r--r-- | inc/config.php | 4 | ||||
| -rw-r--r-- | inc/mod/pages.php | 44 | ||||
| -rw-r--r-- | mod.php | 3 | ||||
| -rw-r--r-- | templates/mod/search_form.html | 9 | ||||
| -rw-r--r-- | templates/mod/search_results.html | 52 |
5 files changed, 93 insertions, 19 deletions
diff --git a/inc/config.php b/inc/config.php index 9706178c..424d07d6 100644 --- a/inc/config.php +++ b/inc/config.php @@ -857,8 +857,8 @@ // Number of news entries to display per page $config['mod']['news_page'] = 40; - // Maximum number of results to display for a search, per board - $config['mod']['search_results'] = 75; + // Number of results to dispaly per page + $config['mod']['search_page'] = 200; // How many entries to show per page in the moderator noticeboard $config['mod']['noticeboard_page'] = 50; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index fc5577bc..79d87ba1 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -168,7 +168,7 @@ function mod_search_redirect() { if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); - if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans'))) { + if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans', 'log'))) { $query = $_POST['query']; $query = urlencode($query); $query = str_replace('_', '%5F', $query); @@ -180,14 +180,14 @@ function mod_search_redirect() { } } -function mod_search($type, $query) { +function mod_search($type, $search_query_escaped, $page_no = 1) { global $pdo, $config; if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); // Unescape query - $query = str_replace('_', ' ', $query); + $query = str_replace('_', ' ', $search_query_escaped); $query = urldecode($query); $search_query = $query; @@ -207,8 +207,9 @@ function mod_search($type, $query) { $match = array(); // Exact phrases ("like this") - if (preg_match_all('/"(.+?)"/', $query, $matches)) { - foreach ($matches[1] as $phrase) { + if (preg_match_all('/"(.+?)"/', $query, $exact_phrases)) { + $exact_phrases = $exact_phrases[1]; + foreach ($exact_phrases as $phrase) { $query = str_replace("\"{$phrase}\"", '', $query); $match[] = $pdo->quote($phrase); } @@ -229,6 +230,8 @@ function mod_search($type, $query) { $sql_field = 'body'; if ($type == 'bans') $sql_field = 'reason'; + if ($type == 'log') + $sql_field = 'text'; // Build the "LIKE 'this' AND LIKE 'that'" etc. part of the SQL query $sql_like = ''; @@ -239,19 +242,37 @@ function mod_search($type, $query) { $sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\''; } + + // Compile SQL query + if ($type == 'posts') { error('Searching posts is under development. Sorry.'); } if ($type == 'IP_notes') { - $query = query('SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC') or error(db_error()); - $results = $query->fetchAll(PDO::FETCH_ASSOC); + $query = 'SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; + $sql_table = 'ip_notes'; } if ($type == 'bans') { - $query = query('SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set`') or error(db_error()); - $results = $query->fetchAll(PDO::FETCH_ASSOC); + $query = 'SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set` DESC'; + $sql_table = 'bans'; + } + + if ($type == 'log') { + $query = 'SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; + $sql_table = 'modlogs'; + } + // Execute SQL query (with pages) + $q = query($query . ' LIMIT ' . (($page_no - 1) * $config['mod']['search_page']) . ', ' . $config['mod']['search_page']) or error(db_error()); + $results = $q->fetchAll(PDO::FETCH_ASSOC); + + // Get total result count + $q = query('SELECT COUNT(*) FROM `' . $sql_table . '` WHERE ' . $sql_like) or error(db_error()); + $result_count = $q->fetchColumn(); + + if ($type == 'bans') { foreach ($results as &$ban) { if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false) $ban['real_ip'] = true; @@ -259,11 +280,12 @@ function mod_search($type, $query) { } // $results now contains the search results - + mod_page(_('Search results'), 'mod/search_results.html', array( 'search_type' => $type, 'search_query' => $search_query, - 'result_count' => count($results), + 'search_query_escaped' => $search_query_escaped, + 'result_count' => $result_count, 'results' => $results )); } @@ -58,7 +58,8 @@ $pages = array( '/bans/(\d+)' => 'bans', // ban list '/search' => 'search_redirect', // search - '/search/(posts|IP_notes|bans)/(.+)' => 'search', // search + '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search + '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search // CSRF-protected moderator actions '/ban' => 'secure_POST ban', // new ban diff --git a/templates/mod/search_form.html b/templates/mod/search_form.html index c74121fd..d8a2fed4 100644 --- a/templates/mod/search_form.html +++ b/templates/mod/search_form.html @@ -2,12 +2,15 @@ <label style="display:inline" for="search">{% trans 'Phrase:' %}</label> <input id="search" name="query" type="text" size="60" value="{{ search_query|e }}"> <select name="type"> - <option value="posts"{% if search_type == 'posts'%} selected{% endif %}>Posts</option> + <option value="posts"{% if search_type == 'posts'%} selected{% endif %}>{% trans 'Posts' %}</option> {% if mod|hasPermission(config.mod.view_notes) and mod|hasPermission(config.mod.show_ip) %} - <option value="IP_notes"{% if search_type == 'IP_notes'%} selected{% endif %}>IP address notes</option> + <option value="IP_notes"{% if search_type == 'IP_notes'%} selected{% endif %}>{% trans 'IP address notes' %}</option> {% endif %} {% if mod|hasPermission(config.mod.view_banlist) %} - <option value="bans"{% if search_type == 'bans'%} selected{% endif %}>Bans</option> + <option value="bans"{% if search_type == 'bans'%} selected{% endif %}>{% trans 'Bans' %}</option> + {% endif %} + {% if mod|hasPermission(config.mod.modlog) %} + <option value="log"{% if search_type == 'log'%} selected{% endif %}>{% trans 'Moderation log' %}</option> {% endif %} </select> <input type="submit" value="{% trans 'Search' %}"> diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index 84de8969..b441a28f 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -41,7 +41,6 @@ </table> {% endif %} - {% if search_type == 'bans' %} <table class="modlog" style="width:100%"> <tr> @@ -126,4 +125,53 @@ </tr> {% endfor %} </table> -{% endif %}
\ No newline at end of file +{% endif %} + +{% if search_type == 'log' %} + <table class="modlog"> + <tr> + <th>{% trans 'Staff' %}</th> + <th>{% trans 'IP address' %}</th> + <th>{% trans 'Time' %}</th> + <th>{% trans 'Board' %}</th> + <th>{% trans 'Action' %}</th> + </tr> + {% for log in results %} + <tr> + <td class="minimal"> + {% if log.username %} + <a href="?/log:{{ log.username|e }}">{{ log.username|e }}</a> + {% elseif log.mod == -1 %} + <em>system</em> + {% else %} + <em>{% trans 'deleted?' %}</em> + {% endif %} + </td> + <td class="minimal"> + <a href="?/IP/{{ log.ip }}">{{ log.ip }}</a> + </td> + <td class="minimal"> + <span title="{{ log.time|date(config.post_date) }}">{{ log.time|ago }}</span> + </td> + <td class="minimal"> + {% if log.board %} + <a href="?/{{ config.board_path|sprintf(log.board) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(log.board) }}</a> + {% else %} + - + {% endif %} + </td> + <td> + {{ log.text }} + </td> + </tr> + {% endfor %} + </table> +{% endif %} + +{% if result_count > results|count %} + <p class="unimportant" style="text-align:center;word-wrap:break-word"> + {% for i in range(0, (result_count - 1) / config.mod.search_page) %} + <a href="?/search/{{ search_type }}/{{ search_query_escaped }}/{{ i + 1 }}">[{{ i + 1 }}]</a> + {% endfor %} + </p> +{% endif %}
\ No newline at end of file |
