mirror of
https://github.com/vichan-devel/vichan.git
synced 2024-11-27 17:00:52 +01:00
Bring back search (searching posts not implemented yet)
This commit is contained in:
parent
158a7c0e79
commit
e62b83e79c
@ -1015,7 +1015,7 @@
|
|||||||
$config['mod']['master_pm'] = ADMIN;
|
$config['mod']['master_pm'] = ADMIN;
|
||||||
// Rebuild everything
|
// Rebuild everything
|
||||||
$config['mod']['rebuild'] = ADMIN;
|
$config['mod']['rebuild'] = ADMIN;
|
||||||
// Search through posts
|
// Search through posts, IP address notes and bans
|
||||||
$config['mod']['search'] = JANITOR;
|
$config['mod']['search'] = JANITOR;
|
||||||
// Read the moderator noticeboard
|
// Read the moderator noticeboard
|
||||||
$config['mod']['noticeboard'] = JANITOR;
|
$config['mod']['noticeboard'] = JANITOR;
|
||||||
|
@ -162,6 +162,112 @@ function mod_dashboard() {
|
|||||||
mod_page(_('Dashboard'), 'mod/dashboard.html', $args);
|
mod_page(_('Dashboard'), 'mod/dashboard.html', $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mod_search_redirect() {
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
if (!hasPermission($config['mod']['search']))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
|
||||||
|
if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans'))) {
|
||||||
|
$query = $_POST['query'];
|
||||||
|
$query = urlencode($query);
|
||||||
|
$query = str_replace('_', '%5F', $query);
|
||||||
|
$query = str_replace('+', '_', $query);
|
||||||
|
|
||||||
|
header('Location: ?/search/' . $_POST['type'] . '/' . $query, true, $config['redirect_http']);
|
||||||
|
} else {
|
||||||
|
header('Location: ?/', true, $config['redirect_http']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mod_search($type, $query) {
|
||||||
|
global $pdo, $config;
|
||||||
|
|
||||||
|
if (!hasPermission($config['mod']['search']))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
|
||||||
|
// Unescape query
|
||||||
|
$query = str_replace('_', ' ', $query);
|
||||||
|
$query = urldecode($query);
|
||||||
|
$search_query = $query;
|
||||||
|
|
||||||
|
// Form a series of LIKE clauses for the query.
|
||||||
|
// This gets a little complicated.
|
||||||
|
|
||||||
|
// Escape "escape" character
|
||||||
|
$query = str_replace('!', '!!', $query);
|
||||||
|
|
||||||
|
// Escape SQL wildcard
|
||||||
|
$query = str_replace('%', '!%', $query);
|
||||||
|
|
||||||
|
// Use asterisk as wildcard instead
|
||||||
|
$query = str_replace('*', '%', $query);
|
||||||
|
|
||||||
|
// Array of phrases to match
|
||||||
|
$match = array();
|
||||||
|
|
||||||
|
// Exact phrases ("like this")
|
||||||
|
if (preg_match_all('/"(.+?)"/', $query, $matches)) {
|
||||||
|
foreach ($matches[1] as $phrase) {
|
||||||
|
$query = str_replace("\"{$phrase}\"", '', $query);
|
||||||
|
$match[] = $pdo->quote($phrase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-exact phrases (ie. plain keywords)
|
||||||
|
$keywords = explode(' ', $query);
|
||||||
|
foreach ($keywords as $word) {
|
||||||
|
if (empty($word))
|
||||||
|
continue;
|
||||||
|
$match[] = $pdo->quote($word);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which `field` to search?
|
||||||
|
if ($type == 'posts')
|
||||||
|
$sql_field = 'body';
|
||||||
|
if ($type == 'IP_notes')
|
||||||
|
$sql_field = 'body';
|
||||||
|
if ($type == 'bans')
|
||||||
|
$sql_field = 'reason';
|
||||||
|
|
||||||
|
// Build the "LIKE 'this' AND LIKE 'that'" etc. part of the SQL query
|
||||||
|
$sql_like = '';
|
||||||
|
foreach ($match as $phrase) {
|
||||||
|
if (!empty($sql_like))
|
||||||
|
$sql_like .= ' AND ';
|
||||||
|
$phrase = preg_replace('/^\'(.+)\'$/', '\'%$1%\'', $phrase);
|
||||||
|
$sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\'';
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
foreach ($results as &$ban) {
|
||||||
|
if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false)
|
||||||
|
$ban['real_ip'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $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),
|
||||||
|
'results' => $results
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
function mod_edit_board($boardName) {
|
function mod_edit_board($boardName) {
|
||||||
global $board, $config;
|
global $board, $config;
|
||||||
|
|
||||||
|
3
mod.php
3
mod.php
@ -56,6 +56,9 @@ $pages = array(
|
|||||||
'/IP/([\w.:]+)/remove_note/(\d+)' => 'ip_remove_note', // remove note from ip address
|
'/IP/([\w.:]+)/remove_note/(\d+)' => 'ip_remove_note', // remove note from ip address
|
||||||
'/bans' => 'bans', // ban list
|
'/bans' => 'bans', // ban list
|
||||||
'/bans/(\d+)' => 'bans', // ban list
|
'/bans/(\d+)' => 'bans', // ban list
|
||||||
|
|
||||||
|
'/search' => 'search_redirect', // search
|
||||||
|
'/search/(posts|IP_notes|bans)/(.+)' => 'search', // search
|
||||||
|
|
||||||
// CSRF-protected moderator actions
|
// CSRF-protected moderator actions
|
||||||
'/ban' => 'secure_POST ban', // new ban
|
'/ban' => 'secure_POST ban', // new ban
|
||||||
|
@ -101,22 +101,17 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{#
|
{% if mod|hasPermission(config.mod.search) %}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans 'Search' %}</legend>
|
<legend>{% trans 'Search' %}</legend>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<form style="display:inline" action="?/search" method="post">
|
{% include 'mod/search_form.html' %}
|
||||||
<label style="display:inline" for="search">{% trans 'Phrase:' %}</label>
|
|
||||||
<input id="search" name="search" type="text" size="35">
|
|
||||||
<input type="submit" value="{% trans 'Search' %}">
|
|
||||||
</form>
|
|
||||||
<p class="unimportant">{% trans '(Search is case-insensitive, and based on keywords. To match exact phrases, use "quotes". Use an asterisk (*) for wildcard.)' %}</p>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
#}
|
{% endif %}
|
||||||
|
|
||||||
{% if config.debug %}
|
{% if config.debug %}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
15
templates/mod/search_form.html
Normal file
15
templates/mod/search_form.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<form style="display:inline" action="?/search" method="post">
|
||||||
|
<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>
|
||||||
|
{% 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>
|
||||||
|
{% endif %}
|
||||||
|
{% if mod|hasPermission(config.mod.view_banlist) %}
|
||||||
|
<option value="bans"{% if search_type == 'bans'%} selected{% endif %}>Bans</option>
|
||||||
|
{% endif %}
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="{% trans 'Search' %}">
|
||||||
|
</form>
|
||||||
|
<p class="unimportant">{% trans '(Search is case-insensitive and based on keywords. To match exact phrases, use "quotes". Use an asterisk (*) for wildcard.)' %}</p>
|
129
templates/mod/search_results.html
Normal file
129
templates/mod/search_results.html
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<fieldset style="margin-bottom:20px">
|
||||||
|
<legend>{% trans 'Search' %}</legend>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
{% include 'mod/search_form.html' %}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<p style="text-align:center">Showing {{ result_count }} result{% if result_count != 1 %}s{% endif %}.</p>
|
||||||
|
|
||||||
|
{% if search_type == 'IP_notes' %}
|
||||||
|
<table class="modlog">
|
||||||
|
<tr>
|
||||||
|
<th>{% trans 'IP address' %}</th>
|
||||||
|
<th>{% trans 'Staff' %}</th>
|
||||||
|
<th>{% trans 'Note' %}</th>
|
||||||
|
<th>{% trans 'Date' %}</th>
|
||||||
|
</tr>
|
||||||
|
{% for note in results %}
|
||||||
|
<tr>
|
||||||
|
<td class="minimal">
|
||||||
|
<a href="?/IP/{{ note.ip }}#notes">{{ note.ip }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="minimal">
|
||||||
|
{% if note.username %}
|
||||||
|
<a href="?/new_PM/{{ note.username|e }}">{{ note.username|e }}</a>
|
||||||
|
{% else %}
|
||||||
|
<em>{% trans 'deleted?' %}</em>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ note.body }}
|
||||||
|
</td>
|
||||||
|
<td class="minimal">
|
||||||
|
{{ note.time|date(config.post_date) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if search_type == 'bans' %}
|
||||||
|
<table class="modlog" style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<th>{% trans 'IP address/mask' %}</th>
|
||||||
|
<th>{% trans 'Reason' %}</th>
|
||||||
|
<th>{% trans 'Board' %}</th>
|
||||||
|
<th>{% trans 'Set' %}</th>
|
||||||
|
<th>{% trans 'Duration' %}</th>
|
||||||
|
<th>{% trans 'Expires' %}</th>
|
||||||
|
<th>{% trans 'Seen' %}</th>
|
||||||
|
<th>{% trans 'Staff' %}</th>
|
||||||
|
</tr>
|
||||||
|
{% for ban in results %}
|
||||||
|
<tr{% if ban.expires != 0 and ban.expires < time() %} style="text-decoration:line-through"{% endif %}>
|
||||||
|
<td style="white-space: nowrap">
|
||||||
|
{% if ban.real_ip %}
|
||||||
|
<a href="?/IP/{{ ban.ip }}#bans">{{ ban.ip }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ ban.ip|e }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if ban.reason %}
|
||||||
|
{{ ban.reason }}
|
||||||
|
{% else %}
|
||||||
|
-
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td style="white-space: nowrap">
|
||||||
|
{% if ban.board %}
|
||||||
|
{{ config.board_abbreviation|sprintf(ban.board) }}
|
||||||
|
{% else %}
|
||||||
|
<em>{% trans 'all boards' %}</em>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td style="white-space: nowrap">
|
||||||
|
<span title="{{ ban.set|date(config.post_date) }}">
|
||||||
|
{{ ban.set|ago }} ago
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="white-space: nowrap">
|
||||||
|
{% if ban.expires == 0 %}
|
||||||
|
-
|
||||||
|
{% else %}
|
||||||
|
{{ (ban.expires - ban.set + time()) | until }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td style="white-space: nowrap">
|
||||||
|
{% if ban.expires == 0 %}
|
||||||
|
<em>{% trans 'never' %}</em>
|
||||||
|
{% else %}
|
||||||
|
{{ ban.expires|date(config.post_date) }}
|
||||||
|
{% if ban.expires > time() %}
|
||||||
|
<small>(in {{ ban.expires|until }})</small>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if ban.seen %}
|
||||||
|
{% trans 'Yes' %}
|
||||||
|
{% else %}
|
||||||
|
{% trans 'No' %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if ban.username %}
|
||||||
|
{% if mod|hasPermission(config.mod.view_banstaff) %}
|
||||||
|
<a href="?/new_PM/{{ ban.username|e }}">{{ ban.username|e }}</a>
|
||||||
|
{% else %}
|
||||||
|
{% if mod|hasPermission(config.mod.view_banquestionmark) %}
|
||||||
|
<em>?</em>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elseif ban.mod == -1 %}
|
||||||
|
<em>system</em>
|
||||||
|
{% else %}
|
||||||
|
<em>{% trans 'deleted?' %}</em>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
Loading…
Reference in New Issue
Block a user