From 97a22e57c1ef3c3e41ed5666255c1e941df21f3e Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 20 Jul 2013 22:47:26 -0400 Subject: Remove imgcaptcha, this code is unused in any of our forks and needs work to get here back. Revert "Merge branch 'imgcaptcha' of https://github.com/asiekierka/Tinyboard" This reverts commit 49afb685c8e658c0f36b8171e176363538eb9419, reversing changes made to 2451a0f29c08e23ff36ef113082c112224f7e576. Conflicts: js/imgcaptcha.js --- templates/post_form.html | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index 07b53a9f..0ea2b999 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -67,21 +67,6 @@ {% endif %} - {% if config.imgcaptcha %} - - - {% trans %}Verification{% endtrans %} - {{ antibot.html() }} - - - -
- {{ config.imgcaptcha_question }}
- Odswiez - {{ antibot.html() }} - - - {% endif %} {% trans %}File{% endtrans %} -- cgit v1.3 From ed8fe6c27a39222604e65acdb09de27fd85fb0a2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 22 Jul 2013 17:51:13 -0400 Subject: Option to check public ban message by default --- inc/config.php | 4 +++- templates/mod/ban_form.html | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index c2a68e6c..721cff41 100644 --- a/inc/config.php +++ b/inc/config.php @@ -860,7 +860,7 @@ // Number of news entries to display per page $config['mod']['news_page'] = 40; - // Number of results to dispaly per page + // Number of results to display per page $config['mod']['search_page'] = 200; // How many entries to show per page in the moderator noticeboard @@ -868,6 +868,8 @@ // Number of entries to summarize and display on the dashboard $config['mod']['noticeboard_dashboard'] = 5; + // Check public ban message by default + $config['mod']['check_ban_message'] = false; // Default public ban message $config['mod']['default_ban_message'] = 'USER WAS BANNED FOR THIS POST'; // What to append to the post for public bans ("%s" is the message) diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html index edc1ab3b..6c7560ad 100644 --- a/templates/mod/ban_form.html +++ b/templates/mod/ban_form.html @@ -41,11 +41,11 @@ - + ({% trans 'public; attached to post' %}) {% if config.quick_reply %} diff --git a/templates/post_thread.html b/templates/post_thread.html index d7a62d4f..b702712e 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -88,14 +88,26 @@ {% endif %}"> {{ post.id }} - {% if post.sticky %} - Sticky + {% if post.sticky %} + {% if config.font_awesome %} + + {% else %} + Sticky + {% endif %} {% endif %} - {% if post.locked %} - Locked + {% if post.locked %} + {% if config.font_awesome %} + + {% else %} + Locked + {% endif %} {% endif %} - {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %} - Bumplocked + {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %} + {% if config.font_awesome %} + + {% else %} + Bumplocked + {% endif %} {% endif %} {% if index %} [{% trans %}Reply{% endtrans %}] diff --git a/templates/thread.html b/templates/thread.html index aea8abb5..3d2b51de 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -7,7 +7,8 @@ {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} {% if config.meta_keywords %}{% endif %} - {% if config.default_stylesheet.1 != '' %}{% endif %} + {% if config.default_stylesheet.1 != '' %}{% endif %} + {% if config.font_awesome %}{% endif %} {% if not nojavascript %} {% if not config.additional_javascript_compile %} -- cgit v1.3 From 46edec0f2d8c31b55e36e160c7d9bac8bf4d3aa4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 23 Jul 2013 09:46:29 -0400 Subject: Bug with last commit --- templates/index.html | 2 +- templates/thread.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/index.html b/templates/index.html index 9515d50a..430e2eab 100644 --- a/templates/index.html +++ b/templates/index.html @@ -8,7 +8,7 @@ {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} + {% if config.font_awesome %}{% endif %} {% if not nojavascript %} {% if config.quick_reply %} diff --git a/templates/thread.html b/templates/thread.html index 3d2b51de..53c784b4 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -8,7 +8,7 @@ {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} + {% if config.font_awesome %}{% endif %} {% if not nojavascript %} {% if not config.additional_javascript_compile %} -- cgit v1.3 From 4e609da2b75f5fe6d694617735cad77014a504f1 Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 23 Jul 2013 10:34:23 -0400 Subject: fix merge --- templates/post_thread.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_thread.html b/templates/post_thread.html index 6ec45482..cbd37229 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -113,7 +113,7 @@ Locked {% endif %} {% endif %} - {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bump$ + {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %} {% if config.font_awesome %} {% else %} -- cgit v1.3 From 35f8730f40d745b93cefbca92d5e83a18599f70c Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 00:13:54 -0400 Subject: ukko: fix top boardlist losing its fixed status --- templates/themes/ukko/ukko.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index baf0f78d..dc8ed382 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -18,7 +18,7 @@ $(document).ready(function() { cache.push(page); $(data).find('div[id*="thread_"]').each(function() { - $('body').prepend($(this).css('display', 'none').attr('data-board', overflow[0].board)); + $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr('data-board', overflow[0].board)); }); thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); @@ -34,4 +34,4 @@ $(document).ready(function() { } }); -}); \ No newline at end of file +}); -- cgit v1.3 From e3cb427feefbbb4fd6a5e76ce77ef80a240941f1 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 00:57:12 -0400 Subject: ukko: fix javascript interoperation --- js/expand.js | 10 +++++++++- js/hide-threads.js | 12 +++++++++--- js/show-backlinks.js | 7 ++++++- templates/themes/ukko/ukko.js | 3 ++- 4 files changed, 26 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/js/expand.js b/js/expand.js index a737ee7f..06151627 100644 --- a/js/expand.js +++ b/js/expand.js @@ -15,7 +15,7 @@ $(document).ready(function(){ if($('div.banner').length != 0) return; // not index - $('div.post.op span.omitted').each(function() { + var do_expand = function() { $(this) .html($(this).text().replace(_("Click reply to view."), ''+_("Click to expand")+'.')) .find('a').click(function() { @@ -52,5 +52,13 @@ $(document).ready(function(){ } }); }); + } + + $('div.post.op span.omitted').each(do_expand); + + $(document).bind("new_post", function(e, post) { + if (!$(post).hasClass("reply")) { + $(post).find('div.post.op span.omitted').each(do_expand); + } }); }); diff --git a/js/hide-threads.js b/js/hide-threads.js index abaa700f..44bd829b 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -35,7 +35,7 @@ $(document).ready(function(){ } } - $('div.post.op').each(function() { + var do_hide_threads = function() { var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); var thread_container = $(this).parent(); @@ -46,7 +46,7 @@ $(document).ready(function(){ } $('[–] ') - .insertBefore(thread_container.find(':first')) + .insertBefore(thread_container.find(':not(h2,h2 *):first')) .click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); @@ -69,9 +69,15 @@ $(document).ready(function(){ hidden_div.remove(); }); - hidden_div.insertAfter(thread_container.find(':first')); + hidden_div.insertAfter(thread_container.find(':not(h2,h2 *):first')); }); if (hidden_data[board][id]) thread_container.find('.hide-thread-link').click(); + } + + $('div.post.op').each(do_hide_threads); + + $(document).bind('new_post', function(e, post) { + do_hide_threads.call($(post).find('div.post.op')[0]); }); }); diff --git a/js/show-backlinks.js b/js/show-backlinks.js index 4ead494b..f23cfc38 100644 --- a/js/show-backlinks.js +++ b/js/show-backlinks.js @@ -48,7 +48,12 @@ onready(function(){ $('div.post.reply').each(showBackLinks); $(document).bind('new_post', function(e, post) { - showBackLinks.call(post); + if ($(post).hasClass("reply")) { + showBackLinks.call(post); + } + else { + $(post).find('div.post.reply').each(showBackLinks); + } }); }); diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index dc8ed382..6566335e 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -10,6 +10,7 @@ $(document).ready(function() { if(thread.length > 0) { thread.prepend('

/' + overflow[0].board + '/

'); $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); + $(document).trigger('new_post', thread); overflow.shift(); } } else { @@ -25,6 +26,7 @@ $(document).ready(function() { if(thread.length > 0) { thread.prepend('

/' + overflow[0].board + '/

'); $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); + $(document).trigger('new_post', thread); overflow.shift(); } @@ -33,5 +35,4 @@ $(document).ready(function() { } } }); - }); -- cgit v1.3 From e2b1034f091313e89143d40503d51d67e00f2f98 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:38:03 -0400 Subject: categories theme: fix title displaying twice, put boardlist there instead --- templates/themes/categories/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html index 9c7d8340..93eb5b72 100644 --- a/templates/themes/categories/news.html +++ b/templates/themes/categories/news.html @@ -7,7 +7,7 @@ -

{{ settings.title }}

+ {{ boardlist.top }}

{{ settings.title }}

{{ settings.subtitle }}
-- cgit v1.3 From b31487b53d4ec715616d40a3aadf6f3fc345d697 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:43:09 -0400 Subject: categories theme: i18n some strings --- templates/themes/categories/news.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html index 93eb5b72..b3bea2b1 100644 --- a/templates/themes/categories/news.html +++ b/templates/themes/categories/news.html @@ -15,16 +15,16 @@
{% if news|count == 0 %} -

(No news to show.)

+

{% trans %}(No news to show.){% endtrans %}

{% else %} {% for entry in news %}

{% if entry.subject %} {{ entry.subject }} {% else %} - no subject + {% trans %}no subject{% endtrans %} {% endif %} - — by {{ entry.name }} at {{ entry.time|date(config.post_date) }} + — {% trans %}by{% endtrans %} {{ entry.name }} {% trans %}at{% endtrans %} {{ entry.time|date(config.post_date) }}

{{ entry.body }}

{% endfor %} -- cgit v1.3 From 98187303d77c41fa94430fa1302f071041c58bfc Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:38:03 -0400 Subject: categories theme: fix title displaying twice, put boardlist there instead --- templates/themes/categories/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html index 9c7d8340..93eb5b72 100644 --- a/templates/themes/categories/news.html +++ b/templates/themes/categories/news.html @@ -7,7 +7,7 @@ -

{{ settings.title }}

+ {{ boardlist.top }}

{{ settings.title }}

{{ settings.subtitle }}
-- cgit v1.3 From cea7881749e85b4ba5c8444e738d42a27d91244f Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:43:09 -0400 Subject: categories theme: i18n some strings --- templates/themes/categories/news.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html index 93eb5b72..b3bea2b1 100644 --- a/templates/themes/categories/news.html +++ b/templates/themes/categories/news.html @@ -15,16 +15,16 @@
{% if news|count == 0 %} -

(No news to show.)

+

{% trans %}(No news to show.){% endtrans %}

{% else %} {% for entry in news %}

{% if entry.subject %} {{ entry.subject }} {% else %} - no subject + {% trans %}no subject{% endtrans %} {% endif %} - — by {{ entry.name }} at {{ entry.time|date(config.post_date) }} + — {% trans %}by{% endtrans %} {{ entry.name }} {% trans %}at{% endtrans %} {{ entry.time|date(config.post_date) }}

{{ entry.body }}

{% endfor %} -- cgit v1.3 From c0e0a5db7d566aed16d5d9d9036a1f46f658e9eb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 13:14:21 -0400 Subject: Error in news template --- templates/mod/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/mod/news.html b/templates/mod/news.html index b6c35798..b0335e0a 100644 --- a/templates/mod/news.html +++ b/templates/mod/news.html @@ -52,7 +52,7 @@ {% trans 'no subject' %} {% endif %} - — {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ notice.time|date(config.post_date) }} + — {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ post.time|date(config.post_date) }}

