summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCzterooki <czterooki1337@gmail.com>2013-07-20 18:28:57 -0400
committerCzterooki <czterooki1337@gmail.com>2013-07-20 18:28:57 -0400
commitbc1bc9f6ef08d778b7218e86ea00f43c1d9bce81 (patch)
tree104fcb30ac68a0f76c0aec37fb01ff65c409f927
parentca5283abaddb6014bc6075ea9fbf3a8daa19f2cc (diff)
parentd31be1958de76e5cabc14ddd410287055b6dac0c (diff)
Merge branch 'master' of github.com:vichan-devel/Tinyboard
-rw-r--r--inc/config.php6
-rw-r--r--inc/display.php29
-rw-r--r--inc/mod/pages.php134
-rw-r--r--js/quote-selection.js24
-rw-r--r--js/youtube.js43
-rw-r--r--mod.php4
-rw-r--r--post.php85
-rw-r--r--templates/mod/dashboard.html11
-rw-r--r--templates/mod/search_form.html18
-rw-r--r--templates/mod/search_results.html177
-rw-r--r--templates/themes/sitemap/info.php2
11 files changed, 434 insertions, 99 deletions
diff --git a/inc/config.php b/inc/config.php
index a3b3d528..6860ba42 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -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;
diff --git a/inc/display.php b/inc/display.php
index ba55903d..fe8bb048 100644
--- a/inc/display.php
+++ b/inc/display.php
@@ -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
diff --git a/inc/mod/pages.php b/inc/mod/pages.php
index 12ad1e92..d5ec6018 100644
--- a/inc/mod/pages.php
+++ b/inc/mod/pages.php
@@ -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;
diff --git a/js/quote-selection.js b/js/quote-selection.js
index 0c5b7e7d..0722c0b1 100644
--- a/js/quote-selection.js
+++ b/js/quote-selection.js
@@ -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) {
diff --git a/js/youtube.js b/js/youtube.js
new file mode 100644
index 00000000..f64d4874
--- /dev/null
+++ b/js/youtube.js
@@ -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);
+ });
+});
+
diff --git a/mod.php b/mod.php
index e76f1f01..d3dc5c23 100644
--- a/mod.php
+++ b/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
diff --git a/post.php b/post.php
index 2825b40b..4ded8622 100644
--- a/post.php
+++ b/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));
}
}
}
diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html
index e54b3cd3..619663f5 100644
--- a/templates/mod/dashboard.html
+++ b/templates/mod/dashboard.html
@@ -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>
diff --git a/templates/mod/search_form.html b/templates/mod/search_form.html
new file mode 100644
index 00000000..d8a2fed4
--- /dev/null
+++ b/templates/mod/search_form.html
@@ -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> \ No newline at end of file
diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html
new file mode 100644
index 00000000..b441a28f
--- /dev/null
+++ b/templates/mod/search_results.html
@@ -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 %} \ No newline at end of file
diff --git a/templates/themes/sitemap/info.php b/templates/themes/sitemap/info.php
index 1198c2e3..43b529fa 100644
--- a/templates/themes/sitemap/info.php
+++ b/templates/themes/sitemap/info.php
@@ -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'
);