mirror of
https://github.com/vichan-devel/vichan.git
synced 2025-01-18 17:14:04 +01:00
Merge branch 'master' of github.com:vichan-devel/Tinyboard
This commit is contained in:
commit
bc1bc9f6ef
@ -899,8 +899,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;
|
||||
@ -1057,7 +1057,7 @@
|
||||
$config['mod']['master_pm'] = ADMIN;
|
||||
// Rebuild everything
|
||||
$config['mod']['rebuild'] = ADMIN;
|
||||
// Search through posts
|
||||
// Search through posts, IP address notes and bans
|
||||
$config['mod']['search'] = JANITOR;
|
||||
// Read the moderator noticeboard
|
||||
$config['mod']['noticeboard'] = JANITOR;
|
||||
|
@ -241,6 +241,29 @@ function secure_link($href) {
|
||||
return $href . '/' . make_secure_link_token($href);
|
||||
}
|
||||
|
||||
function embed_html($link) {
|
||||
global $config;
|
||||
|
||||
foreach ($config['embedding'] as $embed) {
|
||||
if ($html = preg_replace($embed[0], $embed[1], $link)) {
|
||||
if ($html == $link)
|
||||
continue; // Nope
|
||||
|
||||
$html = str_replace('%%tb_width%%', $config['embed_width'], $html);
|
||||
$html = str_replace('%%tb_height%%', $config['embed_height'], $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
if ($link[0] == '<') {
|
||||
// Prior to v0.9.6-dev-8, HTML code for embedding was stored in the database instead of the link.
|
||||
return $link;
|
||||
}
|
||||
|
||||
return 'Embedding error.';
|
||||
}
|
||||
|
||||
class Post {
|
||||
public function __construct($id, $thread, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $embed, $root=null, $mod=false) {
|
||||
global $config;
|
||||
@ -269,6 +292,9 @@ class Post {
|
||||
$this->root = $root;
|
||||
$this->mod = $mod;
|
||||
|
||||
if ($this->embed)
|
||||
$this->embed = embed_html($this->embed);
|
||||
|
||||
if ($this->mod)
|
||||
// Fix internal links
|
||||
// Very complicated regex
|
||||
@ -365,6 +391,9 @@ class Thread {
|
||||
$this->mod = $mod;
|
||||
$this->hr = $hr;
|
||||
|
||||
if ($this->embed)
|
||||
$this->embed = embed_html($this->embed);
|
||||
|
||||
if ($this->mod)
|
||||
// Fix internal links
|
||||
// Very complicated regex
|
||||
|
@ -162,6 +162,140 @@ function mod_dashboard() {
|
||||
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', 'log'))) {
|
||||
$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, $search_query_escaped, $page_no = 1) {
|
||||
global $pdo, $config;
|
||||
|
||||
if (!hasPermission($config['mod']['search']))
|
||||
error($config['error']['noaccess']);
|
||||
|
||||
// Unescape query
|
||||
$query = str_replace('_', ' ', $search_query_escaped);
|
||||
$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, $exact_phrases)) {
|
||||
$exact_phrases = $exact_phrases[1];
|
||||
foreach ($exact_phrases 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';
|
||||
if ($type == 'log')
|
||||
$sql_field = 'text';
|
||||
|
||||
// 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 \'!\'';
|
||||
}
|
||||
|
||||
|
||||
// Compile SQL query
|
||||
|
||||
if ($type == 'posts') {
|
||||
error('Searching posts is under development. Sorry.');
|
||||
}
|
||||
|
||||
if ($type == 'IP_notes') {
|
||||
$query = 'SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC';
|
||||
$sql_table = 'ip_notes';
|
||||
if (!hasPermission($config['mod']['view_notes']) || !hasPermission($config['mod']['show_ip']))
|
||||
error($config['error']['noaccess']);
|
||||
}
|
||||
|
||||
if ($type == 'bans') {
|
||||
$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 (!hasPermission($config['mod']['view_banlist']))
|
||||
error($config['error']['noaccess']);
|
||||
}
|
||||
|
||||
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';
|
||||
if (!hasPermission($config['mod']['modlog']))
|
||||
error($config['error']['noaccess']);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// $results now contains the search results
|
||||
|
||||
mod_page(_('Search results'), 'mod/search_results.html', array(
|
||||
'search_type' => $type,
|
||||
'search_query' => $search_query,
|
||||
'search_query_escaped' => $search_query_escaped,
|
||||
'result_count' => $result_count,
|
||||
'results' => $results
|
||||
));
|
||||
}
|
||||
|
||||
function mod_edit_board($boardName) {
|
||||
global $board, $config;
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
/*
|
||||
* quote-selection.js
|
||||
*
|
||||
* This is a little buggy.
|
||||
* Allows you to quote a post by just selecting some text, then beginning to type.
|
||||
*
|
||||
* Released under the MIT license
|
||||
* Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org>
|
||||
*
|
||||
@ -31,12 +34,15 @@ $(document).ready(function(){
|
||||
|
||||
var altKey = false;
|
||||
var ctrlKey = false;
|
||||
var metaKey = false;
|
||||
|
||||
$(document).keyup(function(e) {
|
||||
if (e.altKey)
|
||||
if (e.keyCode == 18)
|
||||
altKey = false;
|
||||
else if (e.ctrlKey)
|
||||
else if (e.keyCode == 17)
|
||||
ctrlKey = false;
|
||||
else if (e.keyCode == 91)
|
||||
metaKey = false;
|
||||
});
|
||||
|
||||
$(document).keydown(function(e) {
|
||||
@ -44,9 +50,11 @@ $(document).ready(function(){
|
||||
altKey = true;
|
||||
else if (e.ctrlKey)
|
||||
ctrlKey = true;
|
||||
else if (e.metaKey)
|
||||
metaKey = true;
|
||||
|
||||
if (altKey || ctrlKey) {
|
||||
console.log('CTRL/ALT used. Ignoring');
|
||||
if (altKey || ctrlKey || metaKey) {
|
||||
// console.log('CTRL/ALT/Something used. Ignoring');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -56,20 +64,20 @@ $(document).ready(function(){
|
||||
var selection = window.getSelection();
|
||||
var $post = $(selection.anchorNode).parents('.post');
|
||||
if ($post.length == 0) {
|
||||
console.log('Start of selection was not post div', $(selection.anchorNode).parent());
|
||||
// console.log('Start of selection was not post div', $(selection.anchorNode).parent());
|
||||
return;
|
||||
}
|
||||
|
||||
var postID = $post.find('.post_no:eq(1)').text();
|
||||
|
||||
if (postID != $(selection.focusNode).parents('.post').find('.post_no:eq(1)').text()) {
|
||||
console.log('Selection left post div', $(selection.focusNode).parent());
|
||||
// console.log('Selection left post div', $(selection.focusNode).parent());
|
||||
return;
|
||||
}
|
||||
|
||||
;
|
||||
var selectedText = selection.toString();
|
||||
console.log('Selected text: ' + selectedText.replace(/\n/g, '\\n').replace(/\r/g, '\\r'));
|
||||
// console.log('Selected text: ' + selectedText.replace(/\n/g, '\\n').replace(/\r/g, '\\r'));
|
||||
|
||||
if ($('body').hasClass('debug'))
|
||||
alert(selectedText);
|
||||
@ -86,7 +94,7 @@ $(document).ready(function(){
|
||||
/* to solve some bugs on weird browsers, we need to replace \r\n with \n and then undo that after */
|
||||
var quote = (last_quote != postID ? '>>' + postID + '\r\n' : '') + $.trim(selectedText).replace(/\r\n/g, '\n').replace(/^/mg, '>').replace(/\n/g, '\r\n') + '\r\n';
|
||||
|
||||
console.log('Deselecting text');
|
||||
// console.log('Deselecting text');
|
||||
selection.removeAllRanges();
|
||||
|
||||
if (document.selection) {
|
||||
|
43
js/youtube.js
Normal file
43
js/youtube.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* youtube
|
||||
* https://github.com/savetheinternet/Tinyboard/blob/master/js/youtube.js
|
||||
*
|
||||
* Don't load the YouTube player unless the video image is clicked.
|
||||
* This increases performance issues when many videos are embedded on the same page.
|
||||
* Currently only compatiable with YouTube.
|
||||
*
|
||||
* Proof of concept.
|
||||
*
|
||||
* Released under the MIT license
|
||||
* Copyright (c) 2013 Michael Save <savetheinternet@tinyboard.org>
|
||||
*
|
||||
* Usage:
|
||||
* $config['embedding'] = array();
|
||||
* $config['embedding'][0] = array(
|
||||
* '/^https?:\/\/(\w+\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9\-_]{10,11})(&.+)?$/i',
|
||||
* '<div class="video-container" data-video="$2"><a href="$0" target="_blank" class="file"><img style="width:360px;height:270px;" src="//img.youtube.com/vi/$2/0.jpg"/></a></div>'
|
||||
);
|
||||
* $config['additional_javascript'][] = 'js/jquery.min.js';
|
||||
* $config['additional_javascript'][] = 'js/youtube.js';
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
onready(function(){
|
||||
var do_embed_yt = function(tag) {
|
||||
$('div.video-container a', tag).click(function() {
|
||||
var videoID = $(this.parentNode).data('video');
|
||||
|
||||
$(this.parentNode).html('<iframe style="float:left;margin: 10px 20px" type="text/html" width="360" height="270" src="//www.youtube.com/embed/' + videoID + '?autoplay=1" frameborder="0"/>');
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
do_embed_yt(document);
|
||||
|
||||
// allow to work with auto-reload.js, etc.
|
||||
$(document).bind('new_post', function(e, post) {
|
||||
do_embed_yt(post);
|
||||
});
|
||||
});
|
||||
|
4
mod.php
4
mod.php
@ -56,6 +56,10 @@ $pages = array(
|
||||
'/IP/([\w.:]+)/remove_note/(\d+)' => 'ip_remove_note', // remove note from ip address
|
||||
'/bans' => 'bans', // ban list
|
||||
'/bans/(\d+)' => 'bans', // ban list
|
||||
|
||||
'/search' => 'search_redirect', // 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
|
||||
|
85
post.php
85
post.php
@ -251,19 +251,10 @@ if (isset($_POST['delete'])) {
|
||||
// yep; validate it
|
||||
$value = $_POST['embed'];
|
||||
foreach ($config['embedding'] as &$embed) {
|
||||
if ($html = preg_replace($embed[0], $embed[1], $value)) {
|
||||
if ($html == $value) {
|
||||
// Nope.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Width and height
|
||||
$html = str_replace('%%tb_width%%', $config['embed_width'], $html);
|
||||
$html = str_replace('%%tb_height%%', $config['embed_height'], $html);
|
||||
|
||||
// Validated. It works.
|
||||
$post['embed'] = $html;
|
||||
// This looks messy right now, I know. I'll work on a better alternative later.
|
||||
if (preg_match($embed[0], $value)) {
|
||||
// Valid link
|
||||
$post['embed'] = $value;
|
||||
// This is bad, lol.
|
||||
$post['no_longer_require_an_image_for_op'] = true;
|
||||
break;
|
||||
}
|
||||
@ -442,72 +433,8 @@ if (isset($_POST['delete'])) {
|
||||
if ($config['thumb_method'] == 'convert') {
|
||||
if ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg') {
|
||||
$exif = exif_read_data($upload);
|
||||
if (isset($exif['Orientation'])) {
|
||||
switch($exif['Orientation']) {
|
||||
case 1:
|
||||
// Normal
|
||||
$args = false;
|
||||
break;
|
||||
case 2:
|
||||
// 888888
|
||||
// 88
|
||||
// 8888
|
||||
// 88
|
||||
// 88
|
||||
|
||||
$args = '-flop';
|
||||
break;
|
||||
case 3:
|
||||
|
||||
// 88
|
||||
// 88
|
||||
// 8888
|
||||
// 88
|
||||
// 888888
|
||||
|
||||
$args = '-flip -flop';
|
||||
break;
|
||||
case 4:
|
||||
// 88
|
||||
// 88
|
||||
// 8888
|
||||
// 88
|
||||
// 888888
|
||||
|
||||
$args = '-flip';
|
||||
break;
|
||||
case 5:
|
||||
// 8888888888
|
||||
// 88 88
|
||||
// 88
|
||||
|
||||
$args = '-rotate 90 -flop';
|
||||
break;
|
||||
case 6:
|
||||
// 88
|
||||
// 88 88
|
||||
// 8888888888
|
||||
|
||||
$args = '-rotate 90';
|
||||
break;
|
||||
case 7:
|
||||
// 88
|
||||
// 88 88
|
||||
// 8888888888
|
||||
|
||||
$args = '-rotate "-90" -flop';
|
||||
break;
|
||||
case 8:
|
||||
// 8888888888
|
||||
// 88 88
|
||||
// 88
|
||||
|
||||
$args = '-rotate "-90"';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($args)
|
||||
shell_exec('convert ' . escapeshellarg($upload) . ' ' . $args . ' ' . escapeshellarg($upload));
|
||||
if (isset($exif['Orientation']) && $exif['Orientation'] != 1) {
|
||||
shell_exec('convert ' . escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,22 +101,17 @@
|
||||
</ul>
|
||||
</fieldset>
|
||||
|
||||
{#
|
||||
{% if mod|hasPermission(config.mod.search) %}
|
||||
<fieldset>
|
||||
<legend>{% trans 'Search' %}</legend>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<form style="display:inline" action="?/search" method="post">
|
||||
<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>
|
||||
{% include 'mod/search_form.html' %}
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
#}
|
||||
{% endif %}
|
||||
|
||||
{% if config.debug %}
|
||||
<fieldset>
|
||||
|
18
templates/mod/search_form.html
Normal file
18
templates/mod/search_form.html
Normal file
@ -0,0 +1,18 @@
|
||||
<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 %}>{% 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 %}>{% trans 'IP address notes' %}</option>
|
||||
{% endif %}
|
||||
{% if mod|hasPermission(config.mod.view_banlist) %}
|
||||
<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' %}">
|
||||
</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>
|
177
templates/mod/search_results.html
Normal file
177
templates/mod/search_results.html
Normal file
@ -0,0 +1,177 @@
|
||||
<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 %}
|
||||
|
||||
{% 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 %}
|
@ -23,7 +23,7 @@
|
||||
'name' => 'url',
|
||||
'type' => 'text',
|
||||
'comment' => '(with trailing slash)',
|
||||
'default' => 'http://' . (isset ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : "localhost") . $config['root'],
|
||||
'default' => (isset($_SERVER['HTTP_HOST']) ? 'http://' . $_SERVER['HTTP_HOST'] . $config['root'] : ''),
|
||||
'size' => '20'
|
||||
);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user