-- cgit v1.3 From 58306bdc63b7dcaf964ab3541fe4b5a8e0c813b0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:18:06 -0400 Subject: Search posts --- inc/config.php | 2 + inc/mod/pages.php | 41 +++++++++++++++-- templates/mod/search_results.html | 97 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 132 insertions(+), 8 deletions(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 7dda86ab..582c3145 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1035,6 +1035,8 @@ $config['mod']['rebuild'] = ADMIN; // Search through posts, IP address notes and bans $config['mod']['search'] = JANITOR; + // Allow searching posts (can be used with board configuration file to disallow searching through a certain board) + $config['mod']['search_posts'] = JANITOR; // Read the moderator noticeboard $config['mod']['noticeboard'] = JANITOR; // Post to the moderator noticeboard diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 01794d2e..8289d0b0 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -225,7 +225,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // Which `field` to search? if ($type == 'posts') - $sql_field = 'body'; + $sql_field = 'body_nomarkup'; if ($type == 'IP_notes') $sql_field = 'body'; if ($type == 'bans') @@ -246,7 +246,27 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // Compile SQL query if ($type == 'posts') { - error('Searching posts is under development. Sorry.'); + $query = ''; + + $boards = listBoards(); + if (empty($boards)) + error(_('There are no boards to search!')); + + foreach ($boards as $board) { + openBoard($board['uri']); + if (!hasPermission($config['mod']['search_posts'], $board['uri'])) + continue; + + if (!empty($query)) + $query .= ' UNION ALL '; + $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE %s", $board['uri'], $board['uri'], $sql_like); + } + + // You weren't allowed to search any boards + if (empty($query)) + error($config['error']['noaccess']); + + $query .= ' ORDER BY `sticky` DESC, `id` DESC'; } if ($type == 'IP_notes') { @@ -273,10 +293,15 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // 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 == 'posts') { + $q = query("SELECT COUNT(*) FROM ($query) AS `tmp_table`") or error(db_error()); + $result_count = $q->fetchColumn(); + } else { + $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) { @@ -285,6 +310,12 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { } } + if ($type == 'posts') { + foreach ($results as &$post) { + $post['snippet'] = pm_snippet($post['body']); + } + } + // $results now contains the search results mod_page(_('Search results'), 'mod/search_results.html', array( diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index b441a28f..035773fb 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -39,7 +39,7 @@ {% endfor %} -{% endif %} +{% endif %} {% if search_type == 'bans' %} @@ -125,7 +125,7 @@ {% endfor %}
-{% endif %} +{% endif %} {% if search_type == 'log' %} @@ -166,7 +166,98 @@ {% endfor %}
-{% endif %} +{% endif %} + +{% if search_type == 'posts' %} + + + + + + + + + + + + + {% for post in results %} + + + + + + + + + + + + {% endfor %} +
TimeBoardIDThreadIPNameSubjectFileBody (snippet)
+ {{ post.time | ago }} ago + + {{ config.board_abbreviation|sprintf(post.board) }} + + {% if post.thread %} + {% set thread = post.thread %} + {% else %} + {% set thread = post.id %} + {% endif %} + + {{ post.id }} + + + + {% if post.thread %} + {{ post.thread }} + {% else %} + (OP) + {% endif %} + + + {% if mod|hasPermission(config.mod.show_ip, post.board) %} + + {{ post.ip }} + + {% else %} + hidden + {% endif %} + + + {% if post.email|length > 0 %} + {# start email #} + + {% endif %} + {% if capcode %} + {{ capcode.cap }} + {% endif %} + + + {% if post.subject %} + {{ post.subject }} + {% else %} + – + {% endif %} + + {% if post.file %} + {{ post.file }} ({{ post.filesize | filesize }}) + {% else %} + – + {% endif %} + + {{ post.snippet }} +
+{% endif %} {% if result_count > results|count %}

-- cgit v1.3 From c8e93f04d2522224dd84b7d93e526b918a105451 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:24:11 -0400 Subject: Update search results template --- templates/mod/search_results.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'templates') diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index 035773fb..aeaf57b0 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -189,7 +189,7 @@ {{ config.board_abbreviation|sprintf(post.board) }} - + {% if post.thread %} {% set thread = post.thread %} {% else %} @@ -217,7 +217,7 @@ hidden {% endif %} - + {% if post.email|length > 0 %} {# start email #} @@ -237,14 +237,14 @@ {% endif %} - + {% if post.subject %} {{ post.subject }} {% else %} – {% endif %} - + {% if post.file %} {{ post.file }} ({{ post.filesize | filesize }}) {% else %} -- cgit v1.3 From e0bc0a622de2e4b9a8e02f9b48979d14dba04c94 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:26:32 -0400 Subject: Post serach results: link to posts with ?/ --- templates/mod/debug/recent_posts.html | 2 +- templates/mod/search_results.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/debug/recent_posts.html b/templates/mod/debug/recent_posts.html index 740ed21e..13eb4d5a 100644 --- a/templates/mod/debug/recent_posts.html +++ b/templates/mod/debug/recent_posts.html @@ -24,7 +24,7 @@ {% else %} {% set thread = post.id %} {% endif %} - + {{ post.id }} diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index aeaf57b0..de753198 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -195,7 +195,7 @@ {% else %} {% set thread = post.id %} {% endif %} - + {{ post.id }} -- cgit v1.3 From d44b4f19a8760699a8895cbf9856a4cc0a0f5a65 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:31:36 -0400 Subject: See last commit --- templates/mod/debug/recent_posts.html | 2 +- templates/mod/search_results.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/debug/recent_posts.html b/templates/mod/debug/recent_posts.html index 13eb4d5a..b84d24ab 100644 --- a/templates/mod/debug/recent_posts.html +++ b/templates/mod/debug/recent_posts.html @@ -1,4 +1,4 @@ - +
diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index de753198..fbad0381 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -169,7 +169,7 @@ {% endif %} {% if search_type == 'posts' %} -
Time Board
+
-- cgit v1.3 From 1759ac2ea30d3c374beb6b5b6fa76bfa5501da9f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 20:20:07 -0400 Subject: Post search: Search other fields too --- inc/mod/pages.php | 16 ++++++++++++++-- templates/mod/search_results.html | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 8289d0b0..d447fa51 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -174,6 +174,11 @@ function mod_search_redirect() { $query = str_replace('_', '%5F', $query); $query = str_replace('+', '_', $query); + if ($query === '') { + header('Location: ?/', true, $config['redirect_http']); + return; + } + header('Location: ?/search/' . $_POST['type'] . '/' . $query, true, $config['redirect_http']); } else { header('Location: ?/', true, $config['redirect_http']); @@ -225,7 +230,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // Which `field` to search? if ($type == 'posts') - $sql_field = 'body_nomarkup'; + $sql_field = array('body_nomarkup', 'filename', 'subject', 'filehash', 'ip', 'name', 'trip'); if ($type == 'IP_notes') $sql_field = 'body'; if ($type == 'bans') @@ -239,7 +244,14 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { if (!empty($sql_like)) $sql_like .= ' AND '; $phrase = preg_replace('/^\'(.+)\'$/', '\'%$1%\'', $phrase); - $sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\''; + if (is_array($sql_field)) { + foreach ($sql_field as $field) { + $sql_like .= '`' . $field . '` LIKE ' . $phrase . ' ESCAPE \'!\' OR'; + } + $sql_like = preg_replace('/ OR$/', '', $sql_like); + } else { + $sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\''; + } } diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index fbad0381..0c87f75f 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -246,7 +246,7 @@ {% endif %} - {% if mod %} + {% if mod and ((not id and post.mod|hasPermission(config.mod.sticky, board.uri)) or (not id and post.mod|hasPermission(config.mod.lock, board.uri)) or post.mod|hasPermission(config.mod.rawhtml, board.uri)) %} -- cgit v1.3 From 7c8bbe8527be504804893672cc26430d11c272f2 Mon Sep 17 00:00:00 2001 From: Marcin Łabanowski Date: Sun, 23 Dec 2012 04:38:20 +0100 Subject: Implement image identification buttons using regex.info/exif, google images and tineye --- inc/config.php | 8 ++++++++ templates/post_reply.html | 11 +++++++++++ templates/post_thread.html | 10 ++++++++++ 3 files changed, 29 insertions(+) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 35b31b86..55c49045 100644 --- a/inc/config.php +++ b/inc/config.php @@ -485,6 +485,9 @@ $config['show_ratio'] = false; // Display the file's original filename $config['show_filename']= true; + + // Image identification buttons using regex.info/exif, tineye and google images + $config['image_identification'] = false; // Redraw the image using GD functions to strip any excess data (commonly ZIP archives) // WARNING: Currently strips animated GIFs too @@ -753,6 +756,11 @@ $config['root'] = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/'); else $config['root'] = '/'; // CLI mode + + // The scheme and domain. This is needed to get absolute URL of some page (for instance image + // identification buttons). If you use the CLI tools, it would be wise to override this setting. + $config['domain'] = (isset ($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? "https://" : "http://"; + $config['domain'] .= isset ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; // If for some reason the folders and static HTML index files aren't in the current working direcotry, // enter the directory path here. Otherwise, keep it false. diff --git a/templates/post_reply.html b/templates/post_reply.html index c5735a0e..5f7c2619 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -71,6 +71,17 @@ {{ post.filename|bidi_cleanup }} {% endif %} {% endif %} + {% if post.thumb != 'file' and config.image_identification %} + , + + {% if post.file|extension == 'jpg' %} + e + {% endif %} + g + t + + {% endif %} + )

diff --git a/templates/post_thread.html b/templates/post_thread.html index b702712e..0ada3e70 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -28,6 +28,16 @@ {{ post.filename|bidi_cleanup }} {% endif %} {% endif %} + {% if post.thumb != 'file' and config.image_identification %} + , + + {% if post.file|extension == 'jpg' %} + e + {% endif %} + g + t + + {% endif %} )

-- cgit v1.3 From daca11113e5c96e11c9c5518fa55bae0b27054a2 Mon Sep 17 00:00:00 2001 From: Marcin Łabanowski Date: Fri, 28 Dec 2012 19:08:25 +0100 Subject: image identification: add imgops.com button --- templates/post_reply.html | 1 + templates/post_thread.html | 1 + 2 files changed, 2 insertions(+) (limited to 'templates') diff --git a/templates/post_reply.html b/templates/post_reply.html index 5f7c2619..450f8246 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -74,6 +74,7 @@ {% if post.thumb != 'file' and config.image_identification %} , + io {% if post.file|extension == 'jpg' %} e {% endif %} diff --git a/templates/post_thread.html b/templates/post_thread.html index 0ada3e70..72c841be 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -31,6 +31,7 @@ {% if post.thumb != 'file' and config.image_identification %} , + io {% if post.file|extension == 'jpg' %} e {% endif %} -- cgit v1.3 From 701cf42eef17963fc57159e5383c020e76c0181f Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 2 Jul 2013 23:10:00 -0400 Subject: main.js: added preliminary translation functions for javascript --- templates/main.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'templates') diff --git a/templates/main.js b/templates/main.js index b3219b3c..78e7cbf1 100644 --- a/templates/main.js +++ b/templates/main.js @@ -1,5 +1,27 @@ {% raw %} +/* gettext-compatible _ function, example of usage: + * + * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php) + * > alert(_("Hello!")); + * Witaj! + */ +function _(s) { + return (typeof tb_l10n != 'undefined' && typeof tb_l10n[s] != 'undefined') ? tb_l10n[s] : s; +} + +/* printf-like formatting function, example of usage: + * + * > alert(fmt("There are {0} birds on {1} trees", [3,4])); + * There are 3 birds on 4 trees + * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php) + * > alert(fmt(_("{0} users"), [3])); + * 3 uzytkownikow + */ +function fmt(s,a) { + return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; }); +} + var saved = {}; -- cgit v1.3 From 61a305a1a27d414072b0de24441c07b1630c3075 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:04:08 -0400 Subject: js i18n: misc fixes; quick-reply.js i18n Conflicts: tools/i18n_compile.php --- js/quick-reply.js | 6 +++--- templates/main.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'templates') diff --git a/js/quick-reply.js b/js/quick-reply.js index bc36ca48..ea504b48 100644 --- a/js/quick-reply.js +++ b/js/quick-reply.js @@ -17,7 +17,7 @@ $(document).ready(function(){ return; // not index txt_new_topic = $('form[name=post] input[type=submit]').val(); - txt_new_reply = txt_new_topic == 'Submit' ? txt_new_topic : new_reply_string; + txt_new_reply = txt_new_topic == _('Submit') ? txt_new_topic : new_reply_string; undo_quick_reply = function() { $('div.banner').remove(); @@ -27,9 +27,9 @@ $(document).ready(function(){ $('div.post.op').each(function() { var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); - $('[Quick reply]').insertAfter($(this).children('p.intro').children('a:last')).click(function() { + $('['+_("Quick reply")+']').insertAfter($(this).children('p.intro').children('a:last')).click(function() { $('div.banner').remove(); - $('') + $('') .insertBefore('form[name=post]'); $('form[name=post] input[type=submit]').val(txt_new_reply); diff --git a/templates/main.js b/templates/main.js index 78e7cbf1..401d3504 100644 --- a/templates/main.js +++ b/templates/main.js @@ -2,12 +2,12 @@ /* gettext-compatible _ function, example of usage: * - * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php) + * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php) * > alert(_("Hello!")); * Witaj! */ function _(s) { - return (typeof tb_l10n != 'undefined' && typeof tb_l10n[s] != 'undefined') ? tb_l10n[s] : s; + return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s; } /* printf-like formatting function, example of usage: -- cgit v1.3 From 123a72d7de692c8f33f6df39d0a8a7a267fe8b0b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 04:28:26 -0400 Subject: Convert to UNIX line endings --- inc/template.php | 144 +++++++------- templates/main.js | 460 ++++++++++++++++++++++----------------------- templates/mod/login.html | 52 ++--- templates/post_reply.html | 222 +++++++++++----------- templates/post_thread.html | 296 ++++++++++++++--------------- templates/posts.sql | 2 +- templates/thread.html | 140 +++++++------- 7 files changed, 658 insertions(+), 658 deletions(-) (limited to 'templates') diff --git a/inc/template.php b/inc/template.php index 071fa761..09e27c26 100644 --- a/inc/template.php +++ b/inc/template.php @@ -1,72 +1,72 @@ -setPaths($config['dir']['template']); - $twig = new Twig_Environment($loader, array( - 'autoescape' => false, - 'cache' => "{$config['dir']['template']}/cache", - 'debug' => $config['debug'] - )); - $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); - $twig->addExtension(new Twig_Extensions_Extension_I18n()); -} - -function Element($templateFile, array $options) { - global $config, $debug, $twig; - - if (!$twig) - load_twig(); - - if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', $templateFile)) { - $options['pm'] = create_pm_header(); - } - - if (isset($options['body']) && $config['debug']) { - if (isset($debug['start'])) { - $debug['time'] = '~' . round((microtime(true) - $debug['start']) * 1000, 2) . 'ms'; - unset($debug['start']); - } - $debug['included'] = get_included_files(); - $debug['memory'] = round(memory_get_usage(true) / (1024 * 1024), 2) . ' MiB'; - $options['body'] .= - '

Debug

' .
-				str_replace("\n", '
', utf8tohtml(print_r($debug, true))) . - '
'; - } - - // Read the template file - if (@file_get_contents("{$config['dir']['template']}/${templateFile}")) { - $body = $twig->render($templateFile, $options); - - if ($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { - $body = trim(preg_replace("/[\t\r\n]/", '', $body)); - } - - return $body; - } else { - throw new Exception("Template file '${templateFile}' does not exist or is empty in '{$config['dir']['template']}'!"); - } -} - +setPaths($config['dir']['template']); + $twig = new Twig_Environment($loader, array( + 'autoescape' => false, + 'cache' => "{$config['dir']['template']}/cache", + 'debug' => $config['debug'] + )); + $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); + $twig->addExtension(new Twig_Extensions_Extension_I18n()); +} + +function Element($templateFile, array $options) { + global $config, $debug, $twig; + + if (!$twig) + load_twig(); + + if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', $templateFile)) { + $options['pm'] = create_pm_header(); + } + + if (isset($options['body']) && $config['debug']) { + if (isset($debug['start'])) { + $debug['time'] = '~' . round((microtime(true) - $debug['start']) * 1000, 2) . 'ms'; + unset($debug['start']); + } + $debug['included'] = get_included_files(); + $debug['memory'] = round(memory_get_usage(true) / (1024 * 1024), 2) . ' MiB'; + $options['body'] .= + '

Debug

' .
+				str_replace("\n", '
', utf8tohtml(print_r($debug, true))) . + '
'; + } + + // Read the template file + if (@file_get_contents("{$config['dir']['template']}/${templateFile}")) { + $body = $twig->render($templateFile, $options); + + if ($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { + $body = trim(preg_replace("/[\t\r\n]/", '', $body)); + } + + return $body; + } else { + throw new Exception("Template file '${templateFile}' does not exist or is empty in '{$config['dir']['template']}'!"); + } +} + diff --git a/templates/main.js b/templates/main.js index 401d3504..71dcd92a 100644 --- a/templates/main.js +++ b/templates/main.js @@ -1,38 +1,38 @@ -{% raw %} - -/* gettext-compatible _ function, example of usage: - * - * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php) - * > alert(_("Hello!")); - * Witaj! - */ -function _(s) { - return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s; -} - -/* printf-like formatting function, example of usage: - * - * > alert(fmt("There are {0} birds on {1} trees", [3,4])); - * There are 3 birds on 4 trees - * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php) - * > alert(fmt(_("{0} users"), [3])); - * 3 uzytkownikow - */ -function fmt(s,a) { - return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; }); -} - -var saved = {}; - - -var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}'; -var styles = { - {% endraw %} - {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}', - {% endraw %}{% endfor %}{% raw %} -}; +{% raw %} + +/* gettext-compatible _ function, example of usage: + * + * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php) + * > alert(_("Hello!")); + * Witaj! + */ +function _(s) { + return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s; +} + +/* printf-like formatting function, example of usage: + * + * > alert(fmt("There are {0} birds on {1} trees", [3,4])); + * There are 3 birds on 4 trees + * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php) + * > alert(fmt(_("{0} users"), [3])); + * 3 uzytkownikow + */ +function fmt(s,a) { + return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; }); +} + +var saved = {}; + + +var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}'; +var styles = { + {% endraw %} + {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}', + {% endraw %}{% endfor %}{% raw %} +}; var board_name = false; - + function changeStyle(styleName, link) { {% endraw %} {% if config.stylesheets_board %}{% raw %} @@ -43,31 +43,31 @@ function changeStyle(styleName, link) { {% endraw %}{% else %} localStorage.stylesheet = styleName; {% endif %} - {% raw %} - - if (!document.getElementById('stylesheet')) { - var s = document.createElement('link'); - s.rel = 'stylesheet'; - s.type = 'text/css'; - s.id = 'stylesheet'; - var x = document.getElementsByTagName('head')[0]; - x.appendChild(s); - } - - document.getElementById('stylesheet').href = styles[styleName]; - selectedstyle = styleName; - - if (document.getElementsByClassName('styles').length != 0) { - var styleLinks = document.getElementsByClassName('styles')[0].childNodes; - for (var i = 0; i < styleLinks.length; i++) { - styleLinks[i].className = ''; - } - } - - if (link) { - link.className = 'selected'; - } -} + {% raw %} + + if (!document.getElementById('stylesheet')) { + var s = document.createElement('link'); + s.rel = 'stylesheet'; + s.type = 'text/css'; + s.id = 'stylesheet'; + var x = document.getElementsByTagName('head')[0]; + x.appendChild(s); + } + + document.getElementById('stylesheet').href = styles[styleName]; + selectedstyle = styleName; + + if (document.getElementsByClassName('styles').length != 0) { + var styleLinks = document.getElementsByClassName('styles')[0].childNodes; + for (var i = 0; i < styleLinks.length; i++) { + styleLinks[i].className = ''; + } + } + + if (link) { + link.className = 'selected'; + } +} {% endraw %} @@ -95,177 +95,177 @@ function changeStyle(styleName, link) { {% endraw%} {% else %} {% raw %} - if (localStorage.stylesheet) { - for (var styleName in styles) { - if (styleName == localStorage.stylesheet) { - changeStyle(styleName); - break; - } - } + if (localStorage.stylesheet) { + for (var styleName in styles) { + if (styleName == localStorage.stylesheet) { + changeStyle(styleName); + break; + } + } } - {% endraw %} + {% endraw %} {% endif %} {% raw %} - -function init_stylechooser() { - var newElement = document.createElement('div'); - newElement.className = 'styles'; - - for (styleName in styles) { - var style = document.createElement('a'); - style.innerHTML = '[' + styleName + ']'; - style.onclick = function() { - changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this); - }; - if (styleName == selectedstyle) { - style.className = 'selected'; - } - style.href = 'javascript:void(0);'; - newElement.appendChild(style); - } - - document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling); -} - -function get_cookie(cookie_name) { - var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)'); - if (results) - return (unescape(results[2])); - else - return null; -} - -function highlightReply(id) { - if (typeof window.event != "undefined" && event.which == 2) { - // don't highlight on middle click - return true; - } - - var divs = document.getElementsByTagName('div'); - for (var i = 0; i < divs.length; i++) - { - if (divs[i].className.indexOf('post') != -1) - divs[i].className = divs[i].className.replace(/highlighted/, ''); - } - if (id) { - var post = document.getElementById('reply_'+id); - if (post) - post.className += ' highlighted'; - } -} - -function generatePassword() { - var pass = ''; - var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}'; - for (var i = 0; i < 8; i++) { - var rnd = Math.floor(Math.random() * chars.length); - pass += chars.substring(rnd, rnd + 1); - } - return pass; -} - -function dopost(form) { - if (form.elements['name']) { - localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, ''); - } - if (form.elements['email'] && form.elements['email'].value != 'sage') { - localStorage.email = form.elements['email'].value; - } - - saved[document.location] = form.elements['body'].value; - sessionStorage.body = JSON.stringify(saved); - - return form.elements['body'].value != "" || form.elements['file'].value != ""; -} - -function citeReply(id) { - var body = document.getElementById('body'); - - if (document.selection) { - // IE - body.focus(); - var sel = document.selection.createRange(); - sel.text = '>>' + id + '\n'; - } else if (body.selectionStart || body.selectionStart == '0') { - // Mozilla - var start = body.selectionStart; - var end = body.selectionEnd; - body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length); - } else { - // ??? - body.value += '>>' + id + '\n'; - } -} - -function rememberStuff() { - if (document.forms.post) { - if (document.forms.post.password) { - if (!localStorage.password) - localStorage.password = generatePassword(); - document.forms.post.password.value = localStorage.password; - } - - if (localStorage.name && document.forms.post.elements['name']) - document.forms.post.elements['name'].value = localStorage.name; - if (localStorage.email && document.forms.post.elements['email']) - document.forms.post.elements['email'].value = localStorage.email; - - if (window.location.hash.indexOf('q') == 1) - citeReply(window.location.hash.substring(2)); - - if (sessionStorage.body) { - var saved = JSON.parse(sessionStorage.body); - if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) { - // Remove successful posts - var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')); - for (var url in successful) { - saved[url] = null; - } - sessionStorage.body = JSON.stringify(saved); - - document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;'; - } - if (saved[document.location]) { - document.forms.post.body.value = saved[document.location]; - } - } - - if (localStorage.body) { - document.forms.post.body.value = localStorage.body; - localStorage.body = ''; - } - } -} - -function init() { - init_stylechooser(); - - if (document.forms.postcontrols) { - document.forms.postcontrols.password.value = localStorage.password; - } - - if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1)) - highlightReply(window.location.hash.substring(1)); -} - -var RecaptchaOptions = { - theme : 'clean' -}; - -onready_callbacks = []; -function onready(fnc) { - onready_callbacks.push(fnc); -} - -function ready() { - for (var i = 0; i < onready_callbacks.length; i++) { - onready_callbacks[i](); - } -} - -onready(init); - -{% endraw %}{% if config.google_analytics %}{% raw %} - -var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %} - + +function init_stylechooser() { + var newElement = document.createElement('div'); + newElement.className = 'styles'; + + for (styleName in styles) { + var style = document.createElement('a'); + style.innerHTML = '[' + styleName + ']'; + style.onclick = function() { + changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this); + }; + if (styleName == selectedstyle) { + style.className = 'selected'; + } + style.href = 'javascript:void(0);'; + newElement.appendChild(style); + } + + document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling); +} + +function get_cookie(cookie_name) { + var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)'); + if (results) + return (unescape(results[2])); + else + return null; +} + +function highlightReply(id) { + if (typeof window.event != "undefined" && event.which == 2) { + // don't highlight on middle click + return true; + } + + var divs = document.getElementsByTagName('div'); + for (var i = 0; i < divs.length; i++) + { + if (divs[i].className.indexOf('post') != -1) + divs[i].className = divs[i].className.replace(/highlighted/, ''); + } + if (id) { + var post = document.getElementById('reply_'+id); + if (post) + post.className += ' highlighted'; + } +} + +function generatePassword() { + var pass = ''; + var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}'; + for (var i = 0; i < 8; i++) { + var rnd = Math.floor(Math.random() * chars.length); + pass += chars.substring(rnd, rnd + 1); + } + return pass; +} + +function dopost(form) { + if (form.elements['name']) { + localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, ''); + } + if (form.elements['email'] && form.elements['email'].value != 'sage') { + localStorage.email = form.elements['email'].value; + } + + saved[document.location] = form.elements['body'].value; + sessionStorage.body = JSON.stringify(saved); + + return form.elements['body'].value != "" || form.elements['file'].value != ""; +} + +function citeReply(id) { + var body = document.getElementById('body'); + + if (document.selection) { + // IE + body.focus(); + var sel = document.selection.createRange(); + sel.text = '>>' + id + '\n'; + } else if (body.selectionStart || body.selectionStart == '0') { + // Mozilla + var start = body.selectionStart; + var end = body.selectionEnd; + body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length); + } else { + // ??? + body.value += '>>' + id + '\n'; + } +} + +function rememberStuff() { + if (document.forms.post) { + if (document.forms.post.password) { + if (!localStorage.password) + localStorage.password = generatePassword(); + document.forms.post.password.value = localStorage.password; + } + + if (localStorage.name && document.forms.post.elements['name']) + document.forms.post.elements['name'].value = localStorage.name; + if (localStorage.email && document.forms.post.elements['email']) + document.forms.post.elements['email'].value = localStorage.email; + + if (window.location.hash.indexOf('q') == 1) + citeReply(window.location.hash.substring(2)); + + if (sessionStorage.body) { + var saved = JSON.parse(sessionStorage.body); + if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) { + // Remove successful posts + var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')); + for (var url in successful) { + saved[url] = null; + } + sessionStorage.body = JSON.stringify(saved); + + document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;'; + } + if (saved[document.location]) { + document.forms.post.body.value = saved[document.location]; + } + } + + if (localStorage.body) { + document.forms.post.body.value = localStorage.body; + localStorage.body = ''; + } + } +} + +function init() { + init_stylechooser(); + + if (document.forms.postcontrols) { + document.forms.postcontrols.password.value = localStorage.password; + } + + if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1)) + highlightReply(window.location.hash.substring(1)); +} + +var RecaptchaOptions = { + theme : 'clean' +}; + +onready_callbacks = []; +function onready(fnc) { + onready_callbacks.push(fnc); +} + +function ready() { + for (var i = 0; i < onready_callbacks.length; i++) { + onready_callbacks[i](); + } +} + +onready(init); + +{% endraw %}{% if config.google_analytics %}{% raw %} + +var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %} + diff --git a/templates/mod/login.html b/templates/mod/login.html index 43a28d56..476897a6 100644 --- a/templates/mod/login.html +++ b/templates/mod/login.html @@ -1,26 +1,26 @@ -{% if error %}

{{ error }}

{% endif %} -
-
Time Board {% if post.file %} - {{ post.file }} ({{ post.filesize | filesize }}) + {{ post.filename }} ({{ post.filesize | filesize }}) {% else %} – {% endif %} -- cgit v1.3 From 8efab06616bfcdab49fb9e996cdc7ddfe79426bb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 22:08:56 -0400 Subject: Upgrade to utf8mb4 charset for MySQL server versions above 5.5.3. Keep support for older versions. Fix charsets for multiple columns and tables. --- inc/database.php | 21 +++++++++-- inc/functions.php | 5 ++- install.php | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++- install.sql | 95 +++++++++++++++++++++++-------------------------- post.php | 5 ++- templates/posts.sql | 63 +++++++++++++++++---------------- 6 files changed, 202 insertions(+), 87 deletions(-) (limited to 'templates') diff --git a/inc/database.php b/inc/database.php index a0edd1fb..3dc0f0ce 100644 --- a/inc/database.php +++ b/inc/database.php @@ -51,12 +51,16 @@ function sql_open() { try { $options = array( PDO::ATTR_TIMEOUT => $config['db']['timeout'], - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true ); if ($config['db']['persistent']) $options[PDO::ATTR_PERSISTENT] = true; - return $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options); + $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options); + if (mysql_version() >= 50503) + query('SET NAMES utf8mb4') or error(db_error()); + else + query('SET NAMES utf8') or error(db_error()); + return $pdo; } catch(PDOException $e) { $message = $e->getMessage(); @@ -65,10 +69,21 @@ function sql_open() { $message = str_replace($config['db']['password'], 'hidden', $message); // Print error - error('Database error: ' . $message); + error(_('Database error: ') . $message); } } +// 5.6.10 becomes 50610 +function mysql_version() { + global $pdo; + + $version = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION); + $v = explode('.', $version); + if (count($v) != 3) + return false; + return (int) sprintf("%02d%02d%02d", $v[0], $v[1], $v[2]); +} + function prepare($query) { global $pdo, $debug, $config; diff --git a/inc/functions.php b/inc/functions.php index 4af7891a..d5692be5 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1399,6 +1399,9 @@ function markup(&$body, $track_cites = false) { $body = str_replace("\r", '', $body); $body = utf8tohtml($body); + if (mysql_version() < 50503) + $body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); + foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); @@ -1523,7 +1526,7 @@ function markup(&$body, $track_cites = false) { } function utf8tohtml($utf8) { - return mb_encode_numericentity(htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'), array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); + return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); } function ordutf8($string, &$offset) { diff --git a/install.php b/install.php index 08e8046a..c2fe1a55 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ execute() or error(db_error($_query)); } } + case 'v0.9.6-dev-9': + function __query($sql) { + if (mysql_version() >= 50503) + return query($sql); + else + return query(str_replace('utf8mb4', 'utf8', $sql)); + } + + foreach ($boards as &$board) { + __query(sprintf("ALTER TABLE `posts_%s` + CHANGE `subject` `subject` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `email` `email` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `name` `name` VARCHAR(35) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `trip` `trip` VARCHAR(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `capcode` `capcode` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + CHANGE `body_nomarkup` `body_nomarkup` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `thumb` `thumb` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `thumbwidth` `thumbwidth` INT(11) NULL DEFAULT NULL, + CHANGE `thumbheight` `thumbheight` INT(11) NULL DEFAULT NULL, + CHANGE `file` `file` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `filename` `filename` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `filehash` `filehash` TEXT CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL, + CHANGE `password` `password` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + CHANGE `ip` `ip` VARCHAR(39) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL, + CHANGE `embed` `embed` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;", $board['uri'])) or error(db_error()); + } + + __query("ALTER TABLE `antispam` + CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `hash` `hash` CHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL , + DEFAULT CHARACTER SET ASCII COLLATE ascii_bin;") or error(db_error()); + __query("ALTER TABLE `bans` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `reason` `reason` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , + CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL, + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `boards` + CHANGE `uri` `uri` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `title` `title` TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `cites` + CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `target_board` `target_board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + DEFAULT CHARACTER SET ASCII COLLATE ascii_general_ci;") or error(db_error()); + __query("ALTER TABLE `ip_notes` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `ip_notes` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `modlogs` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL , + CHANGE `text` `text` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `mods` + CHANGE `username` `username` VARCHAR( 30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `password` `password` CHAR( 64 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL COMMENT 'SHA256', + CHANGE `salt` `salt` CHAR( 32 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `boards` `boards` TEXT CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `mutes` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + DEFAULT CHARACTER SET ASCII COLLATE ascii_general_ci;") or error(db_error()); + __query("ALTER TABLE `news` + CHANGE `name` `name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `subject` `subject` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `noticeboard` + CHANGE `subject` `subject` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `pms` + CHANGE `message` `message` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `reports` + CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , + CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL , + CHANGE `reason` `reason` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error()); + __query("ALTER TABLE `robot` + CHANGE `hash` `hash` VARCHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL COMMENT 'SHA1', + DEFAULT CHARACTER SET ASCII COLLATE ascii_bin;") or error(db_error()); + __query("ALTER TABLE `theme_settings` + CHANGE `theme` `theme` VARCHAR( 40 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , + CHANGE `name` `name` VARCHAR( 40 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , + CHANGE `value` `value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL , + DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or eror(db_error()); case false: // Update version number file_write($config['has_installed'], VERSION); @@ -547,6 +641,10 @@ if ($step == 0) { $sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); + sql_open(); + if (mysql_version() < 50503) + $sql = str_replace('utf8', 'utf8mb4', $sql); + // This code is probably horrible, but what I'm trying // to do is find all of the SQL queires and put them // in an array. diff --git a/install.sql b/install.sql index ee2ca8a9..c4e82820 100644 --- a/install.sql +++ b/install.sql @@ -1,25 +1,20 @@ -- phpMyAdmin SQL Dump --- version 3.4.2 +-- version 4.0.4.1 -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: Apr 12, 2012 at 11:22 PM --- Server version: 5.1.61 --- PHP Version: 5.3.3-7+squeeze8 +-- Generation Time: Jul 30, 2013 at 09:45 PM +-- Server version: 5.6.10 +-- PHP Version: 5.3.15 -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; - /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; --- --- Database: `tinyboard` --- - -- -------------------------------------------------------- -- @@ -27,15 +22,15 @@ SET time_zone = "+00:00"; -- CREATE TABLE IF NOT EXISTS `antispam` ( - `board` varchar(255) NOT NULL, + `board` varchar(120) CHARACTER SET ascii NOT NULL, `thread` int(11) DEFAULT NULL, - `hash` char(40) NOT NULL, + `hash` char(40) COLLATE ascii_bin NOT NULL, `created` int(11) NOT NULL, `expires` int(11) DEFAULT NULL, `passed` smallint(6) NOT NULL, PRIMARY KEY (`hash`), KEY `board` (`board`,`thread`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin; -- -------------------------------------------------------- @@ -44,17 +39,17 @@ CREATE TABLE IF NOT EXISTS `antispam` ( -- CREATE TABLE IF NOT EXISTS `bans` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `ip` varchar(45) NOT NULL, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ip` varchar(39) CHARACTER SET ascii NOT NULL, `mod` int(11) NOT NULL COMMENT 'which mod made the ban', `set` int(11) NOT NULL, `expires` int(11) DEFAULT NULL, `reason` text, - `board` varchar(120) DEFAULT NULL, + `board` varchar(120) CHARACTER SET ascii DEFAULT NULL, `seen` tinyint(1) NOT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `ip` (`ip`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- @@ -63,18 +58,18 @@ CREATE TABLE IF NOT EXISTS `bans` ( -- CREATE TABLE IF NOT EXISTS `boards` ( - `uri` varchar(120) NOT NULL, + `uri` varchar(120) CHARACTER SET ascii NOT NULL, `title` tinytext NOT NULL, `subtitle` tinytext, PRIMARY KEY (`uri`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; -- -- Dumping data for table `boards` -- -INSERT INTO `boards` (`uri`, `title`, `subtitle`) VALUES -('b', 'Beta', 'In development.'); +INSERT INTO `boards` VALUES +('b', 'Random', NULL); -- -------------------------------------------------------- @@ -83,13 +78,13 @@ INSERT INTO `boards` (`uri`, `title`, `subtitle`) VALUES -- CREATE TABLE IF NOT EXISTS `cites` ( - `board` varchar(8) NOT NULL, + `board` varchar(120) NOT NULL, `post` int(11) NOT NULL, - `target_board` varchar(8) NOT NULL, + `target_board` varchar(120) NOT NULL, `target` int(11) NOT NULL, KEY `target` (`target_board`,`target`), KEY `post` (`board`,`post`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=ascii; -- -------------------------------------------------------- @@ -98,14 +93,14 @@ CREATE TABLE IF NOT EXISTS `cites` ( -- CREATE TABLE IF NOT EXISTS `ip_notes` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `ip` varchar(45) NOT NULL, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ip` varchar(39) CHARACTER SET ascii NOT NULL, `mod` int(11) DEFAULT NULL, `time` int(11) NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`), KEY `ip` (`ip`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- @@ -115,12 +110,12 @@ CREATE TABLE IF NOT EXISTS `ip_notes` ( CREATE TABLE IF NOT EXISTS `modlogs` ( `mod` int(11) NOT NULL, - `ip` varchar(45) NOT NULL, - `board` varchar(120) DEFAULT NULL, + `ip` varchar(39) CHARACTER SET ascii NOT NULL, + `board` varchar(120) CHARACTER SET ascii DEFAULT NULL, `time` int(11) NOT NULL, `text` text NOT NULL, KEY `time` (`time`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; -- -------------------------------------------------------- @@ -131,19 +126,19 @@ CREATE TABLE IF NOT EXISTS `modlogs` ( CREATE TABLE IF NOT EXISTS `mods` ( `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(30) NOT NULL, - `password` char(64) NOT NULL COMMENT 'SHA256', - `salt` char(32) NOT NULL, + `password` char(64) CHARACTER SET ascii NOT NULL COMMENT 'SHA256', + `salt` char(32) CHARACTER SET ascii NOT NULL, `type` smallint(1) NOT NULL COMMENT '0: janitor, 1: mod, 2: admin', - `boards` text NOT NULL, + `boards` text CHARACTER SET ascii NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`,`username`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=4 ; -- -- Dumping data for table `mods` -- -INSERT INTO `mods` (`id`, `username`, `password`, `salt`, `type`, `boards`) VALUES +INSERT INTO `mods` VALUES (1, 'admin', 'cedad442efeef7112fed0f50b011b2b9bf83f6898082f995f69dd7865ca19fb7', '4a44c6c55df862ae901b413feecb0d49', 2, '*'); -- -------------------------------------------------------- @@ -153,10 +148,10 @@ INSERT INTO `mods` (`id`, `username`, `password`, `salt`, `type`, `boards`) VALU -- CREATE TABLE IF NOT EXISTS `mutes` ( - `ip` varchar(45) NOT NULL, + `ip` varchar(39) NOT NULL, `time` int(11) NOT NULL, KEY `ip` (`ip`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=ascii; -- -------------------------------------------------------- @@ -165,14 +160,14 @@ CREATE TABLE IF NOT EXISTS `mutes` ( -- CREATE TABLE IF NOT EXISTS `news` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`), KEY `time` (`time`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- @@ -181,13 +176,13 @@ CREATE TABLE IF NOT EXISTS `news` ( -- CREATE TABLE IF NOT EXISTS `noticeboard` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `mod` int(11) NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- @@ -196,14 +191,14 @@ CREATE TABLE IF NOT EXISTS `noticeboard` ( -- CREATE TABLE IF NOT EXISTS `pms` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `sender` int(11) NOT NULL, `to` int(11) NOT NULL, `message` text NOT NULL, `time` int(11) NOT NULL, `unread` tinyint(1) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- @@ -212,14 +207,14 @@ CREATE TABLE IF NOT EXISTS `pms` ( -- CREATE TABLE IF NOT EXISTS `reports` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `time` int(11) NOT NULL, - `ip` varchar(45) NOT NULL, - `board` varchar(120) DEFAULT NULL, + `ip` varchar(39) CHARACTER SET ascii NOT NULL, + `board` varchar(120) CHARACTER SET ascii DEFAULT NULL, `post` int(11) NOT NULL, `reason` text NOT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=3 ; -- -------------------------------------------------------- @@ -228,9 +223,9 @@ CREATE TABLE IF NOT EXISTS `reports` ( -- CREATE TABLE IF NOT EXISTS `robot` ( - `hash` varchar(40) NOT NULL COMMENT 'SHA1', + `hash` varchar(40) COLLATE ascii_bin NOT NULL COMMENT 'SHA1', PRIMARY KEY (`hash`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin; -- -------------------------------------------------------- @@ -243,7 +238,7 @@ CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) DEFAULT NULL, `value` text, KEY `theme` (`theme`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; diff --git a/post.php b/post.php index e9041ce8..d1749fd1 100644 --- a/post.php +++ b/post.php @@ -378,7 +378,10 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); - $post['body_nomarkup'] = preg_replace('/[\x{010000}-\x{ffffff}]/u', '', $post['body']); + if (mysql_version() >= 50503) + $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset + else + $post['body_nomarkup'] = preg_replace('/[\x{010000}-\x{ffffff}]/u', '', $post['body']); // MySQL's `utf8` charset only supports up to 3-byte symbols if (!($mod && isset($post['raw']) && $post['raw'])) $post['tracked_cites'] = markup($post['body'], true); diff --git a/templates/posts.sql b/templates/posts.sql index c766d38e..0a1dc92a 100644 --- a/templates/posts.sql +++ b/templates/posts.sql @@ -1,32 +1,33 @@ CREATE TABLE IF NOT EXISTS `posts_{{ board }}` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `thread` int(11) DEFAULT NULL, - `subject` varchar(100) DEFAULT NULL, - `email` varchar(30) DEFAULT NULL, - `name` varchar(35) DEFAULT NULL, - `trip` varchar(15) DEFAULT NULL, - `capcode` varchar(50) DEFAULT NULL, - `body` text NOT NULL, - `body_nomarkup` text DEFAULT NULL, - `time` int(11) NOT NULL, - `bump` int(11) DEFAULT NULL, - `thumb` varchar(50) DEFAULT NULL, - `thumbwidth` int(11) DEFAULT NULL, - `thumbheight` int(11) DEFAULT NULL, - `file` varchar(50) DEFAULT NULL, - `filewidth` int(11) DEFAULT NULL, - `fileheight` int(11) DEFAULT NULL, - `filesize` int(11) DEFAULT NULL, - `filename` text DEFAULT NULL, - `filehash` text DEFAULT NULL, - `password` varchar(20) DEFAULT NULL, - `ip` varchar(45) NOT NULL, - `sticky` int(1) NOT NULL, - `locked` int(1) NOT NULL, - `sage` int(1) NOT NULL, - `embed` text, - UNIQUE KEY `id` (`id`), - KEY `thread_id` (`thread`, `id`), - KEY `time` (`time`), - FULLTEXT KEY `body` (`body`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `thread` int(11) DEFAULT NULL, + `subject` varchar(100) DEFAULT NULL, + `email` varchar(30) DEFAULT NULL, + `name` varchar(35) DEFAULT NULL, + `trip` varchar(15) DEFAULT NULL, + `capcode` varchar(50) DEFAULT NULL, + `body` text NOT NULL, + `body_nomarkup` text, + `time` int(11) NOT NULL, + `bump` int(11) DEFAULT NULL, + `thumb` varchar(50) DEFAULT NULL, + `thumbwidth` int(11) DEFAULT NULL, + `thumbheight` int(11) DEFAULT NULL, + `file` varchar(50) DEFAULT NULL, + `filewidth` int(11) DEFAULT NULL, + `fileheight` int(11) DEFAULT NULL, + `filesize` int(11) DEFAULT NULL, + `filename` text, + `filehash` text CHARACTER SET ascii, + `password` varchar(20) DEFAULT NULL, + `ip` varchar(39) CHARACTER SET ascii NOT NULL, + `sticky` int(1) NOT NULL, + `locked` int(1) NOT NULL, + `sage` int(1) NOT NULL, + `embed` text, + UNIQUE KEY `id` (`id`), + KEY `thread_id` (`thread`,`id`), + KEY `time` (`time`), + FULLTEXT KEY `body` (`body`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; + \ No newline at end of file -- cgit v1.3 From 889945f50cd0c2cd1b8f39d7b380133196a93a74 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 23:36:46 -0400 Subject: Hide "flags" section in posting form if user doesn't have permission to do anything special --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index aa051f5f..a112e2ab 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -85,7 +85,7 @@
{% trans %}Flags{% endtrans %} -- cgit v1.3 From bb2868896c2f383a913e8e5929627660cc754b14 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 00:04:57 -0400 Subject: Ability to hide IP addresses from mod log --- inc/config.php | 2 ++ templates/mod/log.html | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 582c3145..28a7a4db 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1024,6 +1024,8 @@ $config['mod']['createusers'] = ADMIN; // View the moderation log $config['mod']['modlog'] = ADMIN; + // View IP addresses of other mods in ?/log + $config['mod']['show_ip_modlog'] = ADMIN; // View relevant moderation log entries on IP address pages (ie. ban history, etc.) // Warning: Can be pretty resource exhaustive if your mod logs are huge. $config['mod']['modlog_ip'] = MOD; diff --git a/templates/mod/log.html b/templates/mod/log.html index e75330b5..0aa3f110 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -18,7 +18,11 @@ {% endif %} - {{ log.ip }} + {% if mod|hasPermission(config.mod.show_ip_modlog) %} + {{ log.ip }} + {% else %} + hidden + {% endif %} {{ log.time|ago }} -- cgit v1.3 From 90b82b1a0635d78d536bc92decbdc273d8f7e323 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 02:38:40 -0400 Subject: Disable autocomplete --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index a112e2ab..03b9961f 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -1,4 +1,4 @@ -
+ {{ antibot.html() }} {% if id %}{% endif %} {{ antibot.html() }} -- cgit v1.3 From a9f3f44c5ffc355df7831eed29b08e0dd2b398fc Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sun, 6 Jan 2013 09:41:00 +0100 Subject: refactored head away from templates Conflicts: templates/generic_page.html templates/index.html templates/page.html --- templates/generic_page.html | 30 +---------- templates/header.html | 28 +++++++++++ templates/index.html | 120 +++++++++++++++++--------------------------- templates/page.html | 59 +++++++++------------- 4 files changed, 100 insertions(+), 137 deletions(-) create mode 100644 templates/header.html (limited to 'templates') diff --git a/templates/generic_page.html b/templates/generic_page.html index dc9e185a..0c8f9867 100644 --- a/templates/generic_page.html +++ b/templates/generic_page.html @@ -2,34 +2,8 @@ {% block head %} - - {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.name }} - - - {% if config.meta_keywords %}{% endif %} - {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if not nojavascript %} - - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - {% if config.recaptcha %}{% endif %} + {% include 'header.html' %} + {{ board.url }} - {{ board.name }} {% endblock %} diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 00000000..95e0bc09 --- /dev/null +++ b/templates/header.html @@ -0,0 +1,28 @@ + + {% if config.url_favicon %}{% endif %} + + + {% if config.meta_keywords %}{% endif %} + {% if config.default_stylesheet.1 != '' %}{% endif %} + + {% if not nojavascript %} + + {% if not config.additional_javascript_compile %} + {% for javascript in config.additional_javascript %}{% endfor %} + {% endif %} + {% endif %} + {% if config.recaptcha %}{% endif %} diff --git a/templates/index.html b/templates/index.html index 430e2eab..da6101ee 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,75 +1,45 @@ - - - - - - {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.title|e }} - - {% if config.meta_keywords %}{% endif %} - {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} - {% if not nojavascript %} - - {% if config.quick_reply %} - - {% endif %} - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - {% if config.recaptcha %}{% endif %} - - - {{ boardlist.top }} - {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} - {% if config.url_banner %}{% endif %} -
-

{{ board.url }} - {{ board.title|e }}

-
- {% if board.subtitle %} - {{ board.subtitle|e }} - {% endif %} - {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} -
-
- - {% include 'post_form.html' %} - - {% if config.blotter %}
{{ config.blotter }}
{% endif %} -
- - - {% if mod %}{% endif %} - {{ body }} - {% include 'report_delete.html' %} - -
{{ btn.prev }} {% for page in pages %} - [{{ page.num }}]{% if loop.last %} {% endif %} - {% endfor %} {{ btn.next }}
- {{ boardlist.bottom }} -
-

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

- {% for footer in config.footer %}

{{ footer }}

{% endfor %} -
- - - + + + + {% include 'header.html' %} + + {% include 'header.html' %} + {{ board.url }} - {{ board.title|e }} + + + {{ boardlist.top }} + {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} + {% if config.url_banner %}{% endif %} +
+

{{ board.url }} - {{ board.title|e }}

+
+ {% if board.subtitle %} + {{ board.subtitle|e }} + {% endif %} + {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} +
+
+ + {% include 'post_form.html' %} + + {% if config.blotter %}
{{ config.blotter }}
{% endif %} +
+
+ + {% if mod %}{% endif %} + {{ body }} + {% include 'report_delete.html' %} +
+
{{ btn.prev }} {% for page in pages %} + [{{ page.num }}]{% if loop.last %} {% endif %} + {% endfor %} {{ btn.next }}
+ {{ boardlist.bottom }} +
+

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

+ {% for footer in config.footer %}

{{ footer }}

{% endfor %} +
+ + + diff --git a/templates/page.html b/templates/page.html index 2f3de358..a7c6a300 100644 --- a/templates/page.html +++ b/templates/page.html @@ -1,34 +1,25 @@ - - - - - - {% if config.url_favicon %}{% endif %} - {{ title }} - - {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if not nojavascript %} - - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - - - {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} -
-

{{ title }}

-
- {% if subtitle %} - {{ subtitle }} - {% endif %} - {% if mod and not hide_dashboard_link %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} -
-
- {{ body }} -
-
-

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

-
- - + + + + + {% include 'header.html' %} + {{ title }} + + + {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} +
+

{{ title }}

+
+ {% if subtitle %} + {{ subtitle }} + {% endif %} + {% if mod and not hide_dashboard_link %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} +
+
+ {{ body }} +
+
+

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

+
+ + -- cgit v1.3 From 1ffabe2b930a72995be9c4b1699ebd0dab22827d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:55:55 -0400 Subject: fix header.html merge --- templates/header.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/header.html b/templates/header.html index 95e0bc09..3791296f 100644 --- a/templates/header.html +++ b/templates/header.html @@ -4,6 +4,7 @@ {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} + {% if config.font_awesome %}{% endif %} {% if not nojavascript %} @@ -25,4 +26,4 @@ .recaptchatable a { display: block; } - {% endraw %}{% endif %} + {% endraw %}{% endif %} \ No newline at end of file -- cgit v1.3 From b7d884ef45c271a0081a61b396cddb9aaf9a55ef Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 16 Jul 2013 13:18:55 -0400 Subject: recaptcha: fix for https --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index 03b9961f..599ae754 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -59,7 +59,7 @@ {{ antibot.html() }}
- + {{ antibot.html() }}
- - - - - - - - - - - -
- {% trans 'Username' %} - - -
- {% trans 'Password' %} - - -
- -
- +{% if error %}

{{ error }}

{% endif %} +
+ + + + + + + + + + + + +
+ {% trans 'Username' %} + + +
+ {% trans 'Password' %} + + +
+ +
+
diff --git a/templates/post_reply.html b/templates/post_reply.html index 450f8246..bc96e74c 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -1,111 +1,111 @@ -{% filter remove_whitespace %} -{# tabs and new lines will be ignored #} -
- -

- - - {% if config.poster_ids %} - ID: {{ post.ip|poster_id(post.thread) }} - {% endif %} - No. - - {{ post.id }} - -

- {% if post.embed %} - {{ post.embed }} - {% elseif post.file == 'deleted' %} - - {% elseif post.file and post.file %} -

File: {{ post.file }} - ( - {% if post.thumb == 'spoiler' %} - Spoiler Image, - {% endif %} - {{ post.filesize|filesize }} - {% if post.filex and post.filey %} - , {{ post.filex}}x{{ post.filey }} - {% if config.show_ratio %} - , {{ post.ratio }} - {% endif %} - {% endif %} - {% if config.show_filename and post.filename %} - , - {% if post.filename|length > config.max_filename_display %} - {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} - {% else %} - {{ post.filename|bidi_cleanup }} - {% endif %} - {% endif %} - {% if post.thumb != 'file' and config.image_identification %} - , - - io - {% if post.file|extension == 'jpg' %} - e - {% endif %} - g - t - - {% endif %} - - ) - -

- - - - {% endif %} - {{ post.postControls }} -
- {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} -
-
-
-{% endfilter %} +{% filter remove_whitespace %} +{# tabs and new lines will be ignored #} +
+ +

+ + + {% if config.poster_ids %} + ID: {{ post.ip|poster_id(post.thread) }} + {% endif %} + No. + + {{ post.id }} + +

+ {% if post.embed %} + {{ post.embed }} + {% elseif post.file == 'deleted' %} + + {% elseif post.file and post.file %} +

File: {{ post.file }} + ( + {% if post.thumb == 'spoiler' %} + Spoiler Image, + {% endif %} + {{ post.filesize|filesize }} + {% if post.filex and post.filey %} + , {{ post.filex}}x{{ post.filey }} + {% if config.show_ratio %} + , {{ post.ratio }} + {% endif %} + {% endif %} + {% if config.show_filename and post.filename %} + , + {% if post.filename|length > config.max_filename_display %} + {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} + {% else %} + {{ post.filename|bidi_cleanup }} + {% endif %} + {% endif %} + {% if post.thumb != 'file' and config.image_identification %} + , + + io + {% if post.file|extension == 'jpg' %} + e + {% endif %} + g + t + + {% endif %} + + ) + +

+ + + + {% endif %} + {{ post.postControls }} +
+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} +
+
+
+{% endfilter %} diff --git a/templates/post_thread.html b/templates/post_thread.html index 72c841be..6d14f207 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -1,160 +1,160 @@ -{% filter remove_whitespace %} -{# tabs and new lines will be ignored #} - -
- -{% if post.embed %} - {{ post.embed }} -{% elseif post.file == 'deleted' %} - -{% elseif post.file and post.file %} -

{% trans %}File:{% endtrans %} {{ post.file }} - ( - {% if post.thumb == 'spoiler' %} - {% trans %}Spoiler Image{% endtrans %}, - {% endif %} - {{ post.filesize|filesize }} - {% if post.filex and post.filey %} - , {{ post.filex}}x{{ post.filey }} - {% if config.show_ratio %} - , {{ post.ratio }} - {% endif %} - {% endif %} - {% if config.show_filename and post.filename %} - , - {% if post.filename|length > config.max_filename_display %} - {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} - {% else %} - {{ post.filename|bidi_cleanup }} - {% endif %} - {% endif %} - {% if post.thumb != 'file' and config.image_identification %} - , - - io - {% if post.file|extension == 'jpg' %} - e - {% endif %} - g - t - - {% endif %} - ) -

- - -{% endif %} -

- - - {% if config.poster_ids %} - ID: {{ post.ip|poster_id(post.id) }} - {% endif %} - No. - - {{ post.id }} - +{% filter remove_whitespace %} +{# tabs and new lines will be ignored #} + +

+ +{% if post.embed %} + {{ post.embed }} +{% elseif post.file == 'deleted' %} + +{% elseif post.file and post.file %} +

{% trans %}File:{% endtrans %} {{ post.file }} + ( + {% if post.thumb == 'spoiler' %} + {% trans %}Spoiler Image{% endtrans %}, + {% endif %} + {{ post.filesize|filesize }} + {% if post.filex and post.filey %} + , {{ post.filex}}x{{ post.filey }} + {% if config.show_ratio %} + , {{ post.ratio }} + {% endif %} + {% endif %} + {% if config.show_filename and post.filename %} + , + {% if post.filename|length > config.max_filename_display %} + {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} + {% else %} + {{ post.filename|bidi_cleanup }} + {% endif %} + {% endif %} + {% if post.thumb != 'file' and config.image_identification %} + , + + io + {% if post.file|extension == 'jpg' %} + e + {% endif %} + g + t + + {% endif %} + ) +

+ + +{% endif %} +

+ + + {% if config.poster_ids %} + ID: {{ post.ip|poster_id(post.id) }} + {% endif %} + No. + + {{ post.id }} + {% if post.sticky %} {% if config.font_awesome %} - {% else %} + {% else %} Sticky - {% endif %} - {% endif %} + {% endif %} + {% endif %} {% if post.locked %} {% if config.font_awesome %} - {% else %} + {% else %} Locked - {% endif %} - {% endif %} + {% endif %} + {% endif %} {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %} {% if config.font_awesome %} - {% else %} + {% else %} Bumplocked - {% endif %} - {% endif %} - {% if index %} - [{% trans %}Reply{% endtrans %}] - {% endif %} - {{ post.postControls }} -

-
- {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} -
- {% if post.omitted or post.omitted_images %} - - {% if post.omitted %} - {% trans %} - 1 post - {% plural post.omitted %} - {{ count }} posts - {% endtrans %} - {% if post.omitted_images %} - {% trans %}and{% endtrans %} - {% endif %} - {% endif %} - {% if post.omitted_images %} - {% trans %} - 1 image reply - {% plural post.omitted_images %} - {{ count }} image replies - {% endtrans %} - {% endif %} {% trans %}omitted. Click reply to view.{% endtrans %} - - {% endif %} -{% if not index %} -{% endif %} -
{% endfilter %} -{% set hr = post.hr %} -{% for post in post.posts %} - {% include 'post_reply.html' %} -{% endfor %} -
{% if hr %}
{% endif %} -
+ {% endif %} + {% endif %} + {% if index %} + [{% trans %}Reply{% endtrans %}] + {% endif %} + {{ post.postControls }} +

+
+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} +
+ {% if post.omitted or post.omitted_images %} + + {% if post.omitted %} + {% trans %} + 1 post + {% plural post.omitted %} + {{ count }} posts + {% endtrans %} + {% if post.omitted_images %} + {% trans %}and{% endtrans %} + {% endif %} + {% endif %} + {% if post.omitted_images %} + {% trans %} + 1 image reply + {% plural post.omitted_images %} + {{ count }} image replies + {% endtrans %} + {% endif %} {% trans %}omitted. Click reply to view.{% endtrans %} + + {% endif %} +{% if not index %} +{% endif %} +
{% endfilter %} +{% set hr = post.hr %} +{% for post in post.posts %} + {% include 'post_reply.html' %} +{% endfor %} +
{% if hr %}
{% endif %} +
diff --git a/templates/posts.sql b/templates/posts.sql index 0a1dc92a..698fad77 100644 --- a/templates/posts.sql +++ b/templates/posts.sql @@ -1,4 +1,4 @@ -CREATE TABLE IF NOT EXISTS `posts_{{ board }}` ( +CREATE TABLE IF NOT EXISTS `posts_{{ board }}` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `thread` int(11) DEFAULT NULL, `subject` varchar(100) DEFAULT NULL, diff --git a/templates/thread.html b/templates/thread.html index 53c784b4..5882d9b6 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -1,71 +1,71 @@ - - - - - - {% if config.url_favicon %}{% endif %} - {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} - - {% if config.meta_keywords %}{% endif %} + + + + + + {% if config.url_favicon %}{% endif %} + {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} + + {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} - {% if not nojavascript %} - - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - {% if config.recaptcha %}{% endif %} - - - {{ boardlist.top }} - {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} - {% if config.url_banner %}{% endif %} -
-

{{ board.url }} - {{ board.title|e }}

-
- {% if board.subtitle %} - {{ board.subtitle|e }} - {% endif %} - {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} -
-
- - - - {% include 'post_form.html' %} - - {% if config.blotter %}
{{ config.blotter }}
{% endif %} -
-
- - {% if mod %}{% endif %} - {{ body }} - {% include 'report_delete.html' %} -
- [{% trans %}Return{% endtrans %}] - - {{ boardlist.bottom }} -
-

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

- {% for footer in config.footer %}

{{ footer }}

{% endfor %} -
- - - + {% if config.font_awesome %}{% endif %} + {% if not nojavascript %} + + {% if not config.additional_javascript_compile %} + {% for javascript in config.additional_javascript %}{% endfor %} + {% endif %} + {% endif %} + {% if config.recaptcha %}{% endif %} + + + {{ boardlist.top }} + {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} + {% if config.url_banner %}{% endif %} +
+

{{ board.url }} - {{ board.title|e }}

+
+ {% if board.subtitle %} + {{ board.subtitle|e }} + {% endif %} + {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} +
+
+ + + + {% include 'post_form.html' %} + + {% if config.blotter %}
{{ config.blotter }}
{% endif %} +
+
+ + {% if mod %}{% endif %} + {{ body }} + {% include 'report_delete.html' %} +
+ [{% trans %}Return{% endtrans %}] + + {{ boardlist.bottom }} +
+

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

+ {% for footer in config.footer %}

{{ footer }}

{% endfor %} +
+ + + -- cgit v1.3 From 15d2c3e28a4f1590a0a42387dd198eb433ff8580 Mon Sep 17 00:00:00 2001 From: Marcin Łabanowski Date: Wed, 2 Jan 2013 05:49:04 +0100 Subject: Added recent_dark stylesheet for recent template, need to be changed currently in style.php though --- templates/themes/recent/recent_dark.css | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 templates/themes/recent/recent_dark.css (limited to 'templates') diff --git a/templates/themes/recent/recent_dark.css b/templates/themes/recent/recent_dark.css new file mode 100644 index 00000000..c59214ac --- /dev/null +++ b/templates/themes/recent/recent_dark.css @@ -0,0 +1,73 @@ +body { + color: #CCCCCC; + background: #1E1E1E; +} + +header div.subtitle, h1 { + color: #CCCCCC; +} + +a:link, a:visited, p.intro a.email span.name { + color: #CCCCCC; + text-decoration: underline; + font-family: sans-serif; +} +a:link:hover, a:visited:hover { + color: #FF0000; + font-family: sans-serif; + text-decoration: underline overline; +} + +.box-wrap { + max-width: 670px; + min-width: 332px; + margin: 30px auto; + overflow: auto; + padding: 0; +} +.box { + background: white; + border: 1px solid #98E; + width: 330px; + margin: 8px 0; + padding: 0; +} +.box ul { + padding: 2px 15px; +} +.box ul li { + list-style: none; + margin: 0; +} +.box.left { + background: #333333; + color: #CCCCCC; + border: #555555 1px solid; + float: left; +} +.box.right { + background: #333333; + color: #CCCCCC; + border: #555555 1px solid; + float: right; +} + +.box h2 { + padding: 3px 7px; + font-size: 12pt; + border: #555555 1px solid; +} +.box.left h2 { + background: #333333; + color: #CCCCCC; + border: #555555 1px solid; +} +.box.right h2 { + background: #333333; + color: #CCCCCC; + border: #555555 1px solid; +} +.box img { + float: none; + margin: 10px auto; +} -- cgit v1.3 From b01417be444bd3217ae09067c039cc14f3a5593b Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sun, 6 Jan 2013 13:40:33 +0100 Subject: added Fluttershy recent theme and theme picker --- templates/themes/recent/info.php | 8 +++++ templates/themes/recent/recent_fs.css | 57 +++++++++++++++++++++++++++++++++++ templates/themes/recent/theme.php | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 templates/themes/recent/recent_fs.css (limited to 'templates') diff --git a/templates/themes/recent/info.php b/templates/themes/recent/info.php index d4cf1029..58448b3d 100644 --- a/templates/themes/recent/info.php +++ b/templates/themes/recent/info.php @@ -55,6 +55,14 @@ 'default' => 'recent.css', 'comment' => '(eg. "recent.css")' ); + + $theme['config'][] = Array( + 'title' => 'CSS stylesheet name', + 'name' => 'basecss', + 'type' => 'text', + 'default' => 'recent.css', + 'comment' => '(eg. "recent.css" - see templates/themes/recent for details)' + ); // Unique function name for building everything $theme['build_function'] = 'recentposts_build'; diff --git a/templates/themes/recent/recent_fs.css b/templates/themes/recent/recent_fs.css new file mode 100644 index 00000000..26aed668 --- /dev/null +++ b/templates/themes/recent/recent_fs.css @@ -0,0 +1,57 @@ +.box-wrap { + max-width: 670px; + min-width: 332px; + margin: 30px auto; + overflow: auto; + padding: 0; +} +.box { + background: white; + border: 1px solid #98E; + width: 330px; + margin: 8px 0; + padding: 0; +} +.box ul { + padding: 2px 15px; +} +.box ul li { + list-style: none; + margin: 0; +} +.box.left { + background: #FDF6AF; + color: #9E914F; + border: 1px solid #9E914F; + float: left; +} +.box.right { + background: #F2DCE5; + color: #525; + border: 1px solid #CA759E; + float: right; +} + +.box h2 { + padding: 3px 7px; + font-size: 12pt; +} +.box img { + float: none; + margin: 10px auto; +} +.box.left h2 { + background: #FEE78F; + color: #9E914F; +} +.box.right h2 { + background: #EB81B4; + color: #F8F8F8; +} + +body { + background: #F7F8F9; +} +header div.subtitle, h1 { + color: #888A8C; +} diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index 1ebe58f6..75907e77 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -19,7 +19,7 @@ global $config, $_theme; if ($action == 'all') { - copy('templates/themes/recent/recent.css', $config['dir']['home'] . $settings['css']); + copy('templates/themes/recent/' . $settings['basecss'], $config['dir']['home'] . $settings['css']); } $this->excluded = explode(' ', $settings['exclude']); -- cgit v1.3 From 317f616e822c4519c78ac068bb69d285955bb39e Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 05:06:29 -0400 Subject: Accidentally included header.html twice --- templates/index.html | 1 - 1 file changed, 1 deletion(-) (limited to 'templates') diff --git a/templates/index.html b/templates/index.html index da6101ee..1cde9882 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,7 +1,6 @@ - {% include 'header.html' %} {% include 'header.html' %} {{ board.url }} - {{ board.title|e }} -- cgit v1.3 From d692bce68674934a4af2e9cba79d65e72279b0a9 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 16:34:50 -0400 Subject: Fix issue #74. Note: This bug may break the display of certain filenames prior to upgrade. --- post.php | 6 +++--- templates/post_reply.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'templates') diff --git a/post.php b/post.php index a82b56ad..8820db2d 100644 --- a/post.php +++ b/post.php @@ -284,7 +284,7 @@ if (isset($_POST['delete'])) { $post['has_file'] = !isset($post['embed']) && (($post['op'] && !isset($post['no_longer_require_an_image_for_op']) && $config['force_image_op']) || (isset($_FILES['file']) && $_FILES['file']['tmp_name'] != '')); if ($post['has_file']) - $post['filename'] = utf8tohtml(get_magic_quotes_gpc() ? stripslashes($_FILES['file']['name']) : $_FILES['file']['name']); + $post['filename'] = urldecode(get_magic_quotes_gpc() ? stripslashes($_FILES['file']['name']) : $_FILES['file']['name']); if (!($post['has_file'] || isset($post['embed'])) || (($post['op'] && $config['force_body_op']) || (!$post['op'] && $config['force_body']))) { $stripped_whitespace = preg_replace('/[\s]/u', '', $post['body']); @@ -347,7 +347,7 @@ if (isset($_POST['delete'])) { } else $noko = false; if ($post['has_file']) { - $post['extension'] = strtolower(substr($post['filename'], strrpos($post['filename'], '.') + 1)); + $post['extension'] = strtolower(mb_substr($post['filename'], mb_strrpos($post['filename'], '.') + 1)); if (isset($config['filename_func'])) $post['file_id'] = $config['filename_func']($post); else @@ -414,7 +414,7 @@ if (isset($_POST['delete'])) { $is_an_image = !in_array($post['extension'], $config['allowed_ext_files']); // Truncate filename if it is too long - $post['filename'] = substr($post['filename'], 0, $config['max_filename_len']); + $post['filename'] = mb_substr($post['filename'], 0, $config['max_filename_len']); $upload = $_FILES['file']['tmp_name']; diff --git a/templates/post_reply.html b/templates/post_reply.html index bc96e74c..b0391f19 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -66,9 +66,9 @@ {% if config.show_filename and post.filename %} , {% if post.filename|length > config.max_filename_display %} - {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} + {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} {% else %} - {{ post.filename|bidi_cleanup }} + {{ post.filename|e|bidi_cleanup }} {% endif %} {% endif %} {% if post.thumb != 'file' and config.image_identification %} -- cgit v1.3 From 6cdf6038754f18af4509ecf078f51894f63c5853 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 16:38:09 -0400 Subject: Fix last commit; Make Tinyboard Twig extension more mb-safe --- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 8 ++++---- templates/post_thread.html | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 61cf9fc9..58a98c40 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -83,9 +83,9 @@ function twig_hasPermission_filter($mod, $permission, $board = null) { } function twig_extension_filter($value, $case_insensitive = true) { - $ext = substr($value, strrpos($value, '.') + 1); + $ext = mb_substr($value, mb_strrpos($value, '.') + 1); if($case_insensitive) - $ext = strtolower($ext); + $ext = mb_strtolower($ext); return $ext; } @@ -96,11 +96,11 @@ function twig_sprintf_filter( $value, $var) { function twig_truncate_filter($value, $length = 30, $preserve = false, $separator = '…') { if (mb_strlen($value) > $length) { if ($preserve) { - if (false !== ($breakpoint = strpos($value, ' ', $length))) { + if (false !== ($breakpoint = mb_strpos($value, ' ', $length))) { $length = $breakpoint; } } - return substr($value, 0, $length) . $separator; + return mb_substr($value, 0, $length) . $separator; } return $value; } diff --git a/templates/post_thread.html b/templates/post_thread.html index 6d14f207..21add308 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -23,9 +23,9 @@ {% if config.show_filename and post.filename %} , {% if post.filename|length > config.max_filename_display %} - {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} + {{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }} {% else %} - {{ post.filename|bidi_cleanup }} + {{ post.filename|e|bidi_cleanup }} {% endif %} {% endif %} {% if post.thumb != 'file' and config.image_identification %} -- cgit v1.3 From 6317a7015272d770770c000c69271ff73cf55007 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 15 Jun 2013 00:22:13 -0400 Subject: header abstraction: abstracted also in thread.html Conflicts: templates/page.html templates/thread.html --- templates/page.html | 2 +- templates/thread.html | 36 +++++------------------------------- 2 files changed, 6 insertions(+), 32 deletions(-) (limited to 'templates') diff --git a/templates/page.html b/templates/page.html index a7c6a300..0d33c16f 100644 --- a/templates/page.html +++ b/templates/page.html @@ -22,4 +22,4 @@

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

- + \ No newline at end of file diff --git a/templates/thread.html b/templates/thread.html index 5882d9b6..a6b8793f 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -2,34 +2,8 @@ - - {% if config.url_favicon %}{% endif %} + {% include 'header.html' %} {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} - - {% if config.meta_keywords %}{% endif %} - {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} - {% if not nojavascript %} - - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - {% if config.recaptcha %}{% endif %} {{ boardlist.top }} @@ -44,11 +18,11 @@ {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %}
- + - + {% include 'post_form.html' %} - + {% if config.blotter %}
{{ config.blotter }}
{% endif %}
@@ -68,4 +42,4 @@ ready(); {% endraw %} - + \ No newline at end of file -- cgit v1.3 From 328484bee7cab9ce354121413cc8d96c3e227aea Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 20:51:43 -0400 Subject: SQL cleanup --- inc/functions.php | 63 +++++++++++++++++++------------------- inc/mod/auth.php | 2 +- inc/mod/pages.php | 32 +++++++++---------- post.php | 10 +++--- templates/themes/catalog/theme.php | 2 +- templates/themes/recent/theme.php | 19 +++++------- templates/themes/rrdtool/theme.php | 5 ++- 7 files changed, 64 insertions(+), 69 deletions(-) (limited to 'templates') diff --git a/inc/functions.php b/inc/functions.php index 7cde156b..0b4ac211 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -243,7 +243,7 @@ function rebuildThemes($action, $board = false) { // List themes $query = query("SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error()); - while ($theme = $query->fetch()) { + while ($theme = $query->fetch(PDO::FETCH_ASSOC)) { rebuildTheme($theme['theme'], $action, $board); } } @@ -281,7 +281,7 @@ function themeSettings($theme) { $query->execute() or error(db_error($query)); $settings = array(); - while ($s = $query->fetch()) { + while ($s = $query->fetch(PDO::FETCH_ASSOC)) { $settings[$s['name']] = $s['value']; } @@ -351,7 +351,7 @@ function getBoardInfo($uri) { $query->bindValue(':uri', $uri); $query->execute() or error(db_error($query)); - if ($board = $query->fetch()) { + if ($board = $query->fetch(PDO::FETCH_ASSOC)) { if ($config['cache']['enabled']) cache::set('board_' . $uri, $board); return $board; @@ -543,7 +543,7 @@ function checkFlood($post) { $query->bindValue(':floodsametime', time()-$config['flood_time_same'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $flood = (bool)$query->fetch(); + $flood = (bool) $query->fetch(PDO::FETCH_ASSOC); if (event('check-flood', $post)) return true; @@ -647,7 +647,7 @@ function checkBan($board = 0) { $query->execute() or error(db_error($query)); } - if ($ban = $query->fetch()) { + if ($ban = $query->fetch(PDO::FETCH_ASSOC)) { if ($ban['expires'] && $ban['expires'] < time()) { // Ban expired $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); @@ -685,12 +685,12 @@ function threadLocked($id) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error()); - if (!$post = $query->fetch()) { + if (($locked = $query->fetchColumn()) === false) { // Non-existant, so it can't be locked... return false; } - return (bool)$post['locked']; + return (bool)$locked; } function threadSageLocked($id) { @@ -703,12 +703,12 @@ function threadSageLocked($id) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error()); - if (!$post = $query->fetch()) { + if (($sagelocked = $query->fetchColumn()) === false) { // Non-existant, so it can't be locked... return false; } - return (bool) $post['sage']; + return (bool)$sagelocked; } function threadExists($id) { @@ -842,7 +842,7 @@ function deleteFile($id, $remove_entirely_if_already=true) { $query = prepare(sprintf("SELECT `thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if (!$post = $query->fetch()) + if (!$post = $query->fetch(PDO::FETCH_ASSOC)) error($config['error']['invalidpost']); if ($post['file'] == 'deleted' && !$post['thread']) @@ -880,7 +880,7 @@ function rebuildPost($id) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ((!$post = $query->fetch()) || !$post['body_nomarkup']) + if ((!$post = $query->fetch(PDO::FETCH_ASSOC)) || !$post['body_nomarkup']) return false; markup($body = &$post['body_nomarkup']); @@ -913,7 +913,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { $ids = array(); // Delete posts and maybe replies - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { if (!$post['thread']) { // Delete thread HTML page file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['id'])); @@ -946,7 +946,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board AND (`target` = " . implode(' OR `target` = ', $ids) . ")"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); - while ($cite = $query->fetch()) { + while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if ($board['uri'] != $cite['board']) { if (!isset($tmp_board)) $tmp_board = $board['uri']; @@ -979,7 +979,7 @@ function clean() { $query->bindValue(':offset', $offset, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { deletePost($post['id']); } } @@ -1000,7 +1000,7 @@ function index($page, $mod=false) { if ($query->rowCount() < 1 && $page > 1) return false; - while ($th = $query->fetch()) { + while ($th = $query->fetch(PDO::FETCH_ASSOC)) { $thread = new Thread( $th['id'], $th['subject'], $th['email'], $th['name'], $th['trip'], $th['capcode'], $th['body'], $th['time'], $th['thumb'], $th['thumbwidth'], $th['thumbheight'], $th['file'], $th['filewidth'], $th['fileheight'], $th['filesize'], $th['filename'], $th['ip'], @@ -1115,7 +1115,7 @@ function getPages($mod=false) { $count = $board['thread_count']; } else { // Count threads - $query = query(sprintf("SELECT COUNT(`id`) FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); + $query = query(sprintf("SELECT COUNT(*) FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); $count = $query->fetchColumn(); } $count = floor(($config['threads_per_page'] + $count - 1) / $config['threads_per_page']); @@ -1155,7 +1155,7 @@ function checkRobot($body) { $query->bindValue(':hash', $body); $query->execute() or error(db_error($query)); - if ($query->fetch()) { + if ($query->fetchColumn()) { return true; } @@ -1163,20 +1163,19 @@ function checkRobot($body) { $query = prepare("INSERT INTO `robot` VALUES (:hash)"); $query->bindValue(':hash', $body); $query->execute() or error(db_error($query)); + return false; } // Returns an associative array with 'replies' and 'images' keys function numPosts($id) { global $board; - $query = prepare(sprintf("SELECT COUNT(*) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); + $query = prepare(sprintf("SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); $query->bindValue(':thread', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $num_posts = $query->fetch(); - $num_posts = $num_posts['num']; - $num_images = $query->fetch(); - $num_images = $num_images['num']; + $num_posts = $query->fetchColumn(); + $num_images = $query->fetchColumn(); return array('replies' => $num_posts, 'images' => $num_images); } @@ -1188,14 +1187,14 @@ function muteTime() { return $time; // Find number of mutes in the past X hours - $query = prepare("SELECT COUNT(*) as `count` FROM `mutes` WHERE `time` >= :time AND `ip` = :ip"); + $query = prepare("SELECT COUNT(*) FROM `mutes` WHERE `time` >= :time AND `ip` = :ip"); $query->bindValue(':time', time()-($config['robot_mute_hour']*3600), PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->execute() or error(db_error($query)); - $result = $query->fetch(); - if ($result['count'] == 0) return 0; - return pow($config['robot_mute_multiplier'], $result['count']); + if (!$result = $query->fetchColumn()) + return 0; + return pow($config['robot_mute_multiplier'], $result); } function mute() { @@ -1225,7 +1224,7 @@ function checkMute() { $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->execute() or error(db_error($query)); - if (!$mute = $query->fetch()) { + if (!$mute = $query->fetch(PDO::FETCH_ASSOC)) { // What!? He's muted but he's not muted... return; } @@ -1514,7 +1513,7 @@ function markup(&$body, $track_cites = false) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } - if ($post = $query->fetch()) { + if ($post = $query->fetch(PDO::FETCH_ASSOC)) { $replacement = '' . '>>' . $cite . @@ -1557,7 +1556,7 @@ function markup(&$body, $track_cites = false) { $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); - if ($post = $query->fetch()) { + if ($post = $query->fetch(PDO::FETCH_ASSOC)) { $replacement = '' . '>>>/' . $_board . '/' . $cite . @@ -1666,7 +1665,7 @@ function buildThread($id, $return = false, $mod = false) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { if (!isset($thread)) { $thread = new Thread( $post['id'], $post['subject'], $post['email'], $post['name'], $post['trip'], $post['capcode'], $post['body'], $post['time'], @@ -1801,7 +1800,7 @@ function getPostByHash($hash) { $query->bindValue(':hash', $hash, PDO::PARAM_STR); $query->execute() or error(db_error($query)); - if ($post = $query->fetch()) { + if ($post = $query->fetch(PDO::FETCH_ASSOC)) { return $post; } @@ -1815,7 +1814,7 @@ function getPostByHashInThread($hash, $thread) { $query->bindValue(':thread', $thread, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($post = $query->fetch()) { + if ($post = $query->fetch(PDO::FETCH_ASSOC)) { return $post; } diff --git a/inc/mod/auth.php b/inc/mod/auth.php index 1bc27dff..a0986a1f 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -147,7 +147,7 @@ function create_pm_header() { $query->bindValue(':id', $mod['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($pm = $query->fetch()) + if ($pm = $query->fetch(PDO::FETCH_ASSOC)) $header = array('id' => $pm['id'], 'waiting' => $query->rowCount() - 1); else $header = true; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 351d3203..f5b1101d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -96,14 +96,14 @@ function mod_dashboard() { $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :id AND `unread` = 1'); $query->bindValue(':id', $mod['id']); $query->execute() or error(db_error($query)); - $args['unread_pms'] = $query->fetchColumn(0); + $args['unread_pms'] = $query->fetchColumn(); if ($config['cache']['enabled']) cache::set('pm_unreadcount_' . $mod['id'], $args['unread_pms']); } $query = query('SELECT COUNT(*) FROM `reports`') or error(db_error($query)); - $args['reports'] = $query->fetchColumn(0); + $args['reports'] = $query->fetchColumn(); if ($mod['type'] >= ADMIN && $config['check_updates']) { if (!$config['version']) @@ -536,7 +536,7 @@ function mod_noticeboard($page_no = 1) { $query = prepare("SELECT COUNT(*) FROM `noticeboard`"); $query->execute() or error(db_error($query)); - $count = $query->fetchColumn(0); + $count = $query->fetchColumn(); mod_page(_('Noticeboard'), 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); } @@ -597,7 +597,7 @@ function mod_news($page_no = 1) { $query = prepare("SELECT COUNT(*) FROM `news`"); $query->execute() or error(db_error($query)); - $count = $query->fetchColumn(0); + $count = $query->fetchColumn(); mod_page(_('News'), 'mod/news.html', array('news' => $news, 'count' => $count)); } @@ -637,7 +637,7 @@ function mod_log($page_no = 1) { $query = prepare("SELECT COUNT(*) FROM `modlogs`"); $query->execute() or error(db_error($query)); - $count = $query->fetchColumn(0); + $count = $query->fetchColumn(); mod_page(_('Moderation log'), 'mod/log.html', array('logs' => $logs, 'count' => $count)); } @@ -664,7 +664,7 @@ function mod_user_log($username, $page_no = 1) { $query = prepare("SELECT COUNT(*) FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); - $count = $query->fetchColumn(0); + $count = $query->fetchColumn(); mod_page(_('Moderation log'), 'mod/log.html', array('logs' => $logs, 'count' => $count, 'username' => $username)); } @@ -906,7 +906,7 @@ function mod_bans($page_no = 1) { $query = prepare("SELECT COUNT(*) FROM `bans`"); $query->execute() or error(db_error($query)); - $count = $query->fetchColumn(0); + $count = $query->fetchColumn(); foreach ($bans as &$ban) { if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false) @@ -1058,7 +1058,7 @@ function mod_move($originBoard, $postID) { $replies = array(); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['mod'] = true; $post['thread'] = $newID; @@ -1365,7 +1365,7 @@ function mod_deletebyip($boardName, $post, $global = false) { $query = prepare(sprintf('SELECT `ip` FROM `posts_%s` WHERE `id` = :id', $boardName)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); - if (!$ip = $query->fetchColumn(0)) + if (!$ip = $query->fetchColumn()) error($config['error']['invalidpost']); $boards = $global ? listBoards() : array(array('uri' => $boardName)); @@ -1387,7 +1387,7 @@ function mod_deletebyip($boardName, $post, $global = false) { $threads_to_rebuild = array(); $threads_deleted = array(); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); deletePost($post['id'], false, false); @@ -1684,7 +1684,7 @@ function mod_inbox() { $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :mod AND `unread` = 1'); $query->bindValue(':mod', $mod['id']); $query->execute() or error(db_error($query)); - $unread = $query->fetchColumn(0); + $unread = $query->fetchColumn(); foreach ($messages as &$message) { $message['snippet'] = pm_snippet($message['message']); @@ -1706,12 +1706,12 @@ function mod_new_pm($username) { $query = prepare("SELECT `id` FROM `mods` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); - if (!$id = $query->fetchColumn(0)) { + if (!$id = $query->fetchColumn()) { // Old style ?/PM: by user ID $query = prepare("SELECT `username` FROM `mods` WHERE `id` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); - if ($username = $query->fetchColumn(0)) + if ($username = $query->fetchColumn()) header('Location: ?/new_PM/' . $username, true, $config['redirect_http']); else error($config['error']['404']); @@ -1832,7 +1832,7 @@ function mod_reports() { $report_posts[$board] = array(); $query = query(sprintf('SELECT * FROM `posts_%s` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error()); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $report_posts[$board][$post['id']] = $post; } } @@ -2169,10 +2169,10 @@ function mod_debug_antispam() { } $query = query('SELECT COUNT(*) FROM `antispam`' . ($where ? " WHERE $where" : '')) or error(db_error()); - $args['total'] = number_format($query->fetchColumn(0)); + $args['total'] = number_format($query->fetchColumn()); $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL' . ($where ? " AND $where" : '')) or error(db_error()); - $args['expiring'] = number_format($query->fetchColumn(0)); + $args['expiring'] = number_format($query->fetchColumn()); $query = query('SELECT * FROM `antispam` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `passed` DESC LIMIT 40') or error(db_error()); $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); diff --git a/post.php b/post.php index db077866..f4499845 100644 --- a/post.php +++ b/post.php @@ -52,7 +52,7 @@ if (isset($_POST['delete'])) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($post = $query->fetch()) { + if ($post = $query->fetch(PDO::FETCH_ASSOC)) { if ($password != '' && $post['password'] != $password) error($config['error']['invalidpassword']); @@ -115,12 +115,12 @@ if (isset($_POST['delete'])) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $post = $query->fetch(); + $thread = $query->fetchColumn(); - if ($post) { + if ($thread) { if ($config['syslog']) _syslog(LOG_INFO, 'Reported post: ' . - '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $id) . ($post['thread'] ? '#' . $id : '') . + '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $thread ? $thread : $id) . ($thread ? '#' . $id : '') . ' for "' . $reason . '"' ); $query = prepare("INSERT INTO `reports` VALUES (NULL, :time, :ip, :board, :post, :reason)"); @@ -231,7 +231,7 @@ if (isset($_POST['delete'])) { $query->bindValue(':id', $post['thread'], PDO::PARAM_INT); $query->execute() or error(db_error()); - if (!$thread = $query->fetch()) { + if (!$thread = $query->fetch(PDO::FETCH_ASSOC)) { // Non-existant error($config['error']['nonexistant']); } diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index e585cf17..5c9f6769 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -39,7 +39,7 @@ $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error()); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])); $post['board_name'] = $board['name']; $post['file'] = $config['uri_thumb'] . $post['thumb']; diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index 75907e77..98fabfa1 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -47,7 +47,7 @@ $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_images'], $query); $query = query($query) or error(db_error()); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); // board settings won't be available in the template file, so generate links now @@ -67,7 +67,7 @@ $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_posts'], $query); $query = query($query) or error(db_error()); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; @@ -78,7 +78,7 @@ } // Total posts - $query = 'SELECT SUM(`top`) AS `count` FROM ('; + $query = 'SELECT SUM(`top`) FROM ('; foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; @@ -86,11 +86,10 @@ } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); - $res = $query->fetch(); - $stats['total_posts'] = number_format($res['count']); + $stats['total_posts'] = number_format($query->fetchColumn()); // Unique IPs - $query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM ('; + $query = 'SELECT COUNT(DISTINCT(`ip`)) FROM ('; foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; @@ -98,11 +97,10 @@ } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); - $res = $query->fetch(); - $stats['unique_posters'] = number_format($res['count']); + $stats['unique_posters'] = number_format($query->fetchColumn()); // Active content - $query = 'SELECT SUM(`filesize`) AS `count` FROM ('; + $query = 'SELECT SUM(`filesize`) FROM ('; foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; @@ -110,8 +108,7 @@ } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); - $res = $query->fetch(); - $stats['active_content'] = $res['count']; + $stats['active_content'] = $query->fetchColumn(); return Element('themes/recent/recent.html', Array( 'settings' => $settings, diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php index 68fc1850..0e0a2f15 100644 --- a/templates/themes/rrdtool/theme.php +++ b/templates/themes/rrdtool/theme.php @@ -61,9 +61,8 @@ // debug just the graphing (not updating) with the --debug switch if (!isset($argv[1]) || $argv[1] != '--debug') { // Update graph - $query = query(sprintf("SELECT MAX(`id`) AS `count` FROM `posts_%s`", $board)); - $count = $query->fetch(); - $count = $count['count']; + $query = query(sprintf("SELECT MAX(`id`) FROM `posts_%s`", $board)); + $count = $query->fetchColumn(); if (!rrd_update($file, Array( '-t', -- cgit v1.3 From ea2b8cce077a092e0cbf136f9a45158668cc5ecf Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 21:24:17 -0400 Subject: Bugfix: HTML injection in post editing (introduces and fixes yet another bug) --- inc/functions.php | 4 ++-- inc/mod/pages.php | 9 ++++++--- templates/mod/edit_post_form.html | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/inc/functions.php b/inc/functions.php index b40b40d2..9e1ce1fa 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1420,7 +1420,7 @@ function markup(&$body, $track_cites = false) { $body = str_replace("\r", '', $body); $body = utf8tohtml($body); - if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@um', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + if (preg_match_all('@<tinyboard ([\w\s]+)>(.+?)</tinyboard>@um', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { $skip_chars = 0; $body_tmp = $body; $end_markup = false; @@ -1436,7 +1436,7 @@ function markup(&$body, $track_cites = false) { if ($modifier['type'] == 'ban message') { // Public ban message - $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + $replacement = sprintf($config['mod']['ban_message'], html_entity_decode($modifier['content'])); if ($end_markup) { $body .= $replacement; } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 7edc0ee6..2808dc56 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1222,7 +1222,7 @@ function mod_ban_post($board, $delete, $post, $token = false) { $_POST['message'] = str_replace('%LENGTH%', strtoupper($length_english), $_POST['message']); $query = prepare(sprintf('UPDATE `posts_%s` SET `body_nomarkup` = CONCAT(`body_nomarkup`, :body_nomarkup) WHERE `id` = :id', $board)); $query->bindValue(':id', $post); - $query->bindValue(':body_nomarkup', sprintf("\n%s", $_POST['message'])); + $query->bindValue(':body_nomarkup', sprintf("\n%s", utf8tohtml($_POST['message']))); $query->execute() or error(db_error($query)); rebuildPost($post); @@ -1298,10 +1298,13 @@ function mod_edit_post($board, $edit_raw_html, $postID) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $postID) . '#' . $postID, true, $config['redirect_http']); } else { if ($config['minify_html']) { - $post['body_nomarkup'] = str_replace("\n", ' ', $post['body_nomarkup']); - $post['body'] = str_replace("\n", ' ', $post['body']); + // $post['body_nomarkup'] = str_replace("\n", ' ', $post['body_nomarkup']); + // $post['body'] = str_replace("\n", ' ', $post['body']); } + // Minifying this page causes an issue with newlines in the textarea. This is a temporary solution. + $config['minify_html'] = false; + mod_page(_('Edit post'), 'mod/edit_post_form.html', array('token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post)); } } diff --git a/templates/mod/edit_post_form.html b/templates/mod/edit_post_form.html index 146e725b..b9359c68 100644 --- a/templates/mod/edit_post_form.html +++ b/templates/mod/edit_post_form.html @@ -32,7 +32,7 @@ {% trans %}Comment{% endtrans %} - + -- cgit v1.3 From a052a791b553c770ef407f91b697bef7a62df5b1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 22:14:26 -0400 Subject: Add optional database table prefix (issue #118; see issue comments for details) --- inc/anti-bot.php | 12 +-- inc/config.php | 2 + inc/database.php | 4 + inc/filters.php | 2 +- inc/functions.php | 80 +++++++-------- inc/mod/auth.php | 8 +- inc/mod/ban.php | 6 +- inc/mod/pages.php | 188 +++++++++++++++++----------------- install.php | 6 +- post.php | 10 +- templates/posts.sql | 2 +- templates/themes/basic/theme.php | 2 +- templates/themes/catalog/theme.php | 2 +- templates/themes/categories/theme.php | 2 +- templates/themes/frameset/theme.php | 2 +- templates/themes/recent/theme.php | 10 +- templates/themes/rrdtool/theme.php | 2 +- templates/themes/sitemap/theme.php | 2 +- 18 files changed, 177 insertions(+), 165 deletions(-) (limited to 'templates') diff --git a/inc/anti-bot.php b/inc/anti-bot.php index bf29b3cb..fde97096 100644 --- a/inc/anti-bot.php +++ b/inc/anti-bot.php @@ -182,12 +182,12 @@ function _create_antibot($board, $thread) { $antibot = new AntiBot(array($board, $thread)); - query('DELETE FROM `antispam` WHERE `expires` < UNIX_TIMESTAMP()') or error(db_error()); + query('DELETE FROM ``antispam`` WHERE `expires` < UNIX_TIMESTAMP()') or error(db_error()); if ($thread) - $query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` = :thread AND `expires` IS NULL'); + $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` = :thread AND `expires` IS NULL'); else - $query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` IS NULL AND `expires` IS NULL'); + $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` IS NULL AND `expires` IS NULL'); $query->bindValue(':board', $board); if ($thread) @@ -195,7 +195,7 @@ function _create_antibot($board, $thread) { $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); $query->execute() or error(db_error($query)); - $query = prepare('INSERT INTO `antispam` VALUES (:board, :thread, :hash, UNIX_TIMESTAMP(), NULL, 0)'); + $query = prepare('INSERT INTO ``antispam`` VALUES (:board, :thread, :hash, UNIX_TIMESTAMP(), NULL, 0)'); $query->bindValue(':board', $board); $query->bindValue(':thread', $thread); $query->bindValue(':hash', $antibot->hash()); @@ -248,7 +248,7 @@ function checkSpam(array $extra_salt = array()) { if ($hash != $_hash) return true; - $query = prepare('SELECT `passed` FROM `antispam` WHERE `hash` = :hash'); + $query = prepare('SELECT `passed` FROM ``antispam`` WHERE `hash` = :hash'); $query->bindValue(':hash', $hash); $query->execute() or error(db_error($query)); if ((($passed = $query->fetchColumn(0)) === false) || ($passed > $config['spam']['hidden_inputs_max_pass'])) { @@ -260,7 +260,7 @@ function checkSpam(array $extra_salt = array()) { } function incrementSpamHash($hash) { - $query = prepare('UPDATE `antispam` SET `passed` = `passed` + 1 WHERE `hash` = :hash'); + $query = prepare('UPDATE ``antispam`` SET `passed` = `passed` + 1 WHERE `hash` = :hash'); $query->bindValue(':hash', $hash); $query->execute() or error(db_error($query)); } diff --git a/inc/config.php b/inc/config.php index 6f2371ec..75384d3f 100644 --- a/inc/config.php +++ b/inc/config.php @@ -76,6 +76,8 @@ $config['db']['password'] = ''; // Tinyboard database $config['db']['database'] = ''; + // Table prefix + $config['db']['prefix'] = ''; // Use a persistent connection (experimental) $config['db']['persistent'] = false; // Anything more to add to the DSN string (eg. port=xxx;foo=bar) diff --git a/inc/database.php b/inc/database.php index 3dc0f0ce..7be001ea 100644 --- a/inc/database.php +++ b/inc/database.php @@ -87,6 +87,8 @@ function mysql_version() { function prepare($query) { global $pdo, $debug, $config; + $query = preg_replace('/``([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)``/u', '`' . $config['db']['prefix'] . '$1`', $query); + sql_open(); if ($config['debug']) @@ -98,6 +100,8 @@ function prepare($query) { function query($query) { global $pdo, $debug, $config; + $query = preg_replace('/``([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)``/u', '`' . $config['db']['prefix'] . '$1`', $query); + sql_open(); if ($config['debug']) { diff --git a/inc/filters.php b/inc/filters.php index 524d37cf..9f03154d 100644 --- a/inc/filters.php +++ b/inc/filters.php @@ -81,7 +81,7 @@ class Filter { else $all_boards = false; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :set, :expires, :reason, :board, 0)"); + $query = prepare("INSERT INTO ``bans`` VALUES (NULL, :ip, :mod, :set, :expires, :reason, :board, 0)"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':mod', -1); $query->bindValue(':set', time()); diff --git a/inc/functions.php b/inc/functions.php index 403f6112..e871fee0 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -241,7 +241,7 @@ function create_antibot($board, $thread = null) { function rebuildThemes($action, $board = false) { // List themes - $query = query("SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error()); + $query = query("SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error()); while ($theme = $query->fetch(PDO::FETCH_ASSOC)) { rebuildTheme($theme['theme'], $action, $board); @@ -276,7 +276,7 @@ function rebuildTheme($theme, $action, $board = false) { function themeSettings($theme) { - $query = prepare("SELECT `name`, `value` FROM `theme_settings` WHERE `theme` = :theme AND `name` IS NOT NULL"); + $query = prepare("SELECT `name`, `value` FROM ``theme_settings`` WHERE `theme` = :theme AND `name` IS NOT NULL"); $query->bindValue(':theme', $theme); $query->execute() or error(db_error($query)); @@ -347,7 +347,7 @@ function getBoardInfo($uri) { return $board; } - $query = prepare("SELECT * FROM `boards` WHERE `uri` = :uri LIMIT 1"); + $query = prepare("SELECT * FROM ``boards`` WHERE `uri` = :uri LIMIT 1"); $query->bindValue(':uri', $uri); $query->execute() or error(db_error($query)); @@ -523,7 +523,7 @@ function listBoards() { if ($config['cache']['enabled'] && ($boards = cache::get('all_boards'))) return $boards; - $query = query("SELECT * FROM `boards` ORDER BY `uri`") or error(db_error()); + $query = query("SELECT * FROM ``boards`` ORDER BY `uri`") or error(db_error()); $boards = $query->fetchAll(); if ($config['cache']['enabled']) @@ -535,7 +535,7 @@ function listBoards() { function checkFlood($post) { global $board, $config; - $query = prepare(sprintf("SELECT * FROM `posts_%s` WHERE (`ip` = :ip AND `time` >= :floodtime) OR (`ip` = :ip AND `body` != '' AND `body` = :body AND `time` >= :floodsameiptime) OR (`body` != '' AND `body` = :body AND `time` >= :floodsametime) LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`ip` = :ip AND `time` >= :floodtime) OR (`ip` = :ip AND `body` != '' AND `body` = :body AND `time` >= :floodsameiptime) OR (`body` != '' AND `body` = :body AND `time` >= :floodsametime) LIMIT 1", $board['uri'])); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':body', $post['body']); $query->bindValue(':floodtime', time()-$config['flood_time'], PDO::PARAM_INT); @@ -589,7 +589,7 @@ function displayBan($ban) { global $config; if (!$ban['seen']) { - $query = prepare("UPDATE `bans` SET `seen` = 1 WHERE `id` = :id"); + $query = prepare("UPDATE ``bans`` SET `seen` = 1 WHERE `id` = :id"); $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); } @@ -620,12 +620,12 @@ function checkBan($board = 0) { if (event('check-ban', $board)) return true; - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, ``bans``.`id` FROM ``bans`` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); if ($query->rowCount() < 1 && $config['ban_range']) { - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, ``bans``.`id` FROM ``bans`` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); @@ -633,7 +633,7 @@ function checkBan($board = 0) { if ($query->rowCount() < 1 && $config['ban_cidr'] && !isIPv6()) { // my most insane SQL query yet - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, ``bans``.`id` FROM ``bans`` WHERE (`board` IS NULL OR `board` = :board) AND ( `ip` REGEXP '^(\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+\)\/(\[0-9]+)$' AND @@ -650,7 +650,7 @@ function checkBan($board = 0) { if ($ban = $query->fetch(PDO::FETCH_ASSOC)) { if ($ban['expires'] && $ban['expires'] < time()) { // Ban expired - $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); + $query = prepare("DELETE FROM ``bans`` WHERE `id` = :id"); $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -670,7 +670,7 @@ function checkBan($board = 0) { // No reason to keep expired bans in the database (except those that haven't been viewed yet) function purge_bans() { - $query = prepare("DELETE FROM `bans` WHERE `expires` IS NOT NULL AND `expires` < :time AND `seen` = 1"); + $query = prepare("DELETE FROM ``bans`` WHERE `expires` IS NOT NULL AND `expires` < :time AND `seen` = 1"); $query->bindValue(':time', time()); $query->execute() or error(db_error($query)); } @@ -681,7 +681,7 @@ function threadLocked($id) { if (event('check-locked', $id)) return true; - $query = prepare(sprintf("SELECT `locked` FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `locked` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error()); @@ -699,7 +699,7 @@ function threadSageLocked($id) { if (event('check-sage-locked', $id)) return true; - $query = prepare(sprintf("SELECT `sage` FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `sage` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error()); @@ -714,7 +714,7 @@ function threadSageLocked($id) { function threadExists($id) { global $board; - $query = prepare(sprintf("SELECT 1 FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT 1 FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error()); @@ -727,7 +727,7 @@ function threadExists($id) { function post(array $post) { global $pdo, $board; - $query = prepare(sprintf("INSERT INTO `posts_%s` (`id`, `thread`, `subject`, `email`, `name`, `trip`, `capcode`, `body`, `body_nomarkup`, `time`, `bump`, `thumb`, `thumbwidth`, `thumbheight`, `file`, `filewidth`, `fileheight`, `filesize`, `filename`, `filehash`, `password`, `ip`, `sticky`, `locked`, `sage`, `embed`) VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :thumb, :thumbwidth, :thumbheight, :file, :width, :height, :filesize, :filename, :filehash, :password, :ip, :sticky, :locked, 0, :embed)", $board['uri'])); + $query = prepare(sprintf("INSERT INTO ``posts_%s`` VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :thumb, :thumbwidth, :thumbheight, :file, :width, :height, :filesize, :filename, :filehash, :password, :ip, :sticky, :locked, 0, :embed)", $board['uri'])); // Basic stuff if (!empty($post['subject'])) { @@ -829,7 +829,7 @@ function bumpThread($id) { if (event('bump', $id)) return true; - $query = prepare(sprintf("UPDATE `posts_%s` SET `bump` = :time WHERE `id` = :id AND `thread` IS NULL", $board['uri'])); + $query = prepare(sprintf("UPDATE ``posts_%s`` SET `bump` = :time WHERE `id` = :id AND `thread` IS NULL", $board['uri'])); $query->bindValue(':time', time(), PDO::PARAM_INT); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -839,7 +839,7 @@ function bumpThread($id) { function deleteFile($id, $remove_entirely_if_already=true) { global $board, $config; - $query = prepare(sprintf("SELECT `thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `thread`,`thumb`,`file` FROM ``posts_%s`` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); if (!$post = $query->fetch(PDO::FETCH_ASSOC)) @@ -848,7 +848,7 @@ function deleteFile($id, $remove_entirely_if_already=true) { if ($post['file'] == 'deleted' && !$post['thread']) return; // Can't delete OP's image completely. - $query = prepare(sprintf("UPDATE `posts_%s` SET `thumb` = NULL, `thumbwidth` = NULL, `thumbheight` = NULL, `filewidth` = NULL, `fileheight` = NULL, `filesize` = NULL, `filename` = NULL, `filehash` = NULL, `file` = :file WHERE `id` = :id", $board['uri'])); + $query = prepare(sprintf("UPDATE ``posts_%s`` SET `thumb` = NULL, `thumbwidth` = NULL, `thumbheight` = NULL, `filewidth` = NULL, `fileheight` = NULL, `filesize` = NULL, `filename` = NULL, `filehash` = NULL, `file` = :file WHERE `id` = :id", $board['uri'])); if ($post['file'] == 'deleted' && $remove_entirely_if_already) { // Already deleted; remove file fully $query->bindValue(':file', null, PDO::PARAM_NULL); @@ -876,7 +876,7 @@ function deleteFile($id, $remove_entirely_if_already=true) { function rebuildPost($id) { global $board; - $query = prepare(sprintf("SELECT `body_nomarkup`, `thread` FROM `posts_%s` WHERE `id` = :id", $board['uri'])); + $query = prepare(sprintf("SELECT `body_nomarkup`, `thread` FROM ``posts_%s`` WHERE `id` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -885,7 +885,7 @@ function rebuildPost($id) { markup($body = &$post['body_nomarkup']); - $query = prepare(sprintf("UPDATE `posts_%s` SET `body` = :body WHERE `id` = :id", $board['uri'])); + $query = prepare(sprintf("UPDATE ``posts_%s`` SET `body` = :body WHERE `id` = :id", $board['uri'])); $query->bindValue(':body', $body); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -900,7 +900,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { global $board, $config; // Select post and replies (if thread) in one query - $query = prepare(sprintf("SELECT `id`,`thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id OR `thread` = :id", $board['uri'])); + $query = prepare(sprintf("SELECT `id`,`thread`,`thumb`,`file` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -918,7 +918,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { // Delete thread HTML page file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['id'])); - $antispam_query = prepare('DELETE FROM `antispam` WHERE `board` = :board AND `thread` = :thread'); + $antispam_query = prepare('DELETE FROM ``antispam`` WHERE `board` = :board AND `thread` = :thread'); $antispam_query->bindValue(':board', $board['uri']); $antispam_query->bindValue(':thread', $post['id']); $antispam_query->execute() or error(db_error($antispam_query)); @@ -939,11 +939,11 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { } - $query = prepare(sprintf("DELETE FROM `posts_%s` WHERE `id` = :id OR `thread` = :id", $board['uri'])); + $query = prepare(sprintf("DELETE FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board AND (`target` = " . implode(' OR `target` = ', $ids) . ")"); + $query = prepare("SELECT `board`, `post` FROM ``cites`` WHERE `target_board` = :board AND (`target` = " . implode(' OR `target` = ', $ids) . ")"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { @@ -958,7 +958,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { if (isset($tmp_board)) openBoard($tmp_board); - $query = prepare("DELETE FROM `cites` WHERE (`target_board` = :board AND `target` = :id) OR (`board` = :board AND `post` = :id)"); + $query = prepare("DELETE FROM ``cites`` WHERE (`target_board` = :board AND `target` = :id) OR (`board` = :board AND `post` = :id)"); $query->bindValue(':board', $board['uri']); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -975,7 +975,7 @@ function clean() { $offset = round($config['max_pages']*$config['threads_per_page']); // I too wish there was an easier way of doing this... - $query = prepare(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset, 9001", $board['uri'])); + $query = prepare(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset, 9001", $board['uri'])); $query->bindValue(':offset', $offset, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -990,7 +990,7 @@ function index($page, $mod=false) { $body = ''; $offset = round($page*$config['threads_per_page']-$config['threads_per_page']); - $query = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset,:threads_per_page", $board['uri'])); + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `sticky` DESC, `bump` DESC LIMIT :offset,:threads_per_page", $board['uri'])); $query->bindValue(':offset', $offset, PDO::PARAM_INT); $query->bindValue(':threads_per_page', $config['threads_per_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1011,7 +1011,7 @@ function index($page, $mod=false) { $replies = $cached['replies']; $omitted = $cached['omitted']; } else { - $posts = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $board['uri'])); + $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $board['uri'])); $posts->bindValue(':id', $th['id']); $posts->bindValue(':limit', ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); $posts->execute() or error(db_error($posts)); @@ -1115,7 +1115,7 @@ function getPages($mod=false) { $count = $board['thread_count']; } else { // Count threads - $query = query(sprintf("SELECT COUNT(*) FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); + $query = query(sprintf("SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); $count = $query->fetchColumn(); } $count = floor(($config['threads_per_page'] + $count - 1) / $config['threads_per_page']); @@ -1151,7 +1151,7 @@ function checkRobot($body) { return true; $body = makerobot($body); - $query = prepare("SELECT 1 FROM `robot` WHERE `hash` = :hash LIMIT 1"); + $query = prepare("SELECT 1 FROM ``robot`` WHERE `hash` = :hash LIMIT 1"); $query->bindValue(':hash', $body); $query->execute() or error(db_error($query)); @@ -1160,7 +1160,7 @@ function checkRobot($body) { } // Insert new hash - $query = prepare("INSERT INTO `robot` VALUES (:hash)"); + $query = prepare("INSERT INTO ``robot`` VALUES (:hash)"); $query->bindValue(':hash', $body); $query->execute() or error(db_error($query)); @@ -1170,7 +1170,7 @@ function checkRobot($body) { // Returns an associative array with 'replies' and 'images' keys function numPosts($id) { global $board; - $query = prepare(sprintf("SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); + $query = prepare(sprintf("SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM ``posts_%s`` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); $query->bindValue(':thread', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1187,7 +1187,7 @@ function muteTime() { return $time; // Find number of mutes in the past X hours - $query = prepare("SELECT COUNT(*) FROM `mutes` WHERE `time` >= :time AND `ip` = :ip"); + $query = prepare("SELECT COUNT(*) FROM ``mutes`` WHERE `time` >= :time AND `ip` = :ip"); $query->bindValue(':time', time()-($config['robot_mute_hour']*3600), PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->execute() or error(db_error($query)); @@ -1199,7 +1199,7 @@ function muteTime() { function mute() { // Insert mute - $query = prepare("INSERT INTO `mutes` VALUES (:ip, :time)"); + $query = prepare("INSERT INTO ``mutes`` VALUES (:ip, :time)"); $query->bindValue(':time', time(), PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->execute() or error(db_error($query)); @@ -1220,7 +1220,7 @@ function checkMute() { $mutetime = muteTime(); if ($mutetime > 0) { // Find last mute time - $query = prepare("SELECT `time` FROM `mutes` WHERE `ip` = :ip ORDER BY `time` DESC LIMIT 1"); + $query = prepare("SELECT `time` FROM ``mutes`` WHERE `ip` = :ip ORDER BY `time` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->execute() or error(db_error($query)); @@ -1514,7 +1514,7 @@ function markup(&$body, $track_cites = false) { foreach ($cites as $matches) { $cite = $matches[2][0]; - $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `thread`,`id` FROM ``posts_%s`` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); @@ -1562,7 +1562,7 @@ function markup(&$body, $track_cites = false) { // Check if the board exists, and load settings if (openBoard($_board)) { if ($cite) { - $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `thread`,`id` FROM ``posts_%s`` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); @@ -1671,7 +1671,7 @@ function buildThread($id, $return = false, $mod = false) { cache::delete("thread_{$board['uri']}_{$id}"); } - $query = prepare(sprintf("SELECT * FROM `posts_%s` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1806,7 +1806,7 @@ function fraction($numerator, $denominator, $sep) { function getPostByHash($hash) { global $board; - $query = prepare(sprintf("SELECT `id`,`thread` FROM `posts_%s` WHERE `filehash` = :hash", $board['uri'])); + $query = prepare(sprintf("SELECT `id`,`thread` FROM ``posts_%s`` WHERE `filehash` = :hash", $board['uri'])); $query->bindValue(':hash', $hash, PDO::PARAM_STR); $query->execute() or error(db_error($query)); @@ -1819,7 +1819,7 @@ function getPostByHash($hash) { function getPostByHashInThread($hash, $thread) { global $board; - $query = prepare(sprintf("SELECT `id`,`thread` FROM `posts_%s` WHERE `filehash` = :hash AND ( `thread` = :thread OR `id` = :thread )", $board['uri'])); + $query = prepare(sprintf("SELECT `id`,`thread` FROM ``posts_%s`` WHERE `filehash` = :hash AND ( `thread` = :thread OR `id` = :thread )", $board['uri'])); $query->bindValue(':hash', $hash, PDO::PARAM_STR); $query->bindValue(':thread', $thread, PDO::PARAM_INT); $query->execute() or error(db_error($query)); diff --git a/inc/mod/auth.php b/inc/mod/auth.php index a0986a1f..bfab0f7e 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -42,7 +42,7 @@ function login($username, $password, $makehash=true) { $password = sha1($password); } - $query = prepare("SELECT `id`, `type`, `boards`, `password`, `salt` FROM `mods` WHERE `username` = :username"); + $query = prepare("SELECT `id`, `type`, `boards`, `password`, `salt` FROM ``mods`` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); @@ -83,7 +83,7 @@ function destroyCookies() { function modLog($action, $_board=null) { global $mod, $board, $config; - $query = prepare("INSERT INTO `modlogs` VALUES (:id, :ip, :board, :time, :text)"); + $query = prepare("INSERT INTO ``modlogs`` VALUES (:id, :ip, :board, :time, :text)"); $query->bindValue(':id', $mod['id'], PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':time', time(), PDO::PARAM_INT); @@ -112,7 +112,7 @@ if (isset($_COOKIE[$config['cookies']['mod']])) { exit; } - $query = prepare("SELECT `id`, `type`, `boards`, `password` FROM `mods` WHERE `username` = :username"); + $query = prepare("SELECT `id`, `type`, `boards`, `password` FROM ``mods`` WHERE `username` = :username"); $query->bindValue(':username', $cookie[0]); $query->execute() or error(db_error($query)); $user = $query->fetch(PDO::FETCH_ASSOC); @@ -143,7 +143,7 @@ function create_pm_header() { return $header; } - $query = prepare("SELECT `id` FROM `pms` WHERE `to` = :id AND `unread` = 1"); + $query = prepare("SELECT `id` FROM ``pms`` WHERE `to` = :id AND `unread` = 1"); $query->bindValue(':id', $mod['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); diff --git a/inc/mod/ban.php b/inc/mod/ban.php index cfc2636f..9166223f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -56,7 +56,7 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod, $pdo; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board, 0)"); + $query = prepare("INSERT INTO ``bans`` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board, 0)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); @@ -89,12 +89,12 @@ function ban($mask, $reason, $length, $board) { } function unban($id) { - $query = prepare("SELECT `ip` FROM `bans` WHERE `id` = :id"); + $query = prepare("SELECT `ip` FROM ``bans`` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); $mask = $query->fetchColumn(); - $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); + $query = prepare("DELETE FROM ``bans`` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 3ff6a9b1..1e0dc7c9 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -82,7 +82,7 @@ function mod_dashboard() { if (hasPermission($config['mod']['noticeboard'])) { if (!$config['cache']['enabled'] || !$args['noticeboard'] = cache::get('noticeboard_preview')) { - $query = prepare("SELECT `noticeboard`.*, `username` FROM `noticeboard` LEFT JOIN `mods` ON `mods`.`id` = `mod` ORDER BY `id` DESC LIMIT :limit"); + $query = prepare("SELECT ``noticeboard``.*, `username` FROM ``noticeboard`` LEFT JOIN ``mods`` ON ``mods``.`id` = `mod` ORDER BY `id` DESC LIMIT :limit"); $query->bindValue(':limit', $config['mod']['noticeboard_dashboard'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $args['noticeboard'] = $query->fetchAll(PDO::FETCH_ASSOC); @@ -93,7 +93,7 @@ function mod_dashboard() { } if (!$config['cache']['enabled'] || ($args['unread_pms'] = cache::get('pm_unreadcount_' . $mod['id'])) == false) { - $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :id AND `unread` = 1'); + $query = prepare('SELECT COUNT(*) FROM ``pms`` WHERE `to` = :id AND `unread` = 1'); $query->bindValue(':id', $mod['id']); $query->execute() or error(db_error($query)); $args['unread_pms'] = $query->fetchColumn(); @@ -102,7 +102,7 @@ function mod_dashboard() { cache::set('pm_unreadcount_' . $mod['id'], $args['unread_pms']); } - $query = query('SELECT COUNT(*) FROM `reports`') or error(db_error($query)); + $query = query('SELECT COUNT(*) FROM ``reports``') or error(db_error($query)); $args['reports'] = $query->fetchColumn(); if ($mod['type'] >= ADMIN && $config['check_updates']) { @@ -208,6 +208,8 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // Use asterisk as wildcard instead $query = str_replace('*', '%', $query); + $query = str_replace('`', '!`', $query); + // Array of phrases to match $match = array(); @@ -271,7 +273,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { if (!empty($query)) $query .= ' UNION ALL '; - $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE %s", $board['uri'], $board['uri'], $sql_like); + $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE %s", $board['uri'], $board['uri'], $sql_like); } // You weren't allowed to search any boards @@ -282,21 +284,21 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { } if ($type == 'IP_notes') { - $query = 'SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; + $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'; + $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'; + $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']); @@ -353,7 +355,7 @@ function mod_edit_board($boardName) { if (!hasPermission($config['mod']['manageboards'], $board['uri'])) error($config['error']['deleteboard']); - $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query = prepare('DELETE FROM ``boards`` WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); $query->execute() or error(db_error($query)); @@ -363,19 +365,19 @@ function mod_edit_board($boardName) { rrmdir($board['uri'] . '/'); // Delete posting table - $query = query(sprintf('DROP TABLE IF EXISTS `posts_%s`', $board['uri'])) or error(db_error()); + $query = query(sprintf('DROP TABLE IF EXISTS ``posts_%s``', $board['uri'])) or error(db_error()); // Clear reports - $query = prepare('DELETE FROM `reports` WHERE `board` = :id'); + $query = prepare('DELETE FROM ``reports`` WHERE `board` = :id'); $query->bindValue(':id', $board['uri'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); // Delete from table - $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query = prepare('DELETE FROM ``boards`` WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board"); + $query = prepare("SELECT `board`, `post` FROM ``cites`` WHERE `target_board` = :board"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { @@ -387,28 +389,28 @@ function mod_edit_board($boardName) { } } - $query = prepare('DELETE FROM `cites` WHERE `board` = :board OR `target_board` = :board'); + $query = prepare('DELETE FROM ``cites`` WHERE `board` = :board OR `target_board` = :board'); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); - $query = prepare('DELETE FROM `antispam` WHERE `board` = :board'); + $query = prepare('DELETE FROM ``antispam`` WHERE `board` = :board'); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); // Remove board from users/permissions table - $query = query('SELECT `id`,`boards` FROM `mods`') or error(db_error()); + $query = query('SELECT `id`,`boards` FROM ``mods``') or error(db_error()); while ($user = $query->fetch(PDO::FETCH_ASSOC)) { $user_boards = explode(',', $user['boards']); if (in_array($board['uri'], $user_boards)) { unset($user_boards[array_search($board['uri'], $user_boards)]); - $_query = prepare('UPDATE `mods` SET `boards` = :boards WHERE `id` = :id'); + $_query = prepare('UPDATE ``mods`` SET `boards` = :boards WHERE `id` = :id'); $_query->bindValue(':boards', implode(',', $user_boards)); $_query->bindValue(':id', $user['id']); $_query->execute() or error(db_error($_query)); } } } else { - $query = prepare('UPDATE `boards` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); + $query = prepare('UPDATE ``boards`` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); $query->bindValue(':title', $_POST['title']); $query->bindValue(':subtitle', $_POST['subtitle']); @@ -467,7 +469,7 @@ function mod_new_board() { error(sprintf($config['error']['boardexists'], $board['url'])); } - $query = prepare('INSERT INTO `boards` VALUES (:uri, :title, :subtitle)'); + $query = prepare('INSERT INTO ``boards`` VALUES (:uri, :title, :subtitle)'); $query->bindValue(':uri', $_POST['uri']); $query->bindValue(':title', $_POST['title']); $query->bindValue(':subtitle', $_POST['subtitle']); @@ -510,7 +512,7 @@ function mod_noticeboard($page_no = 1) { $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); - $query = prepare('INSERT INTO `noticeboard` VALUES (NULL, :mod, :time, :subject, :body)'); + $query = prepare('INSERT INTO ``noticeboard`` VALUES (NULL, :mod, :time, :subject, :body)'); $query->bindValue(':mod', $mod['id']); $query->bindvalue(':time', time()); $query->bindValue(':subject', $_POST['subject']); @@ -525,7 +527,7 @@ function mod_noticeboard($page_no = 1) { header('Location: ?/noticeboard#' . $pdo->lastInsertId(), true, $config['redirect_http']); } - $query = prepare("SELECT `noticeboard`.*, `username` FROM `noticeboard` LEFT JOIN `mods` ON `mods`.`id` = `mod` ORDER BY `id` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT ``noticeboard``.*, `username` FROM ``noticeboard`` LEFT JOIN ``mods`` ON ``mods``.`id` = `mod` ORDER BY `id` DESC LIMIT :offset, :limit"); $query->bindValue(':limit', $config['mod']['noticeboard_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['noticeboard_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -534,7 +536,7 @@ function mod_noticeboard($page_no = 1) { if (empty($noticeboard) && $page_no > 1) error($config['error']['404']); - $query = prepare("SELECT COUNT(*) FROM `noticeboard`"); + $query = prepare("SELECT COUNT(*) FROM ``noticeboard``"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); @@ -547,7 +549,7 @@ function mod_noticeboard_delete($id) { if (!hasPermission($config['mod']['noticeboard_delete'])) error($config['error']['noaccess']); - $query = prepare('DELETE FROM `noticeboard` WHERE `id` = :id'); + $query = prepare('DELETE FROM ``noticeboard`` WHERE `id` = :id'); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -572,7 +574,7 @@ function mod_news($page_no = 1) { $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); - $query = prepare('INSERT INTO `news` VALUES (NULL, :name, :time, :subject, :body)'); + $query = prepare('INSERT INTO ``news`` VALUES (NULL, :name, :time, :subject, :body)'); $query->bindValue(':name', isset($_POST['name']) && hasPermission($config['mod']['news_custom']) ? $_POST['name'] : $mod['username']); $query->bindvalue(':time', time()); $query->bindValue(':subject', $_POST['subject']); @@ -586,7 +588,7 @@ function mod_news($page_no = 1) { header('Location: ?/news#' . $pdo->lastInsertId(), true, $config['redirect_http']); } - $query = prepare("SELECT * FROM `news` ORDER BY `id` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT * FROM ``news`` ORDER BY `id` DESC LIMIT :offset, :limit"); $query->bindValue(':limit', $config['mod']['news_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['news_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -595,7 +597,7 @@ function mod_news($page_no = 1) { if (empty($news) && $page_no > 1) error($config['error']['404']); - $query = prepare("SELECT COUNT(*) FROM `news`"); + $query = prepare("SELECT COUNT(*) FROM ``news``"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); @@ -608,7 +610,7 @@ function mod_news_delete($id) { if (!hasPermission($config['mod']['news_delete'])) error($config['error']['noaccess']); - $query = prepare('DELETE FROM `news` WHERE `id` = :id'); + $query = prepare('DELETE FROM ``news`` WHERE `id` = :id'); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -626,7 +628,7 @@ function mod_log($page_no = 1) { if (!hasPermission($config['mod']['modlog'])) error($config['error']['noaccess']); - $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -635,7 +637,7 @@ function mod_log($page_no = 1) { if (empty($logs) && $page_no > 1) error($config['error']['404']); - $query = prepare("SELECT COUNT(*) FROM `modlogs`"); + $query = prepare("SELECT COUNT(*) FROM ``modlogs``"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); @@ -651,7 +653,7 @@ function mod_user_log($username, $page_no = 1) { if (!hasPermission($config['mod']['modlog'])) error($config['error']['noaccess']); - $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `username` = :username ORDER BY `time` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `username` = :username ORDER BY `time` DESC LIMIT :offset, :limit"); $query->bindValue(':username', $username); $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); @@ -661,7 +663,7 @@ function mod_user_log($username, $page_no = 1) { if (empty($logs) && $page_no > 1) error($config['error']['404']); - $query = prepare("SELECT COUNT(*) FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `username` = :username"); + $query = prepare("SELECT COUNT(*) FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); @@ -707,7 +709,7 @@ function mod_ip_remove_note($ip, $id) { if (filter_var($ip, FILTER_VALIDATE_IP) === false) error("Invalid IP address."); - $query = prepare('DELETE FROM `ip_notes` WHERE `ip` = :ip AND `id` = :id'); + $query = prepare('DELETE FROM ``ip_notes`` WHERE `ip` = :ip AND `id` = :id'); $query->bindValue(':ip', $ip); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -741,7 +743,7 @@ function mod_page_ip($ip) { $_POST['note'] = escape_markup_modifiers($_POST['note']); markup($_POST['note']); - $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); + $query = prepare('INSERT INTO ``ip_notes`` VALUES (NULL, :ip, :mod, :time, :body)'); $query->bindValue(':ip', $ip); $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); @@ -766,7 +768,7 @@ function mod_page_ip($ip) { openBoard($board['uri']); if (!hasPermission($config['mod']['show_ip'], $board['uri'])) continue; - $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri'])); + $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri'])); $query->bindValue(':ip', $ip); $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -798,21 +800,21 @@ function mod_page_ip($ip) { $args['token'] = make_secure_link_token('ban'); if (hasPermission($config['mod']['view_ban'])) { - $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query = prepare("SELECT ``bans``.*, `username` FROM ``bans`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `ip` = :ip"); $query->bindValue(':ip', $ip); $query->execute() or error(db_error($query)); $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); } if (hasPermission($config['mod']['view_notes'])) { - $query = prepare("SELECT `ip_notes`.*, `username` FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query = prepare("SELECT ``ip_notes``.*, `username` FROM ``ip_notes`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `ip` = :ip"); $query->bindValue(':ip', $ip); $query->execute() or error(db_error($query)); $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); } if (hasPermission($config['mod']['modlog_ip'])) { - $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `text` LIKE :search ORDER BY `time` DESC LIMIT 20"); + $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `text` LIKE :search ORDER BY `time` DESC LIMIT 20"); $query->bindValue(':search', '%' . $ip . '%'); $query->execute() or error(db_error($query)); $args['logs'] = $query->fetchAll(PDO::FETCH_ASSOC); @@ -865,7 +867,7 @@ function mod_bans($page_no = 1) { if (isset($config['mod']['unban_limit'])){ if (count($unban) <= $config['mod']['unban_limit'] || $config['mod']['unban_limit'] == -1){ if (!empty($unban)) { - query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); + query('DELETE FROM ``bans`` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); foreach ($unban as $id) { modLog("Removed ban #{$id}"); @@ -878,7 +880,7 @@ function mod_bans($page_no = 1) { } else { if (!empty($unban)) { - query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); + query('DELETE FROM ``bans`` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); foreach ($unban as $id) { modLog("Removed ban #{$id}"); @@ -890,10 +892,10 @@ function mod_bans($page_no = 1) { } if ($config['mod']['view_banexpired']) { - $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY (`expires` IS NOT NULL AND `expires` < :time), `set` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT ``bans``.*, `username` FROM ``bans`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` ORDER BY (`expires` IS NOT NULL AND `expires` < :time), `set` DESC LIMIT :offset, :limit"); } else { // Filter out expired bans - $query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT ``bans``.*, `username` FROM ``bans`` INNER JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC LIMIT :offset, :limit"); } $query->bindValue(':time', time(), PDO::PARAM_INT); $query->bindValue(':limit', $config['mod']['banlist_page'], PDO::PARAM_INT); @@ -904,7 +906,7 @@ function mod_bans($page_no = 1) { if (empty($bans) && $page_no > 1) error($config['error']['404']); - $query = prepare("SELECT COUNT(*) FROM `bans`"); + $query = prepare("SELECT COUNT(*) FROM ``bans``"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); @@ -926,7 +928,7 @@ function mod_lock($board, $unlock, $post) { if (!hasPermission($config['mod']['lock'], $board)) error($config['error']['noaccess']); - $query = prepare(sprintf('UPDATE `posts_%s` SET `locked` = :locked WHERE `id` = :id AND `thread` IS NULL', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `locked` = :locked WHERE `id` = :id AND `thread` IS NULL', $board)); $query->bindValue(':id', $post); $query->bindValue(':locked', $unlock ? 0 : 1); $query->execute() or error(db_error($query)); @@ -937,7 +939,7 @@ function mod_lock($board, $unlock, $post) { } if ($config['mod']['dismiss_reports_on_lock']) { - $query = prepare('DELETE FROM `reports` WHERE `board` = :board AND `post` = :id'); + $query = prepare('DELETE FROM ``reports`` WHERE `board` = :board AND `post` = :id'); $query->bindValue(':board', $board); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); @@ -960,7 +962,7 @@ function mod_sticky($board, $unsticky, $post) { if (!hasPermission($config['mod']['sticky'], $board)) error($config['error']['noaccess']); - $query = prepare(sprintf('UPDATE `posts_%s` SET `sticky` = :sticky WHERE `id` = :id AND `thread` IS NULL', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `sticky` = :sticky WHERE `id` = :id AND `thread` IS NULL', $board)); $query->bindValue(':id', $post); $query->bindValue(':sticky', $unsticky ? 0 : 1); $query->execute() or error(db_error($query)); @@ -982,7 +984,7 @@ function mod_bumplock($board, $unbumplock, $post) { if (!hasPermission($config['mod']['bumplock'], $board)) error($config['error']['noaccess']); - $query = prepare(sprintf('UPDATE `posts_%s` SET `sage` = :bumplock WHERE `id` = :id AND `thread` IS NULL', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `sage` = :bumplock WHERE `id` = :id AND `thread` IS NULL', $board)); $query->bindValue(':id', $post); $query->bindValue(':bumplock', $unbumplock ? 0 : 1); $query->execute() or error(db_error($query)); @@ -1004,7 +1006,7 @@ function mod_move($originBoard, $postID) { if (!hasPermission($config['mod']['move'], $originBoard)) error($config['error']['noaccess']); - $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL', $originBoard)); + $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL', $originBoard)); $query->bindValue(':id', $postID); $query->execute() or error(db_error($query)); if (!$post = $query->fetch(PDO::FETCH_ASSOC)) @@ -1052,7 +1054,7 @@ function mod_move($originBoard, $postID) { // go back to the original board to fetch replies openBoard($originBoard); - $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id`', $originBoard)); + $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id`', $originBoard)); $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1081,7 +1083,7 @@ function mod_move($originBoard, $postID) { openBoard($targetBoard); foreach ($replies as &$post) { - $query = prepare('SELECT `target` FROM `cites` WHERE `target_board` = :board AND `board` = :board AND `post` = :post'); + $query = prepare('SELECT `target` FROM ``cites`` WHERE `target_board` = :board AND `board` = :board AND `post` = :post'); $query->bindValue(':board', $originBoard); $query->bindValue(':post', $post['id'], PDO::PARAM_INT); $query->execute() or error(db_error($qurey)); @@ -1113,7 +1115,7 @@ function mod_move($originBoard, $postID) { } foreach ($post['tracked_cites'] as $cite) { - $query = prepare('INSERT INTO `cites` VALUES (:board, :post, :target_board, :target)'); + $query = prepare('INSERT INTO ``cites`` VALUES (:board, :post, :target_board, :target)'); $query->bindValue(':board', $board['uri']); $query->bindValue(':post', $newPostID, PDO::PARAM_INT); $query->bindValue(':target_board',$cite[0]); @@ -1138,7 +1140,7 @@ function mod_move($originBoard, $postID) { if ($shadow) { // lock old thread - $query = prepare(sprintf('UPDATE `posts_%s` SET `locked` = 1 WHERE `id` = :id', $originBoard)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `locked` = 1 WHERE `id` = :id', $originBoard)); $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1197,7 +1199,7 @@ function mod_ban_post($board, $delete, $post, $token = false) { $security_token = make_secure_link_token($board . '/ban/' . $post); - $query = prepare(sprintf('SELECT `ip`, `thread` FROM `posts_%s` WHERE `id` = :id', $board)); + $query = prepare(sprintf('SELECT `ip`, `thread` FROM ``posts_%s`` WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); if (!$_post = $query->fetch(PDO::FETCH_ASSOC)) @@ -1220,7 +1222,7 @@ function mod_ban_post($board, $delete, $post, $token = false) { $_POST['message'] = preg_replace('/[\r\n]/', '', $_POST['message']); $_POST['message'] = str_replace('%length%', $length_english, $_POST['message']); $_POST['message'] = str_replace('%LENGTH%', strtoupper($length_english), $_POST['message']); - $query = prepare(sprintf('UPDATE `posts_%s` SET `body_nomarkup` = CONCAT(`body_nomarkup`, :body_nomarkup) WHERE `id` = :id', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `body_nomarkup` = CONCAT(`body_nomarkup`, :body_nomarkup) WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->bindValue(':body_nomarkup', sprintf("\n%s", utf8tohtml($_POST['message']))); $query->execute() or error(db_error($query)); @@ -1267,7 +1269,7 @@ function mod_edit_post($board, $edit_raw_html, $postID) { $security_token = make_secure_link_token($board . '/edit' . ($edit_raw_html ? '_raw' : '') . '/' . $postID); - $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `id` = :id', $board)); + $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id', $board)); $query->bindValue(':id', $postID); $query->execute() or error(db_error($query)); @@ -1276,9 +1278,9 @@ function mod_edit_post($board, $edit_raw_html, $postID) { if (isset($_POST['name'], $_POST['email'], $_POST['subject'], $_POST['body'])) { if ($edit_raw_html) - $query = prepare(sprintf('UPDATE `posts_%s` SET `name` = :name, `email` = :email, `subject` = :subject, `body` = :body, `body_nomarkup` = :body_nomarkup WHERE `id` = :id', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body` = :body, `body_nomarkup` = :body_nomarkup WHERE `id` = :id', $board)); else - $query = prepare(sprintf('UPDATE `posts_%s` SET `name` = :name, `email` = :email, `subject` = :subject, `body_nomarkup` = :body WHERE `id` = :id', $board)); + $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body_nomarkup` = :body WHERE `id` = :id', $board)); $query->bindValue(':id', $postID); $query->bindValue('name', $_POST['name']); $query->bindValue(':email', $_POST['email']); @@ -1369,7 +1371,7 @@ function mod_deletebyip($boardName, $post, $global = false) { error($config['error']['noaccess']); // Find IP address - $query = prepare(sprintf('SELECT `ip` FROM `posts_%s` WHERE `id` = :id', $boardName)); + $query = prepare(sprintf('SELECT `ip` FROM ``posts_%s`` WHERE `id` = :id', $boardName)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); if (!$ip = $query->fetchColumn()) @@ -1379,7 +1381,7 @@ function mod_deletebyip($boardName, $post, $global = false) { $query = ''; foreach ($boards as $_board) { - $query .= sprintf("SELECT `thread`, `id`, '%s' AS `board` FROM `posts_%s` WHERE `ip` = :ip UNION ALL ", $_board['uri'], $_board['uri']); + $query .= sprintf("SELECT `thread`, `id`, '%s' AS `board` FROM ``posts_%s`` WHERE `ip` = :ip UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', '', $query); @@ -1431,7 +1433,7 @@ function mod_user($uid) { if (!hasPermission($config['mod']['editusers']) && !(hasPermission($config['mod']['change_password']) && $uid == $mod['id'])) error($config['error']['noaccess']); - $query = prepare('SELECT * FROM `mods` WHERE `id` = :id'); + $query = prepare('SELECT * FROM ``mods`` WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); if (!$user = $query->fetch(PDO::FETCH_ASSOC)) @@ -1457,7 +1459,7 @@ function mod_user($uid) { if (!hasPermission($config['mod']['deleteusers'])) error($config['error']['noaccess']); - $query = prepare('DELETE FROM `mods` WHERE `id` = :id'); + $query = prepare('DELETE FROM ``mods`` WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); @@ -1471,7 +1473,7 @@ function mod_user($uid) { if ($_POST['username'] == '') error(sprintf($config['error']['required'], 'username')); - $query = prepare('UPDATE `mods` SET `username` = :username, `boards` = :boards WHERE `id` = :id'); + $query = prepare('UPDATE ``mods`` SET `username` = :username, `boards` = :boards WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':username', $_POST['username']); $query->bindValue(':boards', implode(',', $boards)); @@ -1486,7 +1488,7 @@ function mod_user($uid) { $salt = generate_salt(); $password = hash('sha256', $salt . sha1($_POST['password'])); - $query = prepare('UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); + $query = prepare('UPDATE ``mods`` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':password', $password); $query->bindValue(':salt', $salt); @@ -1513,7 +1515,7 @@ function mod_user($uid) { $salt = generate_salt(); $password = hash('sha256', $salt . sha1($_POST['password'])); - $query = prepare('UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); + $query = prepare('UPDATE ``mods`` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':password', $password); $query->bindValue(':salt', $salt); @@ -1534,7 +1536,7 @@ function mod_user($uid) { } if (hasPermission($config['mod']['modlog'])) { - $query = prepare('SELECT * FROM `modlogs` WHERE `mod` = :id ORDER BY `time` DESC LIMIT 5'); + $query = prepare('SELECT * FROM ``modlogs`` WHERE `mod` = :id ORDER BY `time` DESC LIMIT 5'); $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); $log = $query->fetchAll(PDO::FETCH_ASSOC); @@ -1581,7 +1583,7 @@ function mod_user_new() { $salt = generate_salt(); $password = hash('sha256', $salt . sha1($_POST['password'])); - $query = prepare('INSERT INTO `mods` VALUES (NULL, :username, :password, :salt, :type, :boards)'); + $query = prepare('INSERT INTO ``mods`` VALUES (NULL, :username, :password, :salt, :type, :boards)'); $query->bindValue(':username', $_POST['username']); $query->bindValue(':password', $password); $query->bindValue(':salt', $salt); @@ -1607,7 +1609,7 @@ function mod_users() { if (!hasPermission($config['mod']['manageusers'])) error($config['error']['noaccess']); - $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); + $query = query("SELECT *, (SELECT `time` FROM ``modlogs`` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM ``modlogs`` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM ``mods`` ORDER BY `type` DESC,`id`") or error(db_error()); $users = $query->fetchAll(PDO::FETCH_ASSOC); mod_page(sprintf('%s (%d)', _('Manage users'), count($users)), 'mod/users.html', array('users' => $users)); @@ -1619,7 +1621,7 @@ function mod_user_promote($uid, $action) { if (!hasPermission($config['mod']['promoteusers'])) error($config['error']['noaccess']); - $query = prepare("UPDATE `mods` SET `type` = `type` " . ($action == 'promote' ? "+1 WHERE `type` < " . (int)ADMIN : "-1 WHERE `type` > " . (int)JANITOR) . " AND `id` = :id"); + $query = prepare("UPDATE ``mods`` SET `type` = `type` " . ($action == 'promote' ? "+1 WHERE `type` < " . (int)ADMIN : "-1 WHERE `type` > " . (int)JANITOR) . " AND `id` = :id"); $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); @@ -1634,7 +1636,7 @@ function mod_pm($id, $reply = false) { if ($reply && !hasPermission($config['mod']['create_pm'])) error($config['error']['noaccess']); - $query = prepare("SELECT `mods`.`username`, `mods_to`.`username` AS `to_username`, `pms`.* FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` LEFT JOIN `mods` AS `mods_to` ON `mods_to`.`id` = `to` WHERE `pms`.`id` = :id"); + $query = prepare("SELECT ``mods``.`username`, `mods_to`.`username` AS `to_username`, ``pms``.* FROM ``pms`` LEFT JOIN ``mods`` ON ``mods``.`id` = `sender` LEFT JOIN ``mods`` AS `mods_to` ON `mods_to`.`id` = `to` WHERE ``pms``.`id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -1642,7 +1644,7 @@ function mod_pm($id, $reply = false) { error($config['error']['404']); if (isset($_POST['delete'])) { - $query = prepare("DELETE FROM `pms` WHERE `id` = :id"); + $query = prepare("DELETE FROM ``pms`` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -1656,7 +1658,7 @@ function mod_pm($id, $reply = false) { } if ($pm['unread'] && $pm['to'] == $mod['id']) { - $query = prepare("UPDATE `pms` SET `unread` = 0 WHERE `id` = :id"); + $query = prepare("UPDATE ``pms`` SET `unread` = 0 WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); @@ -1683,12 +1685,12 @@ function mod_pm($id, $reply = false) { function mod_inbox() { global $config, $mod; - $query = prepare('SELECT `unread`,`pms`.`id`, `time`, `sender`, `to`, `message`, `username` FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` WHERE `to` = :mod ORDER BY `unread` DESC, `time` DESC'); + $query = prepare('SELECT `unread`,``pms``.`id`, `time`, `sender`, `to`, `message`, `username` FROM ``pms`` LEFT JOIN ``mods`` ON ``mods``.`id` = `sender` WHERE `to` = :mod ORDER BY `unread` DESC, `time` DESC'); $query->bindValue(':mod', $mod['id']); $query->execute() or error(db_error($query)); $messages = $query->fetchAll(PDO::FETCH_ASSOC); - $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :mod AND `unread` = 1'); + $query = prepare('SELECT COUNT(*) FROM ``pms`` WHERE `to` = :mod AND `unread` = 1'); $query->bindValue(':mod', $mod['id']); $query->execute() or error(db_error($query)); $unread = $query->fetchColumn(); @@ -1710,12 +1712,12 @@ function mod_new_pm($username) { if (!hasPermission($config['mod']['create_pm'])) error($config['error']['noaccess']); - $query = prepare("SELECT `id` FROM `mods` WHERE `username` = :username"); + $query = prepare("SELECT `id` FROM ``mods`` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); if (!$id = $query->fetchColumn()) { // Old style ?/PM: by user ID - $query = prepare("SELECT `username` FROM `mods` WHERE `id` = :username"); + $query = prepare("SELECT `username` FROM ``mods`` WHERE `id` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); if ($username = $query->fetchColumn()) @@ -1728,7 +1730,7 @@ function mod_new_pm($username) { $_POST['message'] = escape_markup_modifiers($_POST['message']); markup($_POST['message']); - $query = prepare("INSERT INTO `pms` VALUES (NULL, :me, :id, :message, :time, 1)"); + $query = prepare("INSERT INTO ``pms`` VALUES (NULL, :me, :id, :message, :time, 1)"); $query->bindValue(':me', $mod['id']); $query->bindValue(':id', $id); $query->bindValue(':message', $_POST['message']); @@ -1801,7 +1803,7 @@ function mod_rebuild() { } if (isset($_POST['rebuild_thread'])) { - $query = query(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); + $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Rebuilding thread #' . $post['id']; buildThread($post['id']); @@ -1822,7 +1824,7 @@ function mod_reports() { if (!hasPermission($config['mod']['reports'])) error($config['error']['noaccess']); - $query = prepare("SELECT * FROM `reports` ORDER BY `time` DESC LIMIT :limit"); + $query = prepare("SELECT * FROM ``reports`` ORDER BY `time` DESC LIMIT :limit"); $query->bindValue(':limit', $config['mod']['recent_reports'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $reports = $query->fetchAll(PDO::FETCH_ASSOC); @@ -1838,7 +1840,7 @@ function mod_reports() { foreach ($report_queries as $board => $posts) { $report_posts[$board] = array(); - $query = query(sprintf('SELECT * FROM `posts_%s` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error()); + $query = query(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $report_posts[$board][$post['id']] = $post; } @@ -1849,7 +1851,7 @@ function mod_reports() { foreach ($reports as $report) { if (!isset($report_posts[$report['board']][$report['post']])) { // // Invalid report (post has since been deleted) - $query = prepare("DELETE FROM `reports` WHERE `post` = :id AND `board` = :board"); + $query = prepare("DELETE FROM ``reports`` WHERE `post` = :id AND `board` = :board"); $query->bindValue(':id', $report['post'], PDO::PARAM_INT); $query->bindValue(':board', $report['board']); $query->execute() or error(db_error($query)); @@ -1905,7 +1907,7 @@ function mod_reports() { function mod_report_dismiss($id, $all = false) { global $config; - $query = prepare("SELECT `post`, `board`, `ip` FROM `reports` WHERE `id` = :id"); + $query = prepare("SELECT `post`, `board`, `ip` FROM ``reports`` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); if ($report = $query->fetch(PDO::FETCH_ASSOC)) { @@ -1922,10 +1924,10 @@ function mod_report_dismiss($id, $all = false) { error($config['error']['noaccess']); if ($all) { - $query = prepare("DELETE FROM `reports` WHERE `ip` = :ip"); + $query = prepare("DELETE FROM ``reports`` WHERE `ip` = :ip"); $query->bindValue(':ip', $ip); } else { - $query = prepare("DELETE FROM `reports` WHERE `id` = :id"); + $query = prepare("DELETE FROM ``reports`` WHERE `id` = :id"); $query->bindValue(':id', $id); } $query->execute() or error(db_error($query)); @@ -2035,7 +2037,7 @@ function mod_themes_list() { if (!$dir = opendir($config['dir']['themes'])) error(_('Cannot open themes directory; check permissions.')); - $query = query('SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL') or error(db_error()); + $query = query('SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL') or error(db_error()); $themes_in_use = $query->fetchAll(PDO::FETCH_COLUMN); // Scan directory for themes @@ -2071,19 +2073,19 @@ function mod_theme_configure($theme_name) { } // Clear previous settings - $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query = prepare("DELETE FROM ``theme_settings`` WHERE `theme` = :theme"); $query->bindValue(':theme', $theme_name); $query->execute() or error(db_error($query)); foreach ($theme['config'] as &$conf) { - $query = prepare("INSERT INTO `theme_settings` VALUES(:theme, :name, :value)"); + $query = prepare("INSERT INTO ``theme_settings`` VALUES(:theme, :name, :value)"); $query->bindValue(':theme', $theme_name); $query->bindValue(':name', $conf['name']); $query->bindValue(':value', $_POST[$conf['name']]); $query->execute() or error(db_error($query)); } - $query = prepare("INSERT INTO `theme_settings` VALUES(:theme, NULL, NULL)"); + $query = prepare("INSERT INTO ``theme_settings`` VALUES(:theme, NULL, NULL)"); $query->bindValue(':theme', $theme_name); $query->execute() or error(db_error($query)); @@ -2101,7 +2103,7 @@ function mod_theme_configure($theme_name) { if (!$result) { // Install failed - $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query = prepare("DELETE FROM ``theme_settings`` WHERE `theme` = :theme"); $query->bindValue(':theme', $theme_name); $query->execute() or error(db_error($query)); } @@ -2133,7 +2135,7 @@ function mod_theme_uninstall($theme_name) { if (!hasPermission($config['mod']['themes'])) error($config['error']['noaccess']); - $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query = prepare("DELETE FROM ``theme_settings`` WHERE `theme` = :theme"); $query->bindValue(':theme', $theme_name); $query->execute() or error(db_error($query)); @@ -2164,7 +2166,7 @@ function mod_debug_antispam() { $where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']); if (isset($_POST['purge'])) { - $query = prepare(', DATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where); + $query = prepare(', DATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where); $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); $query->execute() or error(db_error()); } @@ -2175,16 +2177,16 @@ function mod_debug_antispam() { $where = ''; } - $query = query('SELECT COUNT(*) FROM `antispam`' . ($where ? " WHERE $where" : '')) or error(db_error()); + $query = query('SELECT COUNT(*) FROM ``antispam``' . ($where ? " WHERE $where" : '')) or error(db_error()); $args['total'] = number_format($query->fetchColumn()); - $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL' . ($where ? " AND $where" : '')) or error(db_error()); + $query = query('SELECT COUNT(*) FROM ``antispam`` WHERE `expires` IS NOT NULL' . ($where ? " AND $where" : '')) or error(db_error()); $args['expiring'] = number_format($query->fetchColumn()); - $query = query('SELECT * FROM `antispam` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `passed` DESC LIMIT 40') or error(db_error()); + $query = query('SELECT * FROM ``antispam`` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `passed` DESC LIMIT 40') or error(db_error()); $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); - $query = query('SELECT * FROM `antispam` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `created` DESC LIMIT 20') or error(db_error()); + $query = query('SELECT * FROM ``antispam`` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `created` DESC LIMIT 20') or error(db_error()); $args['recent'] = $query->fetchAll(PDO::FETCH_ASSOC); mod_page(_('Debug: Anti-spam'), 'mod/debug/antispam.html', $args); @@ -2200,7 +2202,7 @@ function mod_debug_recent_posts() { // 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']); + $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); diff --git a/install.php b/install.php index 847876ab..2f51b22f 100644 --- a/install.php +++ b/install.php @@ -501,6 +501,9 @@ if ($step == 0) { + + + @@ -668,7 +671,8 @@ if ($step == 0) { $queries[] = Element('posts.sql', array('board' => 'b')); $sql_errors = ''; - foreach ($queries as &$query) { + foreach ($queries as $query) { + $query = preg_replace('/^([\w\s]*)`([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)`/u', '$1``$2``', $query); if (!query($query)) $sql_errors .= '
  • ' . db_error() . '
  • '; } diff --git a/post.php b/post.php index f4499845..22782ca7 100644 --- a/post.php +++ b/post.php @@ -48,7 +48,7 @@ if (isset($_POST['delete'])) { error($config['error']['nodelete']); foreach ($delete as &$id) { - $query = prepare(sprintf("SELECT `thread`, `time`,`password` FROM `posts_%s` WHERE `id` = :id", $board['uri'])); + $query = prepare(sprintf("SELECT `thread`, `time`,`password` FROM ``posts_%s`` WHERE `id` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -111,7 +111,7 @@ if (isset($_POST['delete'])) { markup($reason); foreach ($report as &$id) { - $query = prepare(sprintf("SELECT `thread` FROM `posts_%s` WHERE `id` = :id", $board['uri'])); + $query = prepare(sprintf("SELECT `thread` FROM ``posts_%s`` WHERE `id` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -123,7 +123,7 @@ if (isset($_POST['delete'])) { '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $thread ? $thread : $id) . ($thread ? '#' . $id : '') . ' for "' . $reason . '"' ); - $query = prepare("INSERT INTO `reports` VALUES (NULL, :time, :ip, :board, :post, :reason)"); + $query = prepare("INSERT INTO ``reports`` VALUES (NULL, :time, :ip, :board, :post, :reason)"); $query->bindValue(':time', time(), PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR); $query->bindValue(':board', $board['uri'], PDO::PARAM_INT); @@ -227,7 +227,7 @@ if (isset($_POST['delete'])) { //Check if thread exists if (!$post['op']) { - $query = prepare(sprintf("SELECT `sticky`,`locked`,`sage` FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `sticky`,`locked`,`sage` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); $query->bindValue(':id', $post['thread'], PDO::PARAM_INT); $query->execute() or error(db_error()); @@ -583,7 +583,7 @@ if (isset($_POST['delete'])) { if (isset($post['tracked_cites'])) { foreach ($post['tracked_cites'] as $cite) { - $query = prepare('INSERT INTO `cites` VALUES (:board, :post, :target_board, :target)'); + $query = prepare('INSERT INTO ``cites`` VALUES (:board, :post, :target_board, :target)'); $query->bindValue(':board', $board['uri']); $query->bindValue(':post', $id, PDO::PARAM_INT); $query->bindValue(':target_board',$cite[0]); diff --git a/templates/posts.sql b/templates/posts.sql index 698fad77..ca2ec304 100644 --- a/templates/posts.sql +++ b/templates/posts.sql @@ -1,4 +1,4 @@ -CREATE TABLE IF NOT EXISTS `posts_{{ board }}` ( +CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `thread` int(11) DEFAULT NULL, `subject` varchar(100) DEFAULT NULL, diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php index 7ba0d1e7..6ba09ce6 100644 --- a/templates/themes/basic/theme.php +++ b/templates/themes/basic/theme.php @@ -25,7 +25,7 @@ $settings['no_recent'] = (int) $settings['no_recent']; - $query = query("SELECT * FROM `news` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error()); + $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); return Element('themes/basic/index.html', Array( diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index 5c9f6769..4e2d40db 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -37,7 +37,7 @@ $recent_posts = array(); $stats = array(); - $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error()); + $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])); diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php index 7d468d0d..74ed61ed 100644 --- a/templates/themes/categories/theme.php +++ b/templates/themes/categories/theme.php @@ -36,7 +36,7 @@ public static function news($settings) { global $config; - $query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error()); + $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); return Element('themes/categories/news.html', Array( diff --git a/templates/themes/frameset/theme.php b/templates/themes/frameset/theme.php index 5fd9d29e..ffab0538 100644 --- a/templates/themes/frameset/theme.php +++ b/templates/themes/frameset/theme.php @@ -36,7 +36,7 @@ public static function news($settings) { global $config; - $query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error()); + $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); return Element('themes/frameset/news.html', Array( diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index 98fabfa1..08d910f8 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -42,7 +42,7 @@ foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; - $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']); + $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_images'], $query); $query = query($query) or error(db_error()); @@ -62,7 +62,7 @@ foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; - $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']); + $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_posts'], $query); $query = query($query) or error(db_error()); @@ -82,7 +82,7 @@ foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; - $query .= sprintf("SELECT MAX(`id`) AS `top` FROM `posts_%s` UNION ALL ", $_board['uri']); + $query .= sprintf("SELECT MAX(`id`) AS `top` FROM ``posts_%s`` UNION ALL ", $_board['uri']); } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); @@ -93,7 +93,7 @@ foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; - $query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']); + $query .= sprintf("SELECT `ip` FROM ``posts_%s`` UNION ALL ", $_board['uri']); } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); @@ -104,7 +104,7 @@ foreach ($boards as &$_board) { if (in_array($_board['uri'], $this->excluded)) continue; - $query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']); + $query .= sprintf("SELECT `filesize` FROM ``posts_%s`` UNION ALL ", $_board['uri']); } $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query); $query = query($query) or error(db_error()); diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php index 0e0a2f15..a14169a3 100644 --- a/templates/themes/rrdtool/theme.php +++ b/templates/themes/rrdtool/theme.php @@ -61,7 +61,7 @@ // debug just the graphing (not updating) with the --debug switch if (!isset($argv[1]) || $argv[1] != '--debug') { // Update graph - $query = query(sprintf("SELECT MAX(`id`) FROM `posts_%s`", $board)); + $query = query(sprintf("SELECT MAX(`id`) FROM ``posts_%s``", $board)); $count = $query->fetchColumn(); if (!rrd_update($file, Array( diff --git a/templates/themes/sitemap/theme.php b/templates/themes/sitemap/theme.php index e210316b..226f8357 100644 --- a/templates/themes/sitemap/theme.php +++ b/templates/themes/sitemap/theme.php @@ -19,7 +19,7 @@ $threads = array(); foreach ($boards as $board) { - $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM `posts_%s` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM `posts_%s` WHERE `thread` IS NULL", $board, $board)) or error(db_error()); + $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error()); $threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC); } -- cgit v1.3 From 5bf0e7f7e76cd3610e0aa692e0c433aca594ee51 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 00:27:54 -0400 Subject: Better/fixed jQuery styling and slightly improved js/inline-expanding.js accuracy (when jQuery is enabled) --- js/inline-expanding.js | 3 +++ templates/header.html | 30 ++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'templates') diff --git a/js/inline-expanding.js b/js/inline-expanding.js index e529a395..61085b0d 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -17,6 +17,9 @@ onready(function(){ for (var i = 0; i < link.length; i++) { if (typeof link[i] == "object" && link[i].childNodes && typeof link[i].childNodes[0] !== 'undefined' && link[i].childNodes[0].src && link[i].className != 'file') { + if (window.jQuery && !$(link).prev().hasClass('fileinfo')) { + continue; + } link[i].childNodes[0].style.maxWidth = '95%'; link[i].onclick = function(e) { if (this.childNodes[0].className == 'hidden') diff --git a/templates/header.html b/templates/header.html index 3791296f..c1230f0e 100644 --- a/templates/header.html +++ b/templates/header.html @@ -13,17 +13,31 @@ {% endif %} {% endif %} {% if config.recaptcha %}{% endif %} \ No newline at end of file -- cgit v1.3 From 9343651d90113f68b83f214c20a32975d18217e7 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:16:20 -0400 Subject: Add optional database table prefix (issue #118; see issue comments for details) --- search.php | 13 ++++++++----- templates/themes/ukko/theme.php | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'templates') diff --git a/search.php b/search.php index 27ddbe15..a40c4701 100644 --- a/search.php +++ b/search.php @@ -17,21 +17,21 @@ $phrase = $_GET['search']; $_body = ''; - $query = prepare("SELECT COUNT(*) FROM `search_queries` WHERE `ip` = :ip AND `time` > :time"); + $query = prepare("SELECT COUNT(*) FROM ``search_queries`` WHERE `ip` = :ip AND `time` > :time"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':time', time() - ($queries_per_minutes[1] * 60)); $query->execute() or error(db_error($query)); if($query->fetchColumn() > $queries_per_minutes[0]) error(_('Wait a while before searching again, please.')); - $query = prepare("SELECT COUNT(*) FROM `search_queries` WHERE `time` > :time"); + $query = prepare("SELECT COUNT(*) FROM ``search_queries`` WHERE `time` > :time"); $query->bindValue(':time', time() - ($queries_per_minutes_all[1] * 60)); $query->execute() or error(db_error($query)); if($query->fetchColumn() > $queries_per_minutes_all[0]) error(_('Wait a while before searching again, please.')); - $query = prepare("INSERT INTO `search_queries` VALUES (:ip, :time, :query)"); + $query = prepare("INSERT INTO ``search_queries`` VALUES (:ip, :time, :query)"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':time', time()); $query->bindValue(':query', $phrase); @@ -40,7 +40,7 @@ _syslog(LOG_NOTICE, 'Searched /' . $_GET['board'] . '/ for "' . $phrase . '"'); // Cleanup search queries table - $query = prepare("DELETE FROM `search_queries` WHERE `time` <= :time"); + $query = prepare("DELETE FROM ``search_queries`` WHERE `time` <= :time"); $query->bindValue(':time', time() - ($queries_per_minutes_all[1] * 60)); $query->execute() or error(db_error($query)); @@ -85,6 +85,9 @@ // Use asterisk as wildcard to suit convention $phrase = str_replace('*', '%', $phrase); + // Remove `, it's used by table prefix magic + $phrase = str_replace('`', '!`', $phrase); + $like = ''; $match = Array(); @@ -119,7 +122,7 @@ $like = str_replace('%', '%%', $like); - $query = prepare(sprintf("SELECT * FROM `posts_%s` WHERE " . $like . " ORDER BY `time` DESC LIMIT :limit", $board['uri'])); + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE " . $like . " ORDER BY `time` DESC LIMIT :limit", $board['uri'])); $query->bindValue(':limit', $search_limit, PDO::PARAM_INT); $query->execute() or error(db_error($query)); diff --git a/templates/themes/ukko/theme.php b/templates/themes/ukko/theme.php index 6fa5fa7e..1682b4ec 100644 --- a/templates/themes/ukko/theme.php +++ b/templates/themes/ukko/theme.php @@ -25,7 +25,7 @@ foreach($boards as &$_board) { if(in_array($_board['uri'], explode(' ', $this->settings['exclude']))) continue; - $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); + $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query); $query = query($query) or error(db_error()); @@ -48,7 +48,7 @@ $post['filename'], $post['ip'], $post['sticky'], $post['locked'], $post['sage'], $post['embed'], $mod ? '?/' : $config['root'], $mod ); - $posts = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board'])); + $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board'])); $posts->bindValue(':id', $post['id']); $posts->bindValue(':limit', ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); $posts->execute() or error(db_error($posts)); @@ -66,7 +66,7 @@ } if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { - $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board'])); + $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board'])); $ct->bindValue(':thread', $post['id'], PDO::PARAM_INT); $ct->execute() or error(db_error($count)); -- cgit v1.3 From 6b6f32949df7be58c7a9125711aeab2c34cd1d54 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 15:20:25 -0400 Subject: Web config editor: Use a + {% elseif var.type == 'integer' and var.name.0 == 'mod' and (var.default in ['JANITOR', 'MOD', 'ADMIN', 'DISABLED'] or var.default|slice(0, 14) == "$config['mod']") and var.value <= constant('DISABLED') %} + {% elseif var.type == 'integer' %} {% elseif var.type == 'boolean' %} -- cgit v1.3 From 5a44c50811ba9a927add4d54604307692492df8a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 17:18:10 -0400 Subject: Simple file editor replacement for ?/config (optional). Issue #127 --- inc/config.php | 7 +++--- inc/mod/pages.php | 29 ++++++++++++++++++----- templates/mod/config-editor-php.html | 45 ++++++++++++++++++++++++++++++++++++ templates/mod/dashboard.html | 2 +- templates/mod/edit_post_form.html | 2 +- 5 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 templates/mod/config-editor-php.html (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index d82ebfc6..bddb9e4c 100644 --- a/inc/config.php +++ b/inc/config.php @@ -929,6 +929,9 @@ // Automatically dismiss all reports regarding a thread when it is locked $config['mod']['dismiss_reports_on_lock'] = true; + // Replace ?/config with a simple text editor for editing inc/instance-config.php + $config['mod']['config_editor_php'] = false; + // Probably best not to change these: if (!defined('JANITOR')) { define('JANITOR', 0, true); @@ -999,7 +1002,7 @@ // Bypass flood check $config['mod']['flood'] = ADMIN; // Raw HTML posting - $config['mod']['rawhtml'] = DISABLED; + $config['mod']['rawhtml'] = ADMIN; /* Administration */ // View the report queue @@ -1077,8 +1080,6 @@ // Delete news entries $config['mod']['news_delete'] = ADMIN; - // View the current configuration - $config['mod']['show_config'] = ADMIN; // Edit the current configuration (via web interface) $config['mod']['edit_config'] = ADMIN; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 1e0dc7c9..615e85c7 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1304,13 +1304,12 @@ function mod_edit_post($board, $edit_raw_html, $postID) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $postID) . '#' . $postID, true, $config['redirect_http']); } else { if ($config['minify_html']) { - // $post['body_nomarkup'] = str_replace("\n", ' ', $post['body_nomarkup']); - // $post['body'] = str_replace("\n", ' ', $post['body']); + $post['body_nomarkup'] = str_replace("\n", ' ', utf8tohtml($post['body_nomarkup'])); + $post['body'] = str_replace("\n", ' ', utf8tohtml($post['body'])); + $post['body_nomarkup'] = str_replace("\r", '', $post['body_nomarkup']); + $post['body'] = str_replace("\r", '', $post['body']); } - - // Minifying this page causes an issue with newlines in the textarea. This is a temporary solution. - $config['minify_html'] = false; - + mod_page(_('Edit post'), 'mod/edit_post_form.html', array('token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post)); } } @@ -1948,6 +1947,24 @@ function mod_config() { if (!hasPermission($config['mod']['edit_config'])) error($config['error']['noaccess']); + if ($config['mod']['config_editor_php']) { + $readonly = !is_writable('inc/instance-config.php'); + + if (!$readonly && isset($_POST['code'])) { + $code = $_POST['code']; + file_put_contents('inc/instance-config.php', $code); + header('Location: ?/config', true, $config['redirect_http']); + return; + } + + $instance_config = file_get_contents('inc/instance-config.php'); + $instance_config = str_replace("\n", ' ', utf8tohtml($instance_config)); + + mod_page(_('Config editor'), 'mod/config-editor-php.html', array('php' => $instance_config, 'readonly' => $readonly)); + return; + } + + require_once 'inc/mod/config-editor.php'; $conf = config_vars(); diff --git a/templates/mod/config-editor-php.html b/templates/mod/config-editor-php.html new file mode 100644 index 00000000..54c398e4 --- /dev/null +++ b/templates/mod/config-editor-php.html @@ -0,0 +1,45 @@ +{% if readonly %} +

    Tinyboard does not have the required permissions to edit inc/instance-config.php. To make changes, you will need to change the file's permissions first or manually edit the code.

    +{% endif %} + + +{% if not readonly %}{% endif %} + + +
      +
    • +
    +{% if not readonly %}{% endif %} + + \ No newline at end of file diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 5f6585fc..e9fb7c9c 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -94,7 +94,7 @@ {% if mod|hasPermission(config.mod.rebuild) %}
  • {% trans 'Rebuild' %}
  • {% endif %} - {% if mod|hasPermission(config.mod.show_config) %} + {% if mod|hasPermission(config.mod.edit_config) %}
  • {% trans 'Configuration' %}
  • {% endif %} diff --git a/templates/mod/edit_post_form.html b/templates/mod/edit_post_form.html index b9359c68..a2980d35 100644 --- a/templates/mod/edit_post_form.html +++ b/templates/mod/edit_post_form.html @@ -32,7 +32,7 @@ {% trans %}Comment{% endtrans %} - + -- cgit v1.3 From dc84ccc6a8e0b6fd3fc626eb1f321e4cf2d05511 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 23:31:35 -0400 Subject: Revert "Disable autocomplete": this breaks access to post text after an error, at least in Firefox This reverts commit 90b82b1a0635d78d536bc92decbdc273d8f7e323. --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index 9ccd7be3..391f0657 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -1,4 +1,4 @@ -
    + {{ antibot.html() }} {% if id %}{% endif %} {{ antibot.html() }} -- cgit v1.3 From f06978659b4ff4e18e9547ebd4af514d56123cfb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 00:08:37 -0400 Subject: Installer: Nicer pre-installation test --- inc/config.php | 19 +-- install.php | 191 +++++++++++++++++++++------- templates/installer/check-requirements.html | 54 ++++++++ 3 files changed, 211 insertions(+), 53 deletions(-) create mode 100644 templates/installer/check-requirements.html (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index bddb9e4c..fe771358 100644 --- a/inc/config.php +++ b/inc/config.php @@ -418,16 +418,17 @@ $config['thumb_keep_animation_frames'] = 1; // Thumbnailing method: - // - 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG). - // This is a prerequisite for Tinyboard no matter what method you choose. - // - 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats. - // A few minor bugs. http://pecl.php.net/package/imagick - // - 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in - // PHP Imagick. - // - 'convert+gifsicle' Same as above, with the exception of using `gifsicle` (command line application) - // instead of `convert` for resizing gifs. It's faster and resulting animated gifs - // have less artifacts than if resized with ImageMagick. + // - 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG). + // This is a prerequisite for Tinyboard no matter what method you choose. + // - 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats. + // A few minor bugs. http://pecl.php.net/package/imagick + // - 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in + // PHP Imagick. `convert` produces the best still thumbnails and is highly recommended. + // - 'convert+gifsicle' Same as above, with the exception of using `gifsicle` (command line application) + // instead of `convert` for resizing GIFs. It's faster and resulting animated thumbnails + // have less artifacts than if resized with ImageMagick. $config['thumb_method'] = 'gd'; + // $config['thumb_method'] = 'convert'; // Strip EXIF metadata from JPEG files $config['strip_exif'] = false; diff --git a/install.php b/install.php index 6bb161dc..fa41ad2d 100644 --- a/install.php +++ b/install.php @@ -388,53 +388,156 @@ if ($step == 0) { } elseif ($step == 1) { $page['title'] = 'Pre-installation test'; - $page['body'] = ''; - - function rheader($item) { - global $page, $config; - - $page['body'] .= ''; - } - - function row($item, $result) { - global $page, $config, $__is_error; - if (!$result) - $__is_error = true; - $page['body'] .= ''; + $can_exec = true; + if (!function_exists('shell_exec')) + $can_exec = false; + elseif (in_array('shell_exec', array_map('trim', explode(', ', ini_get('disable_functions'))))) + $can_exec = false; + elseif (ini_get('safe_mode')) + $can_exec = false; + elseif (trim(shell_exec('echo "TEST"')) !== 'TEST') + $can_exec = false; + + if (!defined('PHP_VERSION_ID')) { + $version = explode('.', PHP_VERSION); + define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } - // Required extensions - rheader('PHP extensions'); - row('PDO', extension_loaded('pdo')); - row('GD', extension_loaded('gd')); - - // GD tests - rheader('GD tests'); - row('JPEG', function_exists('imagecreatefromjpeg')); - row('PNG', function_exists('imagecreatefrompng')); - row('GIF', function_exists('imagecreatefromgif')); - - // Database drivers - $drivers = PDO::getAvailableDrivers(); - - rheader('PDO drivers (currently installed drivers)'); - foreach ($drivers as &$driver) { - row($driver, true); - } - - // Permissions - rheader('File permissions'); - row('root directory (' . getcwd() . ')', is_writable('.')); - - $page['body'] .= '
    ' . $item . '
    ' . $item . '
    -

    - Continue' . (isset($__is_error) ? ' anyway' : '') . ' -

    '; - - echo Element('page.html', $page); + $extensions = array( + 'PDO' => array( + 'installed' => extension_loaded('pdo'), + 'required' => true + ), + 'PDO' => array( + 'installed' => extension_loaded('gd'), + 'required' => true + ), + 'Imagick' => array( + 'installed' => extension_loaded('imagick'), + 'required' => false + ) + ); + + $tests = array( + array( + 'category' => 'PHP', + 'name' => 'PHP ≥ 5.2.5', + 'result' => PHP_VERSION_ID >= 50205, + 'required' => true, + 'message' => 'Tinyboard requires PHP 5.2.5 or better.', + ), + array( + 'category' => 'PHP', + 'name' => 'PHP ≥ 5.3', + 'result' => PHP_VERSION_ID >= 50300, + 'required' => false, + 'message' => 'PHP ≥ 5.3, though not required, is recommended to make the most out of Tinyboard configuration files.', + ), + array( + 'category' => 'PHP', + 'name' => 'mbstring extension installed', + 'result' => extension_loaded('mbstring'), + 'required' => true, + 'message' => 'You must install the PHP mbstring extension.', + ), + array( + 'category' => 'Database', + 'name' => 'PDO extension installed', + 'result' => extension_loaded('pdo'), + 'required' => true, + 'message' => 'You must install the PHP PDO extension.', + ), + array( + 'category' => 'Database', + 'name' => 'MySQL PDO driver installed', + 'result' => extension_loaded('pdo') && in_array('mysql1', PDO::getAvailableDrivers()), + 'required' => true, + 'message' => 'The required PDO MySQL driver is not installed.', + ), + array( + 'category' => 'Image processing', + 'name' => 'GD extension installed', + 'result' => extension_loaded('gd'), + 'required' => true, + 'message' => 'You must install the PHP GD extension. GD is a requirement even if you have chosen another image processor for thumbnailing.', + ), + array( + 'category' => 'Image processing', + 'name' => 'GD: JPEG', + 'result' => function_exists('imagecreatefromjpeg'), + 'required' => true, + 'message' => 'imagecreatefromjpeg() does not exist. This is a problem.', + ), + array( + 'category' => 'Image processing', + 'name' => 'GD: PNG', + 'result' => function_exists('imagecreatefrompng'), + 'required' => true, + 'message' => 'imagecreatefrompng() does not exist. This is a problem.', + ), + array( + 'category' => 'Image processing', + 'name' => 'GD: GIF', + 'result' => function_exists('imagecreatefromgif'), + 'required' => true, + 'message' => 'imagecreatefromgif() does not exist. This is a problem.', + ), + array( + 'category' => 'Image processing', + 'name' => 'Imagick extension installed', + 'result' => extension_loaded('imagick1'), + 'required' => false, + 'message' => '(Optional) The PHP Imagick (ImageMagick) extension is not installed. You may not use Imagick for better (and faster) image processing.', + ), + array( + 'category' => 'Image processing', + 'name' => '`convert` (command-line ImageMagick)', + 'result' => $can_exec && shell_exec('which convert'), + 'required' => false, + 'message' => '(Optional) `convert` was not found or executable; command-line ImageMagick image processing cannot be enabled.', + ), + array( + 'category' => 'Image processing', + 'name' => '`identify` (command-line ImageMagick)', + 'result' => $can_exec && shell_exec('which identify'), + 'required' => false, + 'message' => '(Optional) `identify` was not found or executable; command-line ImageMagick image processing cannot be enabled.', + ), + array( + 'category' => 'Image processing', + 'name' => '`gifsicle` (command-line animted GIF thumbnailing)', + 'result' => $can_exec && shell_exec('which gifsicle1'), + 'required' => false, + 'message' => '(Optional) `gifsicle` was not found or executable; you may not use `convert+gifsicle` for better animated GIF thumbnailing.', + ), + array( + 'category' => 'File permissions', + 'name' => getcwd(), + 'result' => is_writable('.'), + 'required' => true, + 'message' => 'Tinyboard does not have permission to create directories (boards) here. You will need to chmod (or operating system equivalent) appropriately.' + ), + array( + 'category' => 'File permissions', + 'name' => getcwd() . '/inc/instance-config.php', + 'result' => is_writable('inc/instance-config.php'), + 'required' => false, + 'message' => 'Tinyboard does not have permission to make changes to inc/instance-config.php. To complete the installation, you will be asked to manually copy and paste code into the file instead.' + ) + ); + + $config['font_awesome'] = true; + + echo Element('page.html', array( + 'body' => Element('installer/check-requirements.html', array( + 'extensions' => $extensions, + 'tests' => $tests, + 'config' => $config + )), + 'title' => 'Checking environment', + 'config' => $config + )); } elseif ($step == 2) { // Basic config $page['title'] = 'Configuration'; diff --git a/templates/installer/check-requirements.html b/templates/installer/check-requirements.html new file mode 100644 index 00000000..fea6fed8 --- /dev/null +++ b/templates/installer/check-requirements.html @@ -0,0 +1,54 @@ +
    +

    Pre-installation tests

    + + + + + + + {% set errors = 0 %} + {% set warnings = 0 %} + {% for test in tests %} + + + + + + {% endfor %} +
    CategoryTestResult
    {{ test.category }}{{ test.name }} + {% if test.result %} + + {% else %} + {% if test.required %} + {% set errors = errors + 1 %} + + {% else %} + {% set warnings = warnings + 1 %} + + {% endif %} + {% endif %} +
    + {% if errors or warnings %} +

    There were {{ errors }} error(s) and {{ warnings }} warning(s).

    +
      + {% for test in tests if not test.result%} +
    • + {% if test.required %} + Error: + {% else %} + Warning: + {% endif %} + {{ test.message }} +
    • + {% endfor %} +
    + {% if errors %} +

    Clik here to ignore errors and attempt installing anyway (not recommended).

    + {% else %} +

    Clik here to proceed with installation.

    + {% endif %} + {% else %} +

    There were no errors or warnings. Good!

    +

    Clik here to proceed with installation.

    + {% endif %} +
    -- cgit v1.3 From 5710575d1dc9fbd39bd90f9e5f4f9e33ef3f5a73 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 23:31:35 -0400 Subject: Revert "Disable autocomplete": this breaks access to post text after an error, at least in Firefox This reverts commit 90b82b1a0635d78d536bc92decbdc273d8f7e323. --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/post_form.html b/templates/post_form.html index 599ae754..31fe88c6 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -1,4 +1,4 @@ - + {{ antibot.html() }} {% if id %}{% endif %} {{ antibot.html() }} -- cgit v1.3 From 6f6a20af8eb779f4b8dd703e3d87e72ad9b67908 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 03:16:34 -0400 Subject: ukko: javascript major refactor --- templates/themes/ukko/ukko.js | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'templates') diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index 6566335e..99c737d6 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -1,20 +1,30 @@ +(function(){ + var cache = new Array(), thread = false, loading = false; $(document).ready(function() { + $('.pages').hide(); $(window).on('scroll', function() { - if($(window).scrollTop() + $(window).height() + 100 > $(document).height() && !loading && overflow.length > 0) { + if (overflow.length == 0) { + $('.pages').show().html(_("No more threads to display")); + } + while($(window).scrollTop() + $(window).height() + 500 > $(document).height() && !loading && overflow.length > 0) { var page = '../' + overflow[0].board + '/' + overflow[0].page; - if($.inArray(page, cache) != -1) { - thread = $('div#thread_' + overflow[0].id); - if(thread.length > 0) { - thread.prepend('

    /' + overflow[0].board + '/

    '); - $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); - $(document).trigger('new_post', thread); - overflow.shift(); - } + thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); + if (thread.length > 0 && thread.css('display') != 'none') { // already present + overflow.shift(); + continue; + } + + if($.inArray(page, cache) != -1 && thread.length > 0) { + thread.prepend('

    /' + overflow[0].board + '/

    '); + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); + $(document).trigger('new_post', thread); + overflow.shift(); } else { loading = true; + $('.pages').show().html(_("Loading...")); $.get(page, function(data) { cache.push(page); @@ -23,16 +33,23 @@ $(document).ready(function() { }); thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); - if(thread.length > 0) { + if(thread.length > 0 && thread.css('display') != 'none') { thread.prepend('

    /' + overflow[0].board + '/

    '); $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); $(document).trigger('new_post', thread); overflow.shift(); } + else { + overflow.shift(); // We missed it? Or already present... + } loading = false; + $('.pages').hide().html(""); }); + break; } } }); }); + +})(); -- cgit v1.3 From 73b5cf5a08c395e706e8bc3ac8032bfbc810376f Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 04:20:57 -0400 Subject: ukko: implement ukko hide --- templates/themes/ukko/ukko.js | 65 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 7 deletions(-) (limited to 'templates') diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index 99c737d6..9011c754 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -3,7 +3,54 @@ var cache = new Array(), thread = false, loading = false; + +if (localStorage.hiddenboards !== null) { + localStorage.hiddenboards = "{}"; +} + +// Load data from HTML5 localStorage +var hiddenboards = JSON.parse(localStorage.hiddenboards); + +var storeboards = function() { + localStorage.hiddenboards = JSON.stringify(hiddenboards); +}; + $(document).ready(function() { + var addukkohide = function() { + var ukkohide = $(''); + var board = $(this).next().data("board"); + var hr = $("
    "); + + $(this).append(ukkohide); + $(this).append(hr); + + if (hiddenboards[board] !== true) { + ukkohide.html(_("(hide threads from this board)")); + hr.hide(); + } + else { + ukkohide.html(_("(show threads from this board)")); + $(this).next().hide(); + } + ukkohide.click(function() { + hiddenboards[board] = (hiddenboards[board] !== true); + if (hiddenboards[board] !== true) { + $('[data-board="'+board+'"][data-cached!="yes"]').show().prev(). + find('.ukkohide').html(_("(hide threads from this board)")). + parent().find('hr').hide(); + } + else { + $('[data-board="'+board+'"][data-cached!="yes"]').hide().prev(). + find('.ukkohide').html(_("(show threads from this board)")) + .parent().find('hr').show(); + } + storeboards(); + return false; + }); + + }; + $("h2").each(addukkohide); + $('.pages').hide(); $(window).on('scroll', function() { if (overflow.length == 0) { @@ -12,14 +59,17 @@ $(document).ready(function() { while($(window).scrollTop() + $(window).height() + 500 > $(document).height() && !loading && overflow.length > 0) { var page = '../' + overflow[0].board + '/' + overflow[0].page; thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); - if (thread.length > 0 && thread.css('display') != 'none') { // already present + if (thread.length > 0 && thread.data("cached") !== 'yes') { // already present overflow.shift(); continue; } + var boardheader = $('

    /' + overflow[0].board + '/

    '); + if($.inArray(page, cache) != -1 && thread.length > 0) { - thread.prepend('

    /' + overflow[0].board + '/

    '); - $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).data("cached", "no").css('display', 'block')); + boardheader.insertBefore(thread); + addukkohide.call(boardheader); $(document).trigger('new_post', thread); overflow.shift(); } else { @@ -29,13 +79,14 @@ $(document).ready(function() { cache.push(page); $(data).find('div[id*="thread_"]').each(function() { - $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr('data-board', overflow[0].board)); + $('form[name="postcontrols"]').prepend($(this).css('display', 'none').data("cached", "yes").attr('data-board', overflow[0].board)); }); thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); - if(thread.length > 0 && thread.css('display') != 'none') { - thread.prepend('

    /' + overflow[0].board + '/

    '); - $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block')); + if(thread.length > 0 && thread.data('cached') !== 'no') { + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).data("cached", "no").css('display', 'block')); + boardheader.insertBefore(thread); + addukkohide.call(boardheader); $(document).trigger('new_post', thread); overflow.shift(); } -- cgit v1.3 From 3922677968cd4228be0e37943de131282b9eb1e4 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 04:36:08 -0400 Subject: ukko: bugfixes --- templates/themes/ukko/ukko.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'templates') diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js index 9011c754..11617593 100644 --- a/templates/themes/ukko/ukko.js +++ b/templates/themes/ukko/ukko.js @@ -35,12 +35,12 @@ $(document).ready(function() { ukkohide.click(function() { hiddenboards[board] = (hiddenboards[board] !== true); if (hiddenboards[board] !== true) { - $('[data-board="'+board+'"][data-cached!="yes"]').show().prev(). + $('[data-board="'+board+'"]:not([data-cached="yes"])').show().prev(). find('.ukkohide').html(_("(hide threads from this board)")). parent().find('hr').hide(); } else { - $('[data-board="'+board+'"][data-cached!="yes"]').hide().prev(). + $('[data-board="'+board+'"]:not([data-cached="yes"])').hide().prev(). find('.ukkohide').html(_("(show threads from this board)")) .parent().find('hr').show(); } @@ -59,7 +59,7 @@ $(document).ready(function() { while($(window).scrollTop() + $(window).height() + 500 > $(document).height() && !loading && overflow.length > 0) { var page = '../' + overflow[0].board + '/' + overflow[0].page; thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); - if (thread.length > 0 && thread.data("cached") !== 'yes') { // already present + if (thread.length > 0 && thread.attr("data-cached") !== 'yes') { // already present overflow.shift(); continue; } @@ -67,7 +67,7 @@ $(document).ready(function() { var boardheader = $('

    /' + overflow[0].board + '/

    '); if($.inArray(page, cache) != -1 && thread.length > 0) { - $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).data("cached", "no").css('display', 'block')); + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block')); boardheader.insertBefore(thread); addukkohide.call(boardheader); $(document).trigger('new_post', thread); @@ -79,12 +79,12 @@ $(document).ready(function() { cache.push(page); $(data).find('div[id*="thread_"]').each(function() { - $('form[name="postcontrols"]').prepend($(this).css('display', 'none').data("cached", "yes").attr('data-board', overflow[0].board)); + $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr("data-cached", "yes").attr('data-board', overflow[0].board)); }); thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); - if(thread.length > 0 && thread.data('cached') !== 'no') { - $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).data("cached", "no").css('display', 'block')); + if(thread.length > 0 && thread.attr('data-cached') !== 'no') { + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block')); boardheader.insertBefore(thread); addukkohide.call(boardheader); $(document).trigger('new_post', thread); -- cgit v1.3 From 9e7fbf927c67797269062a3b5f827a92ac822e12 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 16:19:20 -0400 Subject: Installer improvements --- install.php | 176 +++------------------------- templates/installer/check-requirements.html | 10 +- 2 files changed, 21 insertions(+), 165 deletions(-) (limited to 'templates') diff --git a/install.php b/install.php index b1395d3e..82ba5b8b 100644 --- a/install.php +++ b/install.php @@ -524,6 +524,13 @@ if ($step == 0) { 'result' => is_writable('inc/instance-config.php'), 'required' => false, 'message' => 'Tinyboard does not have permission to make changes to inc/instance-config.php. To complete the installation, you will be asked to manually copy and paste code into the file instead.' + ), + array( + 'category' => 'Misc', + 'name' => 'Tinyboard installed using git', + 'result' => is_dir('.git.'), + 'required' => false, + 'message' => 'Tinyboard is still beta software and it\'s not going to come out of beta any time soon. As there are often many months between releases yet changes and bug fixes are very frequent, it\'s recommended to use the git repository to maintain your Tinyboard installation. Using git makes upgrading much easier.' ) ); @@ -542,167 +549,16 @@ if ($step == 0) { // Basic config $page['title'] = 'Configuration'; - function create_salt() { - return substr(base64_encode(sha1(rand())), 0, rand(25, 31)); - } - - $page['body'] = ' - -
    - Database - - - - - - - - - - - - - - - - - -
    -

    The following is all later configurable. For more options, edit your configuration files after installing.

    -
    - Cookies - - - - - -
    - -
    - Flood control - - - - - - - - - - - - - - - - - -
    - -
    - Images - - - - - - - - - - - - - - -
    - -
    - Display - - - - - - - - -
    + $config['cookies']['salt'] = substr(base64_encode(sha1(rand())), 0, 30); + $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30); -
    - Directories - - - - - - - - - - - -
    - -
    - Miscellaneous - - -
    - -

    - -

    - - '; - - - echo Element('page.html', $page); + echo Element('page.html', array( + 'body' => Element('installer/config.html', array( + 'config' => $config + )), + 'title' => 'Configuration', + 'config' => $config + )); } elseif ($step == 3) { $instance_config = '{{ test.name }} {% if test.result %} - + {% else %} {% if test.required %} {% set errors = errors + 1 %} - + {% else %} {% set warnings = warnings + 1 %} - + {% endif %} {% endif %} @@ -34,9 +34,9 @@ {% for test in tests if not test.result%}
  • {% if test.required %} - Error: + Error: {% else %} - Warning: + Warning: {% endif %} {{ test.message }}
  • -- cgit v1.3 From 4fce9b63aee89c04ea0d833992e72ab75585f630 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 20:52:58 -0400 Subject: Major config.php cleanup and a few minor misc fixes. --- inc/config.php | 1040 +++++++++++++++++++++++-------------------- inc/display.php | 42 +- inc/filters.php | 4 +- inc/functions.php | 13 +- inc/image.php | 14 +- mod.php | 11 +- post.php | 2 +- templates/generic_page.html | 2 +- templates/index.html | 2 +- templates/thread.html | 2 +- 10 files changed, 605 insertions(+), 527 deletions(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index fe771358..c181c0c5 100644 --- a/inc/config.php +++ b/inc/config.php @@ -29,45 +29,49 @@ * General/misc settings * ======================= */ - // Blotter -- the simple version. - //$config['blotter'] = 'This is an important announcement!'; - - // Automatically check if a newer version of Tinyboard is available when an administrator logs in + + // Global announcement -- the very simple version. + // This used to be wrongly named $config['blotter'] (still exists as an alias). + // $config['global_message'] = 'This is an important announcement!'; + $config['blotter'] = &$config['global_message']; + + // Automatically check if a newer version of Tinyboard is available when an administrator logs in. $config['check_updates'] = true; // How often to check for updates $config['check_updates_time'] = 43200; // 12 hours - - // Shows some extra information at the bottom of pages. Good for debugging development. + + // Shows some extra information at the bottom of pages. Good for development/debugging. $config['debug'] = false; - // For development purposes. Turns 'display_errors' on. Not recommended for production. + // For development purposes. All this does is turn 'display_errors' on. $config['verbose_errors'] = true; - - // Directory where temporary files will be created. Not really used much yet except for some experimental stuff. + + // Directory where temporary files will be created. $config['tmp'] = sys_get_temp_dir(); - + // The HTTP status code to use when redirecting. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html // Can be either 303 "See Other" or 302 "Found". (303 is more correct but both should work.) + // There is really no reason for you to ever need to change this. $config['redirect_http'] = 303; - - // A small file in the main directory indicating that the script has been ran and the board(s) have been generated. - // This keeps the script from querying the database and causing strain when not needed. + + // A tiny text file in the main directory indicating that the script has been ran and the board(s) have + // been generated. This keeps the script from querying the database and causing strain when not needed. $config['has_installed'] = '.installed'; - + // Use syslog() for logging all error messages and unauthorized login attempts. $config['syslog'] = false; - + // Use `host` via shell_exec() to lookup hostnames, avoiding query timeouts. May not work on your system. // Requires safe_mode to be disabled. $config['dns_system'] = false; - + /* * ==================== * Database settings * ==================== */ - - // SQL driver ("mysql", "pgsql", "sqlite", "dblib", etc) - // http://www.php.net/manual/en/pdo.drivers.php + + // Database driver (http://www.php.net/manual/en/pdo.drivers.php) + // Only MySQL is supported by Tinyboard at the moment, sorry. $config['db']['type'] = 'mysql'; // Hostname or IP address $config['db']['server'] = 'localhost'; @@ -81,60 +85,72 @@ // Use a persistent connection (experimental) $config['db']['persistent'] = false; // Anything more to add to the DSN string (eg. port=xxx;foo=bar) - $config['db']['dsn'] = 'charset=UTF8'; + $config['db']['dsn'] = ''; // Timeout duration in seconds (not all drivers support this) $config['db']['timeout'] = 5; - + /* * ==================== * Cache settings * ==================== */ - - $config['cache']['enabled'] = false; - // $config['cache']['enabled'] = 'memcached'; - // $config['cache']['enabled'] = 'redis'; - // $config['cache']['enabled'] = 'apc'; - // $config['cache']['enabled'] = 'xcache'; - - // Timeout for cached objects such as posts and HTML - $config['cache']['timeout'] = 43200; // 12 hours - - // Optional prefix if you're running multiple Tinyboard instances on the same machine + + /* + * On top of the static file caching system, you can enable the additional caching system which is + * designed to minimize SQL queries and can significantly increase speed when posting or using the + * moderator interface. APC is the recommended method of caching. + * + * http://tinyboard.org/docs/index.php?p=Config/Cache + */ + + $config['cache']['enabled'] = false; + // $config['cache']['enabled'] = 'xcache'; + // $config['cache']['enabled'] = 'apc'; + // $config['cache']['enabled'] = 'memcached'; + // $config['cache']['enabled'] = 'redis'; + + // Timeout for cached objects such as posts and HTML. + $config['cache']['timeout'] = 60 * 60 * 48; // 48 hours + + // Optional prefix if you're running multiple Tinyboard instances on the same machine. $config['cache']['prefix'] = ''; - - // Memcached servers to use - http://www.php.net/manual/en/memcached.addservers.php + + // Memcached servers to use. Read more: http://www.php.net/manual/en/memcached.addservers.php $config['cache']['memcached'] = array( array('localhost', 11211) ); // Redis server to use. Location, port, password, database id. - // Note that Tinyboard may clear the database at times, so you may want to pick a - // database id just for Tinyboard to use. + // Note that Tinyboard may clear the database at times, so you may want to pick a database id just for + // Tinyboard to use. $config['cache']['redis'] = array('localhost', 6379, '', 1); - + /* * ==================== * Cookie settings * ==================== */ - - // Used for moderation login + + // Used for moderation login. $config['cookies']['mod'] = 'mod'; + // Used for communicating with Javascript; telling it when posts were successful. - // Rebuild Javascript file after changing this value or it won't work. $config['cookies']['js'] = 'serv'; - // Cookies "path". Defaults to $config['root']. If $config['root'] is a URL, you need to set this. Should be '/' or '/board/', depending on your installation. + + // Cookies path. Defaults to $config['root']. If $config['root'] is a URL, you need to set this. Should + // be '/' or '/board/', depending on your installation. // $config['cookies']['path'] = '/'; // Where to set the 'path' parameter to $config['cookies']['path'] when creating cookies. Recommended. $config['cookies']['jail'] = true; - // How long should the cookies last (in seconds) - $config['cookies']['expire'] = 15778463; //6 months - // Make this something long and random for security + + // How long should the cookies last (in seconds). Defines how long should moderators should remain logged + // in (0 = browser session). + $config['cookies']['expire'] = 60 * 60 * 24 * 30 * 6; // ~6 months + + // Make this something long and random for security. $config['cookies']['salt'] = 'abcdefghijklmnopqrstuvwxyz09123456789!@#$%^&*()'; - // How long should moderators should remain logged in (0=browser session) (in seconds) - $config['mod']['expire'] = 15778463; //6 months - // Used to salt secure tripcodes (##trip) and poster IDs (if enabled) + + // Used to salt secure tripcodes ("##trip") and poster IDs (if enabled). $config['secure_trip_salt'] = ')(*&^%$#@!98765432190zyxwvutsrqponmlkjihgfedcba'; /* @@ -142,22 +158,29 @@ * Flood/spam settings * ==================== */ - - // How many seconds between each post + + // Minimum time between between each post by the same IP address. $config['flood_time'] = 10; - // How many seconds between each post with exactly the same content and same IP + // Minimum time between between each post with the exact same content AND same IP address. $config['flood_time_ip'] = 120; - // Same as above but different IP address + // Same as above but by a different IP address. (Same content, not necessarily same IP address.) $config['flood_time_same'] = 30; - - // DNS blacklists (DNSBL) http://tinyboard.org/docs/?p=Config/DNSBL - - // http://www.sectoor.de/tor.php - $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); // Tor exit servers - + + /* + * To further prevent spam and abuse, you can use DNS blacklists (DNSBL). A DNSBL is a list of IP + * addresses published through the Internet Domain Name Service (DNS) either as a zone file that can be + * used by DNS server software, or as a live DNS zone that can be queried in real-time. + * + * Read more: http://tinyboard.org/docs/?p=Config/DNSBL + */ + + // Prevents most Tor exit nodes from making posts. Recommended, as a lot of abuse comes from Tor because + // of the strong anonymity associated with it. + $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); + // http://www.sorbs.net/using.shtml // $config['dnsbl'][] = array('dnsbl.sorbs.net', array(2, 3, 4, 5, 6, 7, 8, 9)); - + // http://www.projecthoneypot.org/httpbl.php // $config['dnsbl'][] = array('.%.dnsbl.httpbl.org', function($ip) { // $octets = explode('.', $ip); @@ -172,11 +195,10 @@ // // return true; // }, 'dnsbl.httpbl.org'); // hide our access key - - + // Skip checking certain IP addresses against blacklists (for troubleshooting or whatever) $config['dnsbl_exceptions'][] = '127.0.0.1'; - + /* * Introduction to Tinyboard's spam filter: * @@ -196,14 +218,17 @@ * See also: http://tinyboard.org/docs/?p=Your_request_looks_automated * */ - - // Number of hidden fields to generate + + // Number of hidden fields to generate. $config['spam']['hidden_inputs_min'] = 4; $config['spam']['hidden_inputs_max'] = 12; + // How many times can a "hash" be used to post? $config['spam']['hidden_inputs_max_pass'] = 12; + // How soon after regeneration do hashes expire (in seconds)? $config['spam']['hidden_inputs_expire'] = 60 * 60 * 3; // three hours + // These are fields used to confuse the bots. Make sure they aren't actually used by Tinyboard, or it won't work. $config['spam']['hidden_input_names'] = array( 'user', @@ -217,6 +242,7 @@ 'text', 'message' ); + // Always update this when adding new valid fields to the post form, or EVERYTHING WILL BE DETECTED AS SPAM! $config['spam']['valid_inputs'] = array( 'hash', @@ -238,38 +264,14 @@ 'spoiler', 'quick-reply' ); - - // Custom flood filters. Detect flood attacks and reject new posts if there's a positive match. - // See http://tinyboard.org/wiki/index.php?title=Flood_filters for more information. - //$config['flood_filters'][] = array( - // 'condition' => array( - // // 100 posts in the past 5 minutes (~20 p/m) - // 'posts_in_past_x_minutes' => array(100, 5) - // ), - // // Don't allow the user to post - // 'action' => 'reject', - // // Display this message - // 'message' => 'Your post has been rejected on the suspicion of a flood attack on this board.' - //); - - // Another filter - //$config['flood_filters'][] = array( - // 'condition' => array( - // // 10 new empty threads in the past 2 minutes - // 'threads_with_no_replies_in_past_x_minutes' => array(10, 2), - // // Allow replies, but not new threads (ie. reject topics only). - // 'OP' => true - // ), - // 'action' => 'reject', - // 'message' => 'Your post has been rejected on the suspicion of a flood attack on this board (too many new threads); post a reply instead.' - //); - - // Enable reCaptcha to make spam even harder + + // Enable reCaptcha to make spam even harder. Rarely necessary. $config['recaptcha'] = false; + // Public and private key pair from https://www.google.com/recaptcha/admin/create $config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f'; $config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_'; - + /* * ==================== * Post settings @@ -279,103 +281,155 @@ // Do you need a body for your reply posts? $config['force_body'] = false; // Do you need a body for new threads? - $config['force_body_op'] = true; - // Strip superfluous new lines at the end of a post - $config['strip_superfluous_returns'] = true; + $config['force_body_op'] = true; // Require an image for threads? $config['force_image_op'] = true; - // Strip combining characters from Unicode strings (eg. "Zalgo") + + // Strip superfluous new lines at the end of a post. + $config['strip_superfluous_returns'] = true; + // Strip combining characters from Unicode strings (eg. "Zalgo"). $config['strip_combining_chars'] = true; - - // Max body length + + // Maximum post body length. $config['max_body'] = 1800; - // Amount of post lines to show on the index page + // Maximum number of post body lines to show on the index page. $config['body_truncate'] = 15; - // Amount of characters to show on the index page + // Maximum number of characters to show on the index page. $config['body_truncate_char'] = 2500; - - // Typically spambots try to post a lot of links. Refuse a post with X standalone links? + + // Typically spambots try to post many links. Refuse a post with X links? $config['max_links'] = 20; - // Maximum number of cites per post (protects against abuse) + // Maximum number of cites per post (prevents abuse, as more citations mean more database queries). $config['max_cites'] = 45; - // Maximum number of cross-board links/cites per post + // Maximum number of cross-board links/citations per post. $config['max_cross'] = $config['max_cites']; - + // Track post citations (>>XX). Rebuilds posts after a cited post is deleted, removing broken links. - // A little more database load. + // Puts a little more load on the database. $config['track_cites'] = true; - - // Maximum filename length (will be truncated) + + // Maximum filename length (will be truncated). $config['max_filename_len'] = 255; - // Maximum filename length to display (the rest can be viewed upon mouseover) + // Maximum filename length to display (the rest can be viewed upon mouseover). $config['max_filename_display'] = 30; - - // How long before you can delete a post after posting, in seconds. + + // How long after posting should you have to wait before being able to delete that post? (In seconds.) $config['delete_time'] = 10; - // Reply limit (stops bumping thread when this is reached) + // Reply limit (stops bumping thread when this is reached). $config['reply_limit'] = 250; - - // Image hard limit (stops allowing new image replies when this is reached if not zero) + + // Image hard limit (stops allowing new image replies when this is reached if not zero). $config['image_hard_limit'] = 0; - // Reply hard limit (stops allowing new replies when this is reached if not zero) + // Reply hard limit (stops allowing new replies when this is reached if not zero). $config['reply_hard_limit'] = 0; - - // Strip repeating characters when making hashes + + $config['robot_enable'] = false; + // Strip repeating characters when making hashes. $config['robot_strip_repeating'] = true; - - // Enable mutes - // Tinyboard uses ROBOT9000's original 2^x implementation + // Enabled mutes? Tinyboard uses ROBOT9000's original 2^x implementation where x is the number of times + // you have been muted in the past. $config['robot_mute'] = true; - // How many mutes x hours ago to include in the algorithm + // How long before Tinyboard forgets about a mute? $config['robot_mute_hour'] = 336; // 2 weeks - // If you want to alter the algorithm a bit. Default value is 2. n^x - $config['robot_mute_multiplier'] = 2; + // If you want to alter the algorithm a bit. Default value is 2. + $config['robot_mute_multiplier'] = 2; // (n^x where x is the number of previous mutes) $config['robot_mute_descritpion'] = _('You have been muted for unoriginal content.'); - - // Automatically convert things like "..." to Unicode characters ("…") + + // Automatically convert things like "..." to Unicode characters ("…"). $config['auto_unicode'] = true; - // Whether to turn URLs into functional links + // Whether to turn URLs into functional links. $config['markup_urls'] = true; - // Optional URL prefix for links (eg. "http://anonym.to/?") + // Optional URL prefix for links (eg. "http://anonym.to/?"). $config['link_prefix'] = ''; - - - // Wordfilters are used to automatically replace certain words/phrases with something else. + + + // A wordfilter (sometimes referred to as just a "filter" or "censor") automatically scans users’ posts + // as they are submitted and changes or censors particular words or phrases. + // For a normal string replacement: - // $config['wordfilters'][] = array('cat', 'dog'); - + // $config['wordfilters'][] = array('cat', 'dog'); // Advanced raplcement (regular expressions): - // $config['wordfilters'][] = array('/cat/', 'dog', true); // 'true' means it's a regular expression - - // Always act as if they had typed "noko" in the email field no mattter what + // $config['wordfilters'][] = array('/ca[rt]/', 'dog', true); // 'true' means it's a regular expression + + // Always act as if the user had typed "noko" into the email field. $config['always_noko'] = false; - - // Custom tripcodes. The below example makes a tripcode - // of "#test123" evaluate to "!HelloWorld" + + // Custom tripcodes. The below example makes a tripcode of "#test123" evaluate to "!HelloWorld". // $config['custom_tripcode']['#test123'] = '!HelloWorld'; // $config['custom_tripcode']['##securetrip'] = '!!somethingelse'; - - // Optional spoiler images + + // Allow users to mark their image as a "spoiler" when posting. The thumbnail will be replaced with a + // static spoiler image instead (see $config['spoiler_image']). $config['spoiler_images'] = false; - - + // With the following, you can disable certain superfluous fields or enable "forced anonymous". - + // When true, all names will be set to $config['anonymous']. $config['field_disable_name'] = false; - // When true, no email will be able to be set. + // When true, there will be no email field. $config['field_disable_email'] = false; - // When true, no subject will be able to be set. + // When true, there will be no subject field. $config['field_disable_subject'] = false; - // When true, no subject will be able to be set in replies. + // When true, there will be no subject field for replies. $config['field_disable_reply_subject'] = false; // When true, a blank password will be used for files (not usable for deletion). $config['field_disable_password'] = false; - - // Require users to see the ban page at least once for a ban even if it has since expired? - $config['require_ban_view'] = false; - + + // Require users to see the ban page at least once for a ban even if it has since expired. + $config['require_ban_view'] = true; + + /* + * Custom filters detect certain posts and reject/ban accordingly. They are made up of a + * condition and an action (for when ALL conditions are met). As every single post has to + * be put through each filter, having hundreds probably isn’t ideal as it could slow things down. + * + * Read more: http://tinyboard.org/docs/index.php?p=Config/Filters + * + * This used to be named $config['flood_filters'] (still exists as an alias). + */ + + // An example of blocking an imaginary known spammer, who keeps posting a reply with the name "surgeon", + // ending his posts with "regards, the surgeon" or similar. + // $config['filters'][] = array( + // 'condition' => array( + // 'name' => '/^surgeon$/', + // 'body' => '/regards,\s+(the )?surgeon$/i', + // 'OP' => false + // ), + // 'action' => 'reject', + // 'message' => 'Go away, spammer.' + // ); + + // Same as above, but issuing a 3-hour ban instead of just reject the post. + // $config['filters'][] = array( + // 'condition' => array( + // 'name' => '/^surgeon$/', + // 'body' => '/regards,\s+(the )?surgeon$/i', + // 'OP' => false + // ), + // 'action' => 'ban', + // 'expires' => 60 * 60 * 3, // 3 hours + // 'reason' => 'Go away, spammer.' + // ); + + // PHP 5.3+ (anonymous functions) + // There is also a "custom" condition, making the possibilities of this feature pretty much endless. + // This is a bad example, because there is already a "name" condition built-in. + // $config['filters'][] = array( + // 'condition' => array( + // 'body' => '/h$/i', + // 'OP' => false, + // 'custom' => function($post) { + // if($post['name'] == 'Anonymous') + // return true; + // else + // return false; + // } + // ), + // 'action' => 'reject' + // ); + /* * ==================== * Markup settings @@ -386,122 +440,136 @@ $config['markup'][] = array("/'''([^<]+?)'''/", "\$1"); $config['markup'][] = array("/''([^<]+?)''/", "\$1"); $config['markup'][] = array("/\*\*([^<]+?)\*\*/", "\$1"); - $config['markup'][] = array("/^[ |\t]*==([^<]+?)==[ |\t]*$/m", "\$1"); - - // Highlight PHP code wrapped in tags (PHP 5.3.0+) + // $config['markup'][] = array("/^[ |\t]*==([^<]+?)==[ |\t]*$/m", "\$1"); + + // Highlight PHP code wrapped in tags (PHP 5.3+) // $config['markup'][] = array( // '/^<code>(.+)<\/code>/ms', // function($matches) { // return highlight_string(html_entity_decode($matches[1]), true); // } // ); - + /* * ==================== * Image settings * ==================== */ - - // For resizing, max thumbnail size + + // For resizing, maximum thumbnail dimensions. $config['thumb_width'] = 255; $config['thumb_height'] = 255; - // Max thumbnail size for thread images + // Maximum thumbnail dimensions for thread (OP) images. $config['thumb_op_width'] = 255; $config['thumb_op_height'] = 255; - - // Thumbnail extension, empty for inherited (png recommended) + + // Thumbnail extension ("png" recommended). Leave this empty if you want the extension to be inherited + // from the uploaded file. $config['thumb_ext'] = 'png'; - - // Maximum amount of frames to resize (more frames means more processing power). "1" means no animated thumbnails. - // Requires $config['thumb_ext'] to be 'gif' and $config['thumb_method'] to be 'imagick', 'convert', or 'convert+gifsicle'. - // Not respected by 'convert'; will just resize all frames if this is > 1. + + // Maximum amount of animated GIF frames to resize (more frames can mean more processing power). A value + // of "1" means thumbnails will not be animated. Requires $config['thumb_ext'] to be 'gif' (or blank) and + // $config['thumb_method'] to be 'imagick', 'convert', or 'convert+gifsicle'. This value is not respected + // by 'convert'; will just resize all frames if this is > 1. $config['thumb_keep_animation_frames'] = 1; - - // Thumbnailing method: - // - 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG). - // This is a prerequisite for Tinyboard no matter what method you choose. - // - 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats. - // A few minor bugs. http://pecl.php.net/package/imagick - // - 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in - // PHP Imagick. `convert` produces the best still thumbnails and is highly recommended. - // - 'convert+gifsicle' Same as above, with the exception of using `gifsicle` (command line application) - // instead of `convert` for resizing GIFs. It's faster and resulting animated thumbnails - // have less artifacts than if resized with ImageMagick. + + /* + * Thumbnailing method: + * + * 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG). + * GD is a prerequisite for Tinyboard no matter what method you choose. + * + * 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats. + * A few minor bugs. http://pecl.php.net/package/imagick + * + * 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in + * PHP Imagick. `convert` produces the best still thumbnails and is highly recommended. + * + * 'convert+gifsicle' Same as above, with the exception of using `gifsicle` (command line application) + * instead of `convert` for resizing GIFs. It's faster and resulting animated + * thumbnails have less artifacts than if resized with ImageMagick. + */ $config['thumb_method'] = 'gd'; // $config['thumb_method'] = 'convert'; - - // Strip EXIF metadata from JPEG files + + // Command-line options passed to ImageMagick when using `convert` for thumbnailing. + // http://www.imagemagick.org/ImageMagick-7.0.0/script/command-line-options.php + $config['convert_args'] = '-background transparent -filter Point -sample %dx%d +antialias -quality 50'; + + // Strip EXIF metadata from JPEG files. $config['strip_exif'] = false; - - // Regular expression to check for IE MIME type detection XSS exploit. To disable, comment the line out - // https://github.com/savetheinternet/Tinyboard/issues/20 + + // Regular expression to check for an XSS exploit with IE 6 and 7. To disable, set to false. + // Details: https://github.com/savetheinternet/Tinyboard/issues/20 $config['ie_mime_type_detection'] = '/<(?:body|head|html|img|plaintext|pre|script|table|title|a href|channel|scriptlet)/i'; - - // Allowed image file extensions + + // Allowed image file extensions. $config['allowed_ext'][] = 'jpg'; $config['allowed_ext'][] = 'jpeg'; $config['allowed_ext'][] = 'bmp'; $config['allowed_ext'][] = 'gif'; $config['allowed_ext'][] = 'png'; // $config['allowed_ext'][] = 'svg'; - - // Allowed additional file extensions (not images; downloadable files) + + // Allowed additional file extensions (not images; downloadable files). // $config['allowed_ext_files'][] = 'txt'; // $config['allowed_ext_files'][] = 'zip'; - - // An alternative function for generating a filename, instead of the default UNIX timestamp. - // http://tinyboard.org/wiki/index.php?title=Filenames - // $config['filename_func'] = 'some_function_you_have_created'; - - // Non-image file icons + + // An alternative function for generating image filenames, instead of the default UNIX timestamp. + // $config['filename_func'] = function($post) { + // return sprintf("%s", time() . substr(microtime(), 2, 3)); + // }; + + // Thumbnail to use for the non-image file uploads. $config['file_icons']['default'] = 'file.png'; $config['file_icons']['zip'] = 'zip.png'; - - // Thumbnail to use for the downloadable files (not images) + // $config['file_icons']['extension'] = 'some_file.png'; + + // Location of above images. $config['file_thumb'] = 'static/%s'; - // Thumbnail to use for spoiler images + // Location of thumbnail to use for spoiler images. $config['spoiler_image'] = 'static/spoiler.png'; - - // Thumbnail quality (compression level), from 0 to 9 - $config['thumb_quality'] = 8; - - // When a thumbnailed image is going to be the same (in dimension), just copy the entire file and use that as a thumbnail instead of resizing/redrawing + // Location of thumbnail to use for deleted images. + $config['image_deleted'] = $config['dir']['static'] . 'deleted.png'; + + // When a thumbnailed image is going to be the same (in dimension), just copy the entire file and use + // that as a thumbnail instead of resizing/redrawing. $config['minimum_copy_resize'] = false; - - // Store image hash in the database for r9k-like boards implementation soon - // Function name for hashing + + // Image hashing function. There's really no reason to change this. // sha1_file, md5_file, etc. You can also define your own similar function. $config['file_hash'] = 'sha1_file'; - - // Maximum image upload size in bytes - $config['max_filesize'] = 10*1024*1024; // 10MB - // Maximum image dimensions + + // Maximum image upload size in bytes. + $config['max_filesize'] = 10 * 1024 * 1024; // 10MB + // Maximum image dimensions. $config['max_width'] = 10000; - $config['max_height'] = $config['max_width']; // 1:1 - // Reject duplicate image uploads + $config['max_height'] = $config['max_width']; + // Reject duplicate image uploads. $config['image_reject_repost'] = true; - // Reject duplicate image uploads within the same thread. Doesn't change anything if image_reject_repost is true. + // Reject duplicate image uploads within the same thread. Doesn't change anything if + // $config['image_reject_repost'] is true. $config['image_reject_repost_in_thread'] = false; - - // Display the aspect ratio in a post's file info + + // Display the aspect ratio of uploaded files. $config['show_ratio'] = false; - // Display the file's original filename + // Display the file's original filename. $config['show_filename']= true; - // Image identification links using regex.info/exif, TinEye and Google Images + // Display image identification links using regex.info/exif, TinEye and Google Images. $config['image_identification'] = false; - - // Redraw the image using GD functions to strip any excess data (commonly ZIP archives) - // WARNING: Currently strips animated GIFs too + + // Redraw the image to strip any excess data (commonly ZIP archives) WARNING: This might strip the + // animation of GIFs, depending on the chosen thumbnailing method. $config['redraw_image'] = false; - + /* * ==================== * Board settings * ==================== */ - // Maximum amount of threads to display on a given page. + // Maximum amount of threads to display per page. $config['threads_per_page'] = 10; // Maximum number of pages. Content past the last page is automatically purged. $config['max_pages'] = 10; @@ -510,106 +578,111 @@ // Same as above, but for stickied threads. $config['threads_preview_sticky'] = 1; - // Name of the boards. Usually '/%s/' (/b/, /mu/, etc) - // $config['board_abbreviation'] - BOARD_TITLE + // How to display the URI of boards. Usually '/%s/' (/b/, /mu/, etc). This doesn't change the URL. Find + // $config['board_path'] if you wish to change the URL. $config['board_abbreviation'] = '/%s/'; - - // The default name (ie. Anonymous) + + // The default name (ie. Anonymous). $config['anonymous'] = 'Anonymous'; - - // How many reports you can create in the same request. + + // Number of reports you can create at once. $config['report_limit'] = 3; - + /* * ==================== * Display settings * ==================== */ - - // Locale (en, ru_RU.UTF-8, fi_FI.UTF-8, pl_PL.UTF-8) - $config['locale'] = 'en'; - - // Timezone + + // Tinyboard has been translated into a few langauges. See inc/locale for available translations. + $config['locale'] = 'en'; // (en, ru_RU.UTF-8, fi_FI.UTF-8, pl_PL.UTF-8) + + // Timezone to use for displaying dates/tiems. $config['timezone'] = 'America/Los_Angeles'; - - // The format string passed to strftime() for post times + // The format string passed to strftime() for displaying dates. // http://www.php.net/manual/en/function.strftime.php $config['post_date'] = '%m/%d/%y (%a) %H:%M:%S'; - // Same as above, but used for "you are banned' pages. $config['ban_date'] = '%A %e %B, %Y'; - - // The names on the post buttons. (On most imageboards, these are both "Post") + + // The names on the post buttons. (On most imageboards, these are both just "Post"). $config['button_newtopic'] = _('New Topic'); $config['button_reply'] = _('New Reply'); - - // Assign each poster in a thread a unique ID, shown by "ID: {id}" before the post number. + + // Assign each poster in a thread a unique ID, shown by "ID: xxxxx" before the post number. $config['poster_ids'] = false; - // Number of characters in the poster ID (maximum is 40) + // Number of characters in the poster ID (maximum is 40). $config['poster_id_length'] = 5; - - // Show thread subject in page title? + + // Show thread subject in page title. $config['thread_subject_in_title'] = false; - - // Page footer + + // Additional lines added to the footer of all pages. $config['footer'][] = _('All trademarks, copyrights, comments, and images on this page are owned by and are the responsibility of their respective parties.'); - - // Characters used to generate a random password (with Javascript) + + // Characters used to generate a random password (with Javascript). $config['genpassword_chars'] = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+'; - - // Optional banner at the top of every page. + + // Optional banner image at the top of every page. // $config['url_banner'] = '/banner.php'; - // Banner dimensions are also optional. As the banner loads after the rest of the page, everything - // may be shifted down a few pixels when it does. Making the banner a fixed size will prevent this. + // Banner dimensions are also optional. As the banner loads after the rest of the page, everything may be + // shifted down a few pixels when it does. Making the banner a fixed size will prevent this. // $config['banner_width'] = 300; // $config['banner_height'] = 100; - - // Custom stylesheets available. The prefix for each stylesheet URI is defined below. - $config['stylesheets']['Yotsuba B'] = ''; // default + + // Custom stylesheets available for the user to choose. See the "stylesheets/" folder for a list of + // available stylesheets (or create your own). + $config['stylesheets']['Yotsuba B'] = ''; // Default; there is no additional/custom stylesheet for this. $config['stylesheets']['Yotsuba'] = 'yotsuba.css'; // $config['stylesheets']['Futaba'] = 'futaba.css'; - + // $config['stylesheets']['Dark'] = 'dark.css'; + // The prefix for each stylesheet URI. Defaults to $config['root']/stylesheets/ // $config['uri_stylesheets'] = 'http://static.example.org/stylesheets/'; - - // The default stylesheet to use + + // The default stylesheet to use. $config['default_stylesheet'] = array('Yotsuba B', $config['stylesheets']['Yotsuba B']); - - // Make stylesheet selections board-specific + + // Make stylesheet selections board-specific. $config['stylesheets_board'] = false; - + // Use Font-Awesome for displaying lock and pin icons, instead of the images in static/. // http://fortawesome.github.io/Font-Awesome/icon/pushpin/ // http://fortawesome.github.io/Font-Awesome/icon/lock/ $config['font_awesome'] = true; $config['font_awesome_css'] = 'stylesheets/font-awesome/css/font-awesome.min.css'; - - // Boardlinks - // You can group, order and place the boardlist at the top of every page, using the following template. - //$config['boards'] = array( - // array('a', 'b'), - // array('c', 'd', 'e', 'f', 'g'), - // array('h', 'i', 'j'), - // array('k', array('l', 'm')), - // array('status' => 'http://status.example.org/') - //); - - // Categories - // Required for the Categories theme. - //$config['categories'] = array( - // 'Group Name' => array('a', 'b', 'c'), - // 'Another Group' => array('d') - //); - - // Custom_categories - // Optional for the Categories theme. array of name => (title, url) groups for categories with non-board links. - //$config['custom_categories'] = array( - // 'Links' => array( - // 'Tinyboard' => 'http://tinyboard.org', - // 'Donate' => 'donate.html' - // ) - //); - + + /* + * For lack of a better name, “boardlinks” are those sets of navigational links that appear at the top + * and bottom of board pages. They can be a list of links to boards and/or other pages such as status + * blogs and social network profiles/pages. + * + * "Groups" in the boardlinks are marked with square brackets. Tinyboard allows for infinite recursion + * with groups. Each array() in $config['boards'] represents a new square bracket group. + */ + + // $config['boards'] = array( + // array('a', 'b'), + // array('c', 'd', 'e', 'f', 'g'), + // array('h', 'i', 'j'), + // array('k', array('l', 'm')), + // array('status' => 'http://status.example.org/') + // ); + + // Board categories. Only used in the "Categories" theme. + // $config['categories'] = array( + // 'Group Name' => array('a', 'b', 'c'), + // 'Another Group' => array('d') + // ); + // Optional for the Categories theme. This is an array of name => (title, url) groups for categories + // with non-board links. + // $config['custom_categories'] = array( + // 'Links' => array( + // 'Tinyboard' => 'http://tinyboard.org', + // 'Donate' => 'donate.html' + // ) + // ); + // Automatically remove unnecessary whitespace when compiling HTML files from templates. $config['minify_html'] = true; @@ -619,25 +692,31 @@ * ==================== */ - // Additional Javascript files to include on board index and thread pages. + // Additional Javascript files to include on board index and thread pages. See js/ for available scripts. $config['additional_javascript'][] = 'js/inline-expanding.js'; // $config['additional_javascript'][] = 'js/local-time.js'; - - // Some scripts require jQuery. Check the comments in script files to see what's needed. + + // Some scripts require jQuery. Check the comments in script files to see what's needed. When enabling + // jQuery, you should first empty the array so that "js/query.min.js" can be the first, and then re-add + // "js/inline-expanding.js" or else the inline-expanding script might not interact properly with other + // scripts. + // $config['additional_javascript'] = array(); // $config['additional_javascript'][] = 'js/jquery.min.js'; + // $config['additional_javascript'][] = 'js/inline-expanding.js'; // $config['additional_javascript'][] = 'js/auto-reload.js'; - - // Where these script files are located on the web (defaults to $config['root']). - // $config['additional_javascript_url'] = '/js/'; - + // $config['additional_javascript'][] = 'js/post-hover.js'; + // $config['additional_javascript'][] = 'js/style-select.js'; + + // Where these script files are located on the web. Defaults to $config['root']. + // $config['additional_javascript_url'] = 'http://static.example.org/tinyboard-javascript-stuff/'; + // Compile all additional scripts into one file ($config['file_script']) instead of including them seperately. $config['additional_javascript_compile'] = false; - - // Minify Javascript using http://code.google.com/p/minify/ + + // Minify Javascript using http://code.google.com/p/minify/. $config['minify_js'] = false; - // Allows js/quick-reply.js to work - // This will make your imageboard more vulnerable to flood attacks. + // Allows js/quick-reply.js to work. This could make your imageboard more vulnerable to flood attacks. $config['quick_reply'] = false; /* @@ -645,12 +724,12 @@ * Video embedding * ==================== */ - - // Enable embedding (see below) + + // Enable embedding (see below). $config['enable_embedding'] = false; - + // Custom embedding (YouTube, vimeo, etc.) - // It's very important that you match the full string (with ^ and $) or things will not work correctly. + // It's very important that you match the entire input (with ^ and $) or things will not work correctly. $config['embedding'] = array( array( '/^https?:\/\/(\w+\.)?youtube\.com\/watch\?v=([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', @@ -677,39 +756,39 @@ '' ) ); - - // Embedding width and height + + // Embedding width and height. $config['embed_width'] = 300; $config['embed_height'] = 246; - + /* * ==================== * Error messages * ==================== */ - + // Error messages - $config['error']['lurk'] = _('Lurk some more before posting.'); - $config['error']['bot'] = _('You look like a bot.'); - $config['error']['referer'] = _('Your browser sent an invalid or no HTTP referer.'); - $config['error']['toolong'] = _('The %s field was too long.'); + $config['error']['lurk'] = _('Lurk some more before posting.'); + $config['error']['bot'] = _('You look like a bot.'); + $config['error']['referer'] = _('Your browser sent an invalid or no HTTP referer.'); + $config['error']['toolong'] = _('The %s field was too long.'); $config['error']['toolong_body'] = _('The body was too long.'); $config['error']['tooshort_body'] = _('The body was too short or empty.'); - $config['error']['noimage'] = _('You must upload an image.'); - $config['error']['nomove'] = _('The server failed to handle your upload.'); - $config['error']['fileext'] = _('Unsupported image format.'); - $config['error']['noboard'] = _('Invalid board!'); + $config['error']['noimage'] = _('You must upload an image.'); + $config['error']['nomove'] = _('The server failed to handle your upload.'); + $config['error']['fileext'] = _('Unsupported image format.'); + $config['error']['noboard'] = _('Invalid board!'); $config['error']['nonexistant'] = _('Thread specified does not exist.'); - $config['error']['locked'] = _('Thread locked. You may not reply at this time.'); + $config['error']['locked'] = _('Thread locked. You may not reply at this time.'); $config['error']['reply_hard_limit'] = _('Thread has reached its maximum reply limit.'); $config['error']['image_hard_limit'] = _('Thread has reached its maximum image limit.'); - $config['error']['nopost'] = _('You didn\'t make a post.'); - $config['error']['flood'] = _('Flood detected; Post discarded.'); - $config['error']['spam'] = _('Your request looks automated; Post discarded.'); + $config['error']['nopost'] = _('You didn\'t make a post.'); + $config['error']['flood'] = _('Flood detected; Post discarded.'); + $config['error']['spam'] = _('Your request looks automated; Post discarded.'); $config['error']['unoriginal'] = _('Unoriginal content!'); - $config['error']['muted'] = _('Unoriginal content! You have been muted for %d seconds.'); + $config['error']['muted'] = _('Unoriginal content! You have been muted for %d seconds.'); $config['error']['youaremuted'] = _('You are muted! Expires in %d seconds.'); - $config['error']['dnsbl'] = _('Your IP address is listed in %s.'); + $config['error']['dnsbl'] = _('Your IP address is listed in %s.'); $config['error']['toomanylinks'] = _('Too many links; flood detected.'); $config['error']['toomanycites'] = _('Too many cites; post discarded.'); $config['error']['toomanycross'] = _('Too many cross-board links; post discarded.'); @@ -720,19 +799,19 @@ $config['error']['invalidimg'] = _('Invalid image.'); $config['error']['unknownext'] = _('Unknown file extension.'); $config['error']['filesize'] = _('Maximum file size: %maxsz% bytes
    Your file\'s size: %filesz% bytes'); - $config['error']['maxsize'] = _('The file was too big.'); + $config['error']['maxsize'] = _('The file was too big.'); $config['error']['invalidzip'] = _('Invalid archive!'); $config['error']['fileexists'] = _('That file already exists!'); $config['error']['fileexistsinthread'] = _('That file already exists in this thread!'); $config['error']['delete_too_soon'] = _('You\'ll have to wait another %s before deleting that.'); $config['error']['mime_exploit'] = _('MIME type detection XSS exploit (IE) detected; post discarded.'); $config['error']['invalid_embed'] = _('Couldn\'t make sense of the URL of the video you tried to embed.'); - $config['error']['captcha'] = _('You seem to have mistyped the verification.'); - + $config['error']['captcha'] = _('You seem to have mistyped the verification.'); + // Moderator errors $config['error']['toomanyunban'] = _('You are only allowed to unban %s users at a time. You tried to unban %u users.'); - $config['error']['invalid'] = _('Invalid username and/or password.'); - $config['error']['notamod'] = _('You are not a mod…'); + $config['error']['invalid'] = _('Invalid username and/or password.'); + $config['error']['notamod'] = _('You are not a mod…'); $config['error']['invalidafter'] = _('Invalid username and/or password. Your user may have been deleted or changed.'); $config['error']['malformed'] = _('Invalid/malformed cookies.'); $config['error']['missedafield'] = _('Your browser didn\'t submit an input when it should have.'); @@ -741,98 +820,96 @@ $config['error']['boardexists'] = _('There is already a %s board.'); $config['error']['noaccess'] = _('You don\'t have permission to do that.'); $config['error']['invalidpost'] = _('That post doesn\'t exist…'); - $config['error']['404'] = _('Page not found.'); + $config['error']['404'] = _('Page not found.'); $config['error']['modexists'] = _('That mod already exists!'); $config['error']['invalidtheme'] = _('That theme doesn\'t exist!'); - $config['error']['csrf'] = _('Invalid security token! Please go back and try again.'); + $config['error']['csrf'] = _('Invalid security token! Please go back and try again.'); /* * ========================= * Directory/file settings * ========================= */ - + // The root directory, including the trailing slash, for Tinyboard. - // examples: '/', 'http://boards.chan.org/', '/chan/' + // Examples: '/', 'http://boards.chan.org/', '/chan/'. if (isset($_SERVER['REQUEST_URI'])) - $config['root'] = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/'); + $config['root'] = str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/'; else $config['root'] = '/'; // CLI mode // The scheme and domain. This is used to get the site's absolute URL (eg. for image identification links). // If you use the CLI tools, it would be wise to override this setting. - $config['domain'] = (isset ($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? "https://" : "http://"; - $config['domain'] .= isset ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; - + $config['domain'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? 'https://' : 'http://'; + $config['domain'] .= isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; + // If for some reason the folders and static HTML index files aren't in the current working direcotry, // enter the directory path here. Otherwise, keep it false. $config['root_file'] = false; - + + // Location of files. $config['file_index'] = 'index.html'; $config['file_page'] = '%d.html'; $config['file_mod'] = 'mod.php'; $config['file_post'] = 'post.php'; $config['file_script'] = 'main.js'; - - // Board directory, followed by a forward-slash (/). (%s is board abbreviation) + + // Board directory, followed by a forward-slash (/). $config['board_path'] = '%s/'; - + // Misc directories. $config['dir']['img'] = 'src/'; $config['dir']['thumb'] = 'thumb/'; $config['dir']['res'] = 'res/'; - // For load balancing, having a seperate server (and domain/subdomain) for serving static content is possible. - // This can either be a directory or a URL (eg. http://static.example.org/) - //$config['dir']['static'] = $config['root'] . 'static/'; - // Where to store the .html templates. This folder and templates must exist or fatal errors will be thrown. + + // For load balancing, having a seperate server (and domain/subdomain) for serving static content is + // possible. This can either be a directory or a URL. Defaults to $config['root'] . 'static/'. + // $config['dir']['static'] = 'http://static.example.org/'; + + // Where to store the .html templates. This folder and the template files must exist. $config['dir']['template'] = getcwd() . '/templates'; - // For the themes (homepages, etc.) + // Location of Tinyboard "themes". $config['dir']['themes'] = getcwd() . '/templates/themes'; - // Same as above, but a URI (accessable by web interface, not locally) + // Same as above, but a URI (accessable by web interface). $config['dir']['themes_uri'] = 'templates/themes'; - // Homepage directory + // Home directory. Used by themes. $config['dir']['home'] = ''; - - // Static images - // These can be URLs OR base64 (data URI scheme) - //$config['image_sticky'] = $config['dir']['static'] . 'sticky.gif'; - //$config['image_locked'] = $config['dir']['static'] . 'locked.gif'; - //$config['image_bumplocked'] = $config['dir']['static'] . 'sage.gif'; - //$config['image_deleted'] = $config['dir']['static'] . 'deleted.'; - //$config['image_zip'] = $config['dir']['static'] . 'zip.'; - - // If you want to put images and other dynamic-static stuff on another (preferably cookieless) domain, you can use this: - // This will override $config['root'] and $config['dir']['...'] directives. - // "%s" will get replaced with $board['dir'], which usually includes a trailing slash. To avoid double slashes, you don't need - // to put a slash after %s + + // Static images. These can be URLs OR base64 (data URI scheme). These are only used if + // $config['font_awesome'] is false (default). + // $config['image_sticky'] = $config['dir']['static'] . 'sticky.gif'; + // $config['image_locked'] = $config['dir']['static'] . 'locked.gif'; + // $config['image_bumplocked'] = $config['dir']['static'] . 'sage.gif'. + + // If you want to put images and other dynamic-static stuff on another (preferably cookieless) domain. + // This will override $config['root'] and $config['dir']['...'] directives. "%s" will get replaced with + // $board['dir'], which includes a trailing slash. // $config['uri_thumb'] = 'http://images.example.org/%sthumb/'; // $config['uri_img'] = 'http://images.example.org/%ssrc/'; - - // Set custom locations for stylesheets, scripts and maybe a banner. - // This can be good for load balancing across multiple servers or hostnames. + + // Set custom locations for stylesheets and the main script file. This can be used for load balancing + // across multiple servers or hostnames. // $config['url_stylesheet'] = 'http://static.example.org/style.css'; // main/base stylesheet // $config['url_javascript'] = 'http://static.example.org/main.js'; + + // Website favicon. // $config['url_favicon'] = '/favicon.gif'; - + /* * ==================== * Mod settings * ==================== */ - - // Limit how many bans can be removed via the ban list. (Set too -1 to remove limit.) - $config['mod']['unban_limit'] = 5; - - // Whether or not to lock moderator sessions to the IP address that was logged in with. + + // Limit how many bans can be removed via the ban list. Set to -1 for no limit. + $config['mod']['unban_limit'] = -1; + + // Whether or not to lock moderator sessions to IP addresses. This makes cookie theft ineffective. $config['mod']['lock_ip'] = true; - - // The page that is first shown when a moderator logs in. Defaults to the dashboard. + + // The page that is first shown when a moderator logs in. Defaults to the dashboard (?/). $config['mod']['default'] = '/'; - - // Don't even display MySQL password to administrators (in the configuration page). - $config['mod']['never_reveal_password'] = true; - - // Mod links (full HTML) - // Correspond to above permission directives + + // Mod links (full HTML). $config['mod']['link_delete'] = '[D]'; $config['mod']['link_ban'] = '[B]'; $config['mod']['link_bandelete'] = '[B&D]'; @@ -847,92 +924,94 @@ $config['mod']['link_bumpunlock'] = '[-Sage]'; $config['mod']['link_editpost'] = '[Edit]'; $config['mod']['link_move'] = '[Move]'; - - // Moderator capcodes + + // Moderator capcodes. $config['capcode'] = ' ## %s'; - - // Custom capcodes, by example: - // "## Custom" becomes lightgreen, italic and bold + + // "## Custom" becomes lightgreen, italic and bold: //$config['custom_capcode']['Custom'] =' ## %s'; - - // "## Mod" makes everything purple, including the name and tripcode + + // "## Mod" makes everything purple, including the name and tripcode: //$config['custom_capcode']['Mod'] = array( // ' ## %s', // 'color:purple', // Change name style; optional // 'color:purple' // Change tripcode style; optional //); - - // "## Admin" makes everything red and bold, including the name and tripcode + + // "## Admin" makes everything red and bold, including the name and tripcode: //$config['custom_capcode']['Admin'] = array( // ' ## %s', // 'color:red;font-weight:bold', // Change name style; optional // 'color:red;font-weight:bold' // Change tripcode style; optional //); - - // Enable IP range bans (eg. "127.*.0.1", "127.0.0.*", and "12*.0.0.1" all match "127.0.0.1"). - // A little more load on the database + + // Enable IP range bans (eg. "127.*.0.1", "127.0.0.*", and "12*.0.0.1" all match "127.0.0.1"). Puts a + // little more load on the database $config['ban_range'] = true; - - // Enable CDIR netmask bans (eg. "10.0.0.0/8" for 10.0.0.0.0 - 10.255.255.255). Useful for stopping persistent spammers. - // Again, a little more database load. + + // Enable CDIR netmask bans (eg. "10.0.0.0/8" for 10.0.0.0.0 - 10.255.255.255). Useful for stopping + // persistent spammers and ban evaders. Again, a little more database load. $config['ban_cidr'] = true; - - // Do a DNS lookup on IP addresses to get their hostname on the IP summary page + + // Do DNS lookups on IP addresses to get their hostname for the moderator IP pages (?/IP/x.x.x.x). $config['mod']['dns_lookup'] = true; - // How many recent posts, per board, to show in the IP summary page + // How many recent posts, per board, to show in ?/IP/x.x.x.x. $config['mod']['ip_recentposts'] = 5; - - // How many posts to display on the reports page + + // Number of posts to display on the reports page. $config['mod']['recent_reports'] = 10; - - // How many actions to show per page in the moderation log + // Number of actions to show per page in the moderation log. $config['mod']['modlog_page'] = 350; - // How many bans to show per page in the ban list + // Number of bans to show per page in the ban list. $config['mod']['banlist_page'] = 350; - - // Number of news entries to display per page + // Number of news entries to display per page. $config['mod']['news_page'] = 40; - - // Number of results to display per page + // Number of results to display per page. $config['mod']['search_page'] = 200; - - // How many entries to show per page in the moderator noticeboard + // Number of entries to show per page in the moderator noticeboard. $config['mod']['noticeboard_page'] = 50; - // Number of entries to summarize and display on the dashboard + // Number of entries to summarize and display on the dashboard. $config['mod']['noticeboard_dashboard'] = 5; - - // Check public ban message by default + + // Check public ban message by default. $config['mod']['check_ban_message'] = false; - // Default public ban message. - // In public ban messages, %length% is replaced with "for x days" or "permanently" (with %LENGTH% being the uppercase equivalent). + // Default public ban message. In public ban messages, %length% is replaced with "for x days" or + // "permanently" (with %LENGTH% being the uppercase equivalent). $config['mod']['default_ban_message'] = _('USER WAS BANNED FOR THIS POST'); - // $config['mod']['default_ban_message'] = 'USER WAS BANNED %LENGTH% FOR THIS POST'; // Include length in ban message - // What to append to the post for public bans ("%s" is the message) + // $config['mod']['default_ban_message'] = 'USER WAS BANNED %LENGTH% FOR THIS POST'; + // HTML to append to post bodies for public bans messages (where "%s" is the message). $config['mod']['ban_message'] = '(%s)'; - - // When moving a thread to another board and choosing to keep a "shadow thread", an automated post (with a capcode) will - // be made, linking to the new location for the thread. "%s" will be replaced with a standard cross-board post citation (>>>/board/xxx) + + // When moving a thread to another board and choosing to keep a "shadow thread", an automated post (with + // a capcode) will be made, linking to the new location for the thread. "%s" will be replaced with a + // standard cross-board post citation (>>>/board/xxx) $config['mod']['shadow_mesage'] = 'Moved to %s.'; // Capcode to use when posting the above message. $config['mod']['shadow_capcode'] = 'Mod'; - // Name to use when posting the above message. If false, the default board name will be used. If something else, that will be used. + // Name to use when posting the above message. If false, $config['anonymous'] will be used. $config['mod']['shadow_name'] = false; - - // Wait indefinitely when rebuilding everything + + // PHP time limit for ?/rebuild. A value of 0 should cause PHP to wait indefinitely. $config['mod']['rebuild_timelimit'] = 0; - - // PM snippet (for ?/inbox) length in characters + + // PM snippet (for ?/inbox) length in characters. $config['mod']['snippet_length'] = 75; - - // Edit raw HTML in posts by default + + // Edit raw HTML in posts by default. $config['mod']['raw_html_default'] = false; - - // Automatically dismiss all reports regarding a thread when it is locked + + // Automatically dismiss all reports regarding a thread when it is locked. $config['mod']['dismiss_reports_on_lock'] = true; - - // Replace ?/config with a simple text editor for editing inc/instance-config.php + + // Replace ?/config with a simple text editor for editing inc/instance-config.php. $config['mod']['config_editor_php'] = false; - + +/* + * ==================== + * Mod permissions + * ==================== + */ + // Probably best not to change these: if (!defined('JANITOR')) { define('JANITOR', 0, true); @@ -940,31 +1019,24 @@ define('ADMIN', 2, true); define('DISABLED', 3, true); } - -/* - * ==================== - * Mod permissions - * ==================== - */ - - // Capcode permissions + + // Capcode permissions. $config['mod']['capcode'] = array( // JANITOR => array('Janitor'), - MOD => array('Mod'), + MOD => array('Mod'), ADMIN => true ); - + // Example: Allow mods to post with "## Moderator" as well // $config['mod']['capcode'][MOD][] = 'Moderator'; - // Example: Allow janitors to post with any capcode // $config['mod']['capcode'][JANITOR] = true; - - // Set any of the below to "DISABLED" to make them unavailable for everyone. - + + // Set any of the below to "DISABLED" to make them unavailable for everyone. + // Don't worry about per-board moderators. Let all mods moderate any board. $config['mod']['skip_per_board'] = false; - + /* Post Controls */ // View IP addresses $config['mod']['show_ip'] = MOD; @@ -1004,7 +1076,7 @@ $config['mod']['flood'] = ADMIN; // Raw HTML posting $config['mod']['rawhtml'] = ADMIN; - + /* Administration */ // View the report queue $config['mod']['reports'] = JANITOR; @@ -1016,8 +1088,8 @@ $config['mod']['view_banlist'] = MOD; // View the username of the mod who made a ban $config['mod']['view_banstaff'] = MOD; - // If the moderator doesn't fit the $config['mod']['view_banstaff''] (previous) permission, - // show him just a "?" instead. Otherwise, it will be "Mod" or "Admin" + // If the moderator doesn't fit the $config['mod']['view_banstaff''] (previous) permission, show him just + // a "?" instead. Otherwise, it will be "Mod" or "Admin". $config['mod']['view_banquestionmark'] = false; // Show expired bans in the ban list (they are kept in cache until the culprit returns) $config['mod']['view_banexpired'] = true; @@ -1051,8 +1123,8 @@ $config['mod']['modlog'] = ADMIN; // View IP addresses of other mods in ?/log $config['mod']['show_ip_modlog'] = ADMIN; - // View relevant moderation log entries on IP address pages (ie. ban history, etc.) - // Warning: Can be pretty resource exhaustive if your mod logs are huge. + // View relevant moderation log entries on IP address pages (ie. ban history, etc.) Warning: Can be + // pretty resource intensive if your mod logs are huge. $config['mod']['modlog_ip'] = MOD; // Create a PM (viewing mod usernames) $config['mod']['create_pm'] = JANITOR; @@ -1062,7 +1134,8 @@ $config['mod']['rebuild'] = ADMIN; // Search through posts, IP address notes and bans $config['mod']['search'] = JANITOR; - // Allow searching posts (can be used with board configuration file to disallow searching through a certain board) + // Allow searching posts (can be used with board configuration file to disallow searching through a + // certain board) $config['mod']['search_posts'] = JANITOR; // Read the moderator noticeboard $config['mod']['noticeboard'] = JANITOR; @@ -1080,13 +1153,13 @@ $config['mod']['news_custom'] = ADMIN; // Delete news entries $config['mod']['news_delete'] = ADMIN; - + // Edit the current configuration (via web interface) $config['mod']['edit_config'] = ADMIN; - + // Execute un-filtered SQL queries on the database (?/debug/sql) $config['mod']['debug_sql'] = DISABLED; - + /* * ==================== * Events (PHP 5.3.0+) @@ -1098,7 +1171,7 @@ // event_handler('post', function($post) { // // do something // }); - + // event_handler('post', function($post) { // // do something else // @@ -1111,51 +1184,50 @@ * Other/uncategorized * ==================== */ - - // Meta keywords. It's probably best to include these in per-board configurations. - //$config['meta_keywords'] = 'chan,anonymous discussion,imageboard,tinyboard'; - - // Link imageboard to your Google Analytics account to track users and provide marketing insights. + + // Meta keywords. It's probably best to include these in per-board configurations. + // $config['meta_keywords'] = 'chan,anonymous discussion,imageboard,tinyboard'; + + // Link imageboard to your Google Analytics account to track users and provide traffic insights. // $config['google_analytics'] = 'UA-xxxxxxx-yy'; // Keep the Google Analytics cookies to one domain -- ga._setDomainName() // $config['google_analytics_domain'] = 'www.example.org'; - - // If you use Varnish, Squid, or any similar caching reverse-proxy in front of Tinyboard, - // you can configure Tinyboard to PURGE files when they're written to - //$config['purge'] = array( - // array('127.0.0.1', 80) - // array('127.0.0.1', 80, 'example.org') - //); - // Connection timeout, in seconds + + // If you use Varnish, Squid, or any similar caching reverse-proxy in front of Tinyboard, you can + // configure Tinyboard to PURGE files when they're written to. + // $config['purge'] = array( + // array('127.0.0.1', 80) + // array('127.0.0.1', 80, 'example.org') + // ); + // Connection timeout, in seconds. $config['purge_timeout'] = 3; - - // Additional mod.php?/ pages (for developers). Look in inc/mod/pages.php for help. - //$config['mod']['custom_pages']['/something/(\d+)'] = function($id) { - // global $config; - // if (!hasPermission($config['mod']['something'])) - // error($config['error']['noaccess']); - // // ... - //}; - - // Add links to dashboard (will all be in "Other" category) - $config['mod']['dashboard_links'] = array(); + + // Additional mod.php?/ pages. Look in inc/mod/pages.php for help. + // $config['mod']['custom_pages']['/something/(\d+)'] = function($id) { + // global $config; + // if (!hasPermission($config['mod']['something'])) + // error($config['error']['noaccess']); + // // ... + // }; + + // Add links to dashboard (will all be in a new "Other" category). // $config['mod']['dashboard_links']['Something'] = '?/something'; - - // Remote servers - // http://tinyboard.org/wiki/index.php?title=Multiple_Servers - //$config['remote']['static'] = array( - // 'host' => 'static.example.org', - // 'auth' => array( - // 'method' => 'plain', - // 'username' => 'username', - // 'password' => 'password!123' - // ), - // 'type' => 'scp' - //); - - // Regex for board URIs + + // Remote servers. I'm not even sure if this code works anymore. It might. Haven't tried it in a while. + // $config['remote']['static'] = array( + // 'host' => 'static.example.org', + // 'auth' => array( + // 'method' => 'plain', + // 'username' => 'username', + // 'password' => 'password!123' + // ), + // 'type' => 'scp' + // ); + + // Regex for board URIs. Don't add "`" character or any Unicode that MySQL can't handle. 58 characters + // is the absolute maximum, because MySQL cannot handle table names greater than 64 characters. $config['board_regex'] = '[0-9a-zA-Z$_\x{0080}-\x{FFFF}]{1,58}'; - - // Complex regular expression to catch URLs + + // Complex regular expression to catch URLs. $config['url_regex'] = '/' . '(https?|ftp):\/\/' . '(([\w\-]+\.)+[a-zA-Z]{2,6}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' . '(:\d+)?' . '(\/([\w\-~.#\/?=&;:+%!*\[\]@$\'()+,|\^]+)?)?' . '/'; diff --git a/inc/display.php b/inc/display.php index 5da2f302..7c2665e1 100644 --- a/inc/display.php +++ b/inc/display.php @@ -319,31 +319,31 @@ class Post { // Delete if (hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['dir'] . 'delete/' . $this->id); // Delete all posts by IP if (hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['uri'] . '/deletebyip/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['dir'] . 'deletebyip/' . $this->id); // Delete all posts by IP (global) if (hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['uri'] . '/deletebyip/' . $this->id . '/global'); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['dir'] . 'deletebyip/' . $this->id . '/global'); // Ban if (hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_ban'] . ''; + $built .= ' ' . $config['mod']['link_ban'] . ''; // Ban & Delete if (hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_bandelete'] . ''; + $built .= ' ' . $config['mod']['link_bandelete'] . ''; // Delete file (keep post) if (!empty($this->file) && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletefile'], _('Delete file'), _('Are you sure you want to delete this file?'), $board['uri'] . '/deletefile/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletefile'], _('Delete file'), _('Are you sure you want to delete this file?'), $board['dir'] . 'deletefile/' . $this->id); // Edit post if (hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_editpost'] . ''; + $built .= ' ' . $config['mod']['link_editpost'] . ''; if (!empty($built)) $built = '' . $built . ''; @@ -420,54 +420,54 @@ class Thread { // Mod controls (on posts) // Delete if (hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_delete'], _('Delete'), _('Are you sure you want to delete this?'), $board['uri'] . '/delete/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_delete'], _('Delete'), _('Are you sure you want to delete this?'), $board['dir'] . 'delete/' . $this->id); // Delete all posts by IP if (hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip'], _('Delete all posts by IP'), _('Are you sure you want to delete all posts by this IP address?'), $board['uri'] . '/deletebyip/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip'], _('Delete all posts by IP'), _('Are you sure you want to delete all posts by this IP address?'), $board['dir'] . 'deletebyip/' . $this->id); // Delete all posts by IP (global) if (hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip_global'], _('Delete all posts by IP across all boards'), _('Are you sure you want to delete all posts by this IP address, across all boards?'), $board['uri'] . '/deletebyip/' . $this->id . '/global'); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletebyip_global'], _('Delete all posts by IP across all boards'), _('Are you sure you want to delete all posts by this IP address, across all boards?'), $board['dir'] . 'deletebyip/' . $this->id . '/global'); // Ban if (hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_ban'] . ''; + $built .= ' ' . $config['mod']['link_ban'] . ''; // Ban & Delete if (hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_bandelete'] . ''; + $built .= ' ' . $config['mod']['link_bandelete'] . ''; // Delete file (keep post) if (!empty($this->file) && $this->file != 'deleted' && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) - $built .= ' ' . secure_link_confirm($config['mod']['link_deletefile'], _('Delete file'), _('Are you sure you want to delete this file?'), $board['uri'] . '/deletefile/' . $this->id); + $built .= ' ' . secure_link_confirm($config['mod']['link_deletefile'], _('Delete file'), _('Are you sure you want to delete this file?'), $board['dir'] . 'deletefile/' . $this->id); // Sticky if (hasPermission($config['mod']['sticky'], $board['uri'], $this->mod)) if ($this->sticky) - $built .= ' ' . $config['mod']['link_desticky'] . ''; + $built .= ' ' . $config['mod']['link_desticky'] . ''; else - $built .= ' ' . $config['mod']['link_sticky'] . ''; + $built .= ' ' . $config['mod']['link_sticky'] . ''; if (hasPermission($config['mod']['bumplock'], $board['uri'], $this->mod)) if ($this->bumplocked) - $built .= ' ' . $config['mod']['link_bumpunlock'] . ''; + $built .= ' ' . $config['mod']['link_bumpunlock'] . ''; else - $built .= ' ' . $config['mod']['link_bumplock'] . ''; + $built .= ' ' . $config['mod']['link_bumplock'] . ''; // Lock if (hasPermission($config['mod']['lock'], $board['uri'], $this->mod)) if ($this->locked) - $built .= ' ' . $config['mod']['link_unlock'] . ''; + $built .= ' ' . $config['mod']['link_unlock'] . ''; else - $built .= ' ' . $config['mod']['link_lock'] . ''; + $built .= ' ' . $config['mod']['link_lock'] . ''; if (hasPermission($config['mod']['move'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_move'] . ''; + $built .= ' ' . $config['mod']['link_move'] . ''; // Edit post if (hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) - $built .= ' ' . $config['mod']['link_editpost'] . ''; + $built .= ' ' . $config['mod']['link_editpost'] . ''; if (!empty($built)) $built = '' . $built . ''; diff --git a/inc/filters.php b/inc/filters.php index 9f03154d..cd512821 100644 --- a/inc/filters.php +++ b/inc/filters.php @@ -132,10 +132,10 @@ class Filter { function do_filters(array $post) { global $config; - if (!isset($config['flood_filters'])) + if (!isset($config['filters'])) return; - foreach ($config['flood_filters'] as $arr) { + foreach ($config['filters'] as $arr) { $filter = new Filter($arr); if ($filter->check($post)) $filter->action(); diff --git a/inc/functions.php b/inc/functions.php index e871fee0..f000dc3c 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -40,7 +40,7 @@ function loadConfig() { 'dir', 'mod', 'spam', - 'flood_filters', + 'filters', 'wordfilters', 'custom_capcode', 'custom_tripcode', @@ -54,7 +54,8 @@ function loadConfig() { 'stylesheets', 'additional_javascript', 'markup', - 'custom_pages' + 'custom_pages', + 'dashboard_links' ); $config = array(); @@ -85,8 +86,8 @@ function loadConfig() { date_default_timezone_set($config['timezone']); - if (!isset($config['blotter'])) - $config['blotter'] = false; + if (!isset($config['global_message'])) + $config['global_message'] = false; if (!isset($config['post_url'])) $config['post_url'] = $config['root'] . $config['file_post']; @@ -128,8 +129,6 @@ function loadConfig() { $config['image_bumplocked'] = $config['dir']['static'] . 'sage.gif'; if (!isset($config['image_deleted'])) $config['image_deleted'] = $config['dir']['static'] . 'deleted.png'; - if (!isset($config['image_zip'])) - $config['image_zip'] = $config['dir']['static'] . 'zip.png'; if (!isset($config['uri_thumb'])) $config['uri_thumb'] = $config['root'] . $board['dir'] . $config['dir']['thumb']; @@ -1704,7 +1703,7 @@ function buildThread($id, $return = false, $mod = false) { 'mod' => $mod, 'antibot' => $mod ? false : create_antibot($board['uri'], $id), 'boardlist' => createBoardlist($mod), - 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['uri'] . '/' . $config['file_index']) + 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index']) )); if ($return) diff --git a/inc/image.php b/inc/image.php index 51db2f83..bfb77d30 100644 --- a/inc/image.php +++ b/inc/image.php @@ -279,10 +279,8 @@ class ImageConvert extends ImageBase { } $this->temp = tempnam($config['tmp'], 'imagick'); - - $quality = $config['thumb_quality'] * 10; - - $config['thumb_keep_animation_frames'] = (int) $config['thumb_keep_animation_frames']; + + $config['thumb_keep_animation_frames'] = (int)$config['thumb_keep_animation_frames']; if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { @@ -291,12 +289,12 @@ class ImageConvert extends ImageBase { escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); } else { - if (shell_exec("convert -background transparent -filter Point -sample {$this->width}x{$this->height} +antialias -quality {$quality} " . + if (shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); } } else { - if (shell_exec("convert -background transparent -flatten -filter Point -scale {$this->width}x{$this->height} +antialias -quality {$quality} " . + if (shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); } @@ -309,7 +307,7 @@ class ImagePNG extends ImageBase { } public function to($src) { global $config; - imagepng($this->image, $src, $config['thumb_quality']); + imagepng($this->image, $src); } public function resize() { $this->GD_create(); @@ -322,7 +320,7 @@ class ImagePNG extends ImageBase { class ImageGIF extends ImageBase { public function from() { - $this->image = @imagecreatefromgif ($this->src); + $this->image = @imagecreatefromgif($this->src); } public function to($src) { imagegif ($this->image, $src); diff --git a/mod.php b/mod.php index cd4d17d4..ee05c349 100644 --- a/mod.php +++ b/mod.php @@ -109,7 +109,7 @@ $new_pages = array(); foreach ($pages as $key => $callback) { if (is_string($callback) && preg_match('/^secure /', $callback)) $key .= '(/(?P[a-f0-9]{8}))?'; - $key = str_replace('\%b', $config['board_regex'], $key); + $key = str_replace('\%b', '?P' . sprintf(substr($config['board_path'], 0, -1), $config['board_regex']), $key); $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback; } $pages = $new_pages; @@ -118,6 +118,15 @@ foreach ($pages as $uri => $handler) { if (preg_match($uri, $query, $matches)) { $matches = array_slice($matches, 1); + if (isset($matches['board'])) { + $board_match = $matches['board']; + unset($matches['board']); + $key = array_search($board_match, $matches); + if (preg_match('/^' . sprintf(substr($config['board_path'], 0, -1), '(' . $config['board_regex'] . ')') . '$/u', $matches[$key], $board_match)) { + $matches[$key] = $board_match[1]; + } + } + if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) { $secure_post_only = isset($m[1]); if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') { diff --git a/post.php b/post.php index 5031830f..103894db 100644 --- a/post.php +++ b/post.php @@ -428,7 +428,7 @@ if (isset($_POST['delete'])) { $post['filehash'] = $config['file_hash']($upload); $post['filesize'] = filesize($upload); - if ($is_an_image) { + if ($is_an_image && $config['ie_mime_type_detection'] !== false) { // Check IE MIME type detection XSS exploit $buffer = file_get_contents($upload, null, null, null, 255); if (preg_match($config['ie_mime_type_detection'], $buffer)) { diff --git a/templates/generic_page.html b/templates/generic_page.html index 0c8f9867..8f608a6a 100644 --- a/templates/generic_page.html +++ b/templates/generic_page.html @@ -22,7 +22,7 @@ {% include 'post_form.html' %} - {% if config.blotter %}
    {{ config.blotter }}
    {% endif %} + {% if config.global_message %}
    {{ config.global_message }}
    {% endif %}
    diff --git a/templates/index.html b/templates/index.html index 1cde9882..e32ac253 100644 --- a/templates/index.html +++ b/templates/index.html @@ -21,7 +21,7 @@ {% include 'post_form.html' %} - {% if config.blotter %}
    {{ config.blotter }}
    {% endif %} + {% if config.global_message %}
    {{ config.global_message }}
    {% endif %}
    diff --git a/templates/thread.html b/templates/thread.html index a6b8793f..97f8a3db 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -23,7 +23,7 @@ {% include 'post_form.html' %} - {% if config.blotter %}
    {{ config.blotter }}
    {% endif %} + {% if config.global_message %}
    {{ config.global_message }}
    {% endif %}
    -- cgit v1.3 From 6ecda16be3a69b42ae6d6149e0eaa9578015a21a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 22:06:32 -0400 Subject: Forgot to commit this --- templates/installer/config.html | 95 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 templates/installer/config.html (limited to 'templates') diff --git a/templates/installer/config.html b/templates/installer/config.html new file mode 100644 index 00000000..193bb98b --- /dev/null +++ b/templates/installer/config.html @@ -0,0 +1,95 @@ + +
    + Database (MySQL) + + + + + + + + + + + + + + +
    +

    The following is all later configurable. For more options, edit your configuration files after installing.

    +
    + Cookies + + + + + +
    + +
    + Flood control + + + + + + + + + + + + + + + + + +
    + +
    + Images + + + + + + + + + + + + + + +
    + +
    + Display + + + + + + + + +
    + +
    + Directories + + +
    + +
    + Miscellaneous + + +
    + +

    + +

    + -- cgit v1.3 From 1d37e81adeea9b2a1bc1028f2bf45b47ac045ec4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 00:22:28 -0400 Subject: Better error handling/displaying with $config['debug'] and $config['verbose_errors'] --- inc/config.php | 2 +- inc/display.php | 22 +++++++++++----------- inc/functions.php | 16 ++++++++++++++-- inc/image.php | 10 +++++----- templates/error.html | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 templates/error.html (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 337d92cb..8d1c05d7 100644 --- a/inc/config.php +++ b/inc/config.php @@ -42,7 +42,7 @@ // Shows some extra information at the bottom of pages. Good for development/debugging. $config['debug'] = false; - // For development purposes. All this does is turn 'display_errors' on. + // For development purposes. Displays (and "dies" on) all errors and warnings. Turn on with the above. $config['verbose_errors'] = true; // Directory where temporary files will be created. diff --git a/inc/display.php b/inc/display.php index 7c2665e1..4972d563 100644 --- a/inc/display.php +++ b/inc/display.php @@ -57,7 +57,7 @@ function createBoardlist($mod=false) { ); } -function error($message, $priority = true) { +function error($message, $priority = true, $debug_stuff = false) { global $board, $mod, $config; if ($config['syslog'] && $priority !== false) { @@ -71,16 +71,16 @@ function error($message, $priority = true) { } die(Element('page.html', array( - 'config'=>$config, - 'title'=>_('Error'), - 'subtitle'=>_('An error has occured.'), - 'body'=>'
    ' . - '

    ' . _($message) . '

    ' . - (isset($board) ? - "

    "._("Go back").".

    " : '') . - '
    ' + 'config' => $config, + 'title' => _('Error'), + 'subtitle' => _('An error has occured.'), + 'body' => Element('error.html', array( + 'config' => $config, + 'message' => $message, + 'mod' => $mod, + 'board' => isset($board) ? $board : false, + 'debug' => is_array($debug_stuff) ? str_replace("\n", ' ', utf8tohtml(print_r($debug_stuff, true))) : utf8tohtml($debug_stuff) + )) ))); } diff --git a/inc/functions.php b/inc/functions.php index f000dc3c..b6bdd809 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -155,10 +155,22 @@ function loadConfig() { } if ($config['verbose_errors']) { + set_error_handler(function($errno, $errstr, $errfile, $errline) { + if (error_reporting() == 0) + return false; // Looks like this warning was suppressed by the @ operator. + error(utf8tohtml($errstr), true, array( + 'file' => $errfile, + 'line' => $errline, + 'errno' => $errno, + 'error' => $errstr, + 'backtrace' => array_slice(debug_backtrace(), 1) + )); + }); error_reporting(E_ALL); - ini_set('display_errors', 1); + ini_set('display_errors', true); + ini_set('html_errors', false); } - + // Keep the original address to properly comply with other board configurations if (!isset($__ip)) $__ip = $_SERVER['REMOTE_ADDR']; diff --git a/inc/image.php b/inc/image.php index 141973ee..4fc9d018 100644 --- a/inc/image.php +++ b/inc/image.php @@ -287,16 +287,16 @@ class ImageConvert extends ImageBase { if (trim($error = shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . escapeshellarg($this->temp) . '2>&1 &&echo $?') !== '0') || !file_exists($this->temp)) - error($error); + error('Failed to resize image!', null, $error); } else { - if (trim($error = shell_exec('convert ' . sprintf($config['convert_args'], '', $this->width, $this->height) . ' ' . + if (trim($error = shell_exec('aconvert ' . sprintf($config['convert_args'], '', $this->width, $this->height) . ' ' . escapeshellarg($this->src) . ' ' . escapeshellarg($this->temp) . ' 2>&1 &&echo $?')) !== '0' || !file_exists($this->temp)) - error($error); + error('Failed to resize image!', null, $error); } } else { - if (trim($error = shell_exec('convert ' . sprintf($config['convert_args'], '-flatten', $this->width, $this->height) . ' ' . + if (trim($error = shell_exec('aconvert ' . sprintf($config['convert_args'], '-flatten', $this->width, $this->height) . ' ' . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp) . ' 2>&1 &&echo $?')) !== '0' || !file_exists($this->temp)) - error($error); + error('Failed to resize image!', null, $error); } } } diff --git a/templates/error.html b/templates/error.html new file mode 100644 index 00000000..3b8eb693 --- /dev/null +++ b/templates/error.html @@ -0,0 +1,18 @@ +
    +

    {{ message }}

    + {% if board %} +

    + + {% trans 'Go back' %} + +

    + {% endif %} +
    +{% if debug and config.debug %} +
    +

    {% trans 'Error information' %}

    +
    +		{{ debug }}
    +	
    +
    +{% endif %} \ No newline at end of file -- cgit v1.3 From 0d1bfa47f1f459b4893426e752ce2d3e9b2de030 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 05:41:01 -0400 Subject: Web config editor: Write "MOD", "JANITOR", etc. to instance-config instead of just int representations --- inc/mod/config-editor.php | 10 +++++++++- inc/mod/pages.php | 15 ++++++++++++++- templates/mod/config-editor.html | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/inc/mod/config-editor.php b/inc/mod/config-editor.php index d6cad8f0..caca5a0e 100644 --- a/inc/mod/config-editor.php +++ b/inc/mod/config-editor.php @@ -62,6 +62,13 @@ function config_vars() { } else { $var['type'] = gettype($temp); } + + if ($var['type'] == 'integer' && $var['name'][0] == 'mod' && + (in_array($var['default'], array('JANITOR', 'MOD', 'ADMIN', 'DISABLED')) || mb_strpos($var['default'], "\$config['mod']") === 0)) { + // Permissions variable + $var['permissions'] = true; + } + unset($var['default_temp']); if (!is_array($var['name']) || (end($var['name']) != '' && !in_array(reset($var['name']), array('stylesheets')))) { $already_exists = false; @@ -80,7 +87,8 @@ function config_vars() { 'comment' => array(), 'default' => false, 'default_temp' => false, - 'commented' => false + 'commented' => false, + 'permissions' => false, ); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 6c46a84f..13520871 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -2010,7 +2010,20 @@ function mod_config() { $config_append .= '[' . var_export($var['name'], true) . ']'; } - $config_append .= ' = ' . var_export($value, true) . ";\n"; + + $config_append .= ' = '; + if ($var['permissions'] && in_array($value, array(JANITOR, MOD, ADMIN, DISABLED))) { + $perm_array = array( + JANITOR => 'JANITOR', + MOD => 'MOD', + ADMIN => 'ADMIN', + DISABLED => 'DISABLED' + ); + $config_append .= $perm_array[$value]; + } else { + $config_append .= var_export($value, true); + } + $config_append .= ";\n"; } } diff --git a/templates/mod/config-editor.html b/templates/mod/config-editor.html index 41e01dad..d333e9a2 100644 --- a/templates/mod/config-editor.html +++ b/templates/mod/config-editor.html @@ -25,7 +25,7 @@ {% if var.type == 'string' %} - {% elseif var.type == 'integer' and var.name.0 == 'mod' and (var.default in ['JANITOR', 'MOD', 'ADMIN', 'DISABLED'] or var.default|slice(0, 14) == "$config['mod']") and var.value <= constant('DISABLED') %} + {% elseif var.permissions %} '; echo Element('page.html', $page); @@ -2048,12 +2062,18 @@ function mod_config() { } } - header('Location: ?/', true, $config['redirect_http']); + header('Location: ?/config', true, $config['redirect_http']); exit; } - mod_page(_('Config editor'), 'mod/config-editor.html', array('conf' => $conf)); + mod_page(_('Config editor') . ($board_config ? ': ' . sprintf($config['board_abbreviation'], $board_config) : ''), + 'mod/config-editor.html', array( + 'boards' => listBoards(), + 'board' => $board_config, + 'conf' => $conf, + 'file' => $config_file + )); } function mod_themes_list() { diff --git a/mod.php b/mod.php index ee05c349..742eeefb 100644 --- a/mod.php +++ b/mod.php @@ -21,64 +21,65 @@ if (get_magic_quotes_gpc()) { $query = isset($_SERVER['QUERY_STRING']) ? urldecode($_SERVER['QUERY_STRING']) : ''; $pages = array( - '' => ':?/', // redirect to dashboard - '/' => 'dashboard', // dashboard + '' => ':?/', // redirect to dashboard + '/' => 'dashboard', // dashboard '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work) - '/logout' => 'logout', // logout + '/logout' => 'logout', // logout - '/users' => 'users', // manage users - '/users/(\d+)' => 'user', // edit user - '/users/(\d+)/(promote|demote)' => 'user_promote', // prmote/demote user + '/users' => 'users', // manage users + '/users/(\d+)' => 'user', // edit user + '/users/(\d+)/(promote|demote)' => 'user_promote', // prmote/demote user '/users/new' => 'user_new', // create a new user '/new_PM/([^/]+)' => 'new_pm', // create a new pm - '/PM/(\d+)(/reply)?' => 'pm', // read a pm - '/inbox' => 'inbox', // pm inbox + '/PM/(\d+)(/reply)?' => 'pm', // read a pm + '/inbox' => 'inbox', // pm inbox '/noticeboard' => 'noticeboard', // view noticeboard - '/noticeboard/(\d+)' => 'noticeboard', // view noticeboard - '/noticeboard/delete/(\d+)' => 'noticeboard_delete',// delete from noticeboard - '/log' => 'log', // modlog - '/log/(\d+)' => 'log', // modlog + '/noticeboard/(\d+)' => 'noticeboard', // view noticeboard + '/noticeboard/delete/(\d+)' => 'noticeboard_delete', // delete from noticeboard + '/log' => 'log', // modlog + '/log/(\d+)' => 'log', // modlog '/log:([^/]+)' => 'user_log', // modlog - '/log:([^/]+)/(\d+)' => 'user_log', // modlog - '/news' => 'news', // view news - '/news/(\d+)' => 'news', // view news - '/news/delete/(\d+)' => 'news_delete', // delete from news + '/log:([^/]+)/(\d+)' => 'user_log', // modlog + '/news' => 'news', // view news + '/news/(\d+)' => 'news', // view news + '/news/delete/(\d+)' => 'news_delete', // delete from news '/edit/(\%b)' => 'edit_board', // edit board details '/new-board' => 'new_board', // create a new board - '/rebuild' => 'rebuild', // rebuild static files - '/reports' => 'reports', // report queue - '/reports/(\d+)/dismiss(all)?' => 'report_dismiss', // dismiss a report + '/rebuild' => 'rebuild', // rebuild static files + '/reports' => 'reports', // report queue + '/reports/(\d+)/dismiss(all)?' => 'report_dismiss', // dismiss a report - '/IP/([\w.:]+)' => 'ip', // view ip address + '/IP/([\w.:]+)' => 'ip', // view ip address '/IP/([\w.:]+)/remove_note/(\d+)' => 'ip_remove_note', // remove note from ip address - '/bans' => 'bans', // ban list - '/bans/(\d+)' => 'bans', // ban list + '/bans' => 'bans', // ban list + '/bans/(\d+)' => 'bans', // ban list - '/search' => 'search_redirect', // search + '/search' => 'search_redirect', // search '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search - '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search + '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search // CSRF-protected moderator actions - '/ban' => 'secure_POST ban', // new ban - '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster - '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread + '/ban' => 'secure_POST ban', // new ban + '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster + '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post - '/(\%b)/delete/(\d+)' => 'secure delete', // delete post - '/(\%b)/deletefile/(\d+)' => 'secure deletefile', // delete file from post + '/(\%b)/delete/(\d+)' => 'secure delete', // delete post + '/(\%b)/deletefile/(\d+)' => 'secure deletefile', // delete file from post '/(\%b)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address - '/(\%b)/(un)?lock/(\d+)' => 'secure lock', // lock thread - '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread - '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread + '/(\%b)/(un)?lock/(\d+)' => 'secure lock', // lock thread + '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread + '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread - '/themes' => 'themes_list', // manage themes + '/themes' => 'themes_list', // manage themes '/themes/(\w+)' => 'theme_configure', // configure/reconfigure theme - '/themes/(\w+)/rebuild' => 'theme_rebuild', // rebuild theme - '/themes/(\w+)/uninstall' => 'theme_uninstall', // uninstall theme + '/themes/(\w+)/rebuild' => 'theme_rebuild', // rebuild theme + '/themes/(\w+)/uninstall' => 'theme_uninstall', // uninstall theme - '/config' => 'config', // config editor + '/config' => 'config', // config editor + '/config/(\%b)' => 'config', // config editor // these pages aren't listed in the dashboard without $config['debug'] '/debug/antispam' => 'debug_antispam', diff --git a/templates/mod/config-editor-php.html b/templates/mod/config-editor-php.html index 54c398e4..4f76b5dd 100644 --- a/templates/mod/config-editor-php.html +++ b/templates/mod/config-editor-php.html @@ -1,17 +1,35 @@ -{% if readonly %} -

    Tinyboard does not have the required permissions to edit inc/instance-config.php. To make changes, you will need to change the file's permissions first or manually edit the code.

    -{% endif %} - - -{% if not readonly %}
    {% endif %} - +
    +

    + Any changes you make here will simply be appended to {{ file }}. If you wish to make the most of Tinyboard's customizability, you can instead edit the file directly. This page is intended for making quick changes and for those who don't have a basic understanding of PHP code. +

    + {% if boards|count %} + + {% endif %} + + {% if readonly %} +

    Tinyboard does not have the required permissions to edit {{ file }}. To make changes, you will need to change the file's permissions first or manually edit the code.

    + {% endif %} + -
      -
    • -
    -{% if not readonly %}{% endif %} + {% if not readonly %}
    {% endif %} + + +
      +
    • +
    + {% if not readonly %}
    {% endif %} +