From 8772c31ce13e65b379be7b74154dd077cbd68ecb Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 20 Jul 2013 22:45:21 -0400 Subject: [PATCH 001/289] post search: missed default config --- inc/config.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/inc/config.php b/inc/config.php index bbc899ef..74794645 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1084,6 +1084,28 @@ // Execute un-filtered SQL queries on the database (?/debug/sql) $config['mod']['debug_sql'] = DISABLED; +/* + * ==================== + * Public post search + * ==================== + */ + $config['search'] = array(); + + // Enable the search form + $config['search']['enable'] = false; + + // Maximal number of queries per IP address per minutes + $config['search']['queries_per_minutes'] = Array(15, 2); + + // Global maximal number of queries per minutes + $config['search']['queries_per_minutes_all'] = Array(50, 2); + + // Limit of search results + $config['search']['search_limit'] = 100; + + // Boards for searching + //$config['search']['boards'] = array('a', 'b', 'c', 'd', 'e'); + /* * ==================== * Events (PHP 5.3.0+) From 97a22e57c1ef3c3e41ed5666255c1e941df21f3e Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 20 Jul 2013 22:47:26 -0400 Subject: [PATCH 002/289] 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 --- imgcaptcha_im.php | 7 -- imgcaptcha_p.php | 5 -- inc/config.php | 15 ----- inc/ic-encrypt.php | 37 ----------- inc/imgcaptcha.php | 136 --------------------------------------- js/imgcaptcha.js | 12 ---- post.php | 8 +-- templates/post_form.html | 15 ----- 8 files changed, 1 insertion(+), 234 deletions(-) delete mode 100644 imgcaptcha_im.php delete mode 100644 imgcaptcha_p.php delete mode 100644 inc/ic-encrypt.php delete mode 100644 inc/imgcaptcha.php delete mode 100644 js/imgcaptcha.js diff --git a/imgcaptcha_im.php b/imgcaptcha_im.php deleted file mode 100644 index 152d92ad..00000000 --- a/imgcaptcha_im.php +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/imgcaptcha_p.php b/imgcaptcha_p.php deleted file mode 100644 index 9543dc6c..00000000 --- a/imgcaptcha_p.php +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/inc/config.php b/inc/config.php index 74794645..04ed6812 100644 --- a/inc/config.php +++ b/inc/config.php @@ -233,8 +233,6 @@ 'embed', 'recaptcha_challenge_field', 'recaptcha_response_field', - 'imgcaptcha_hash', - 'imgcaptcha_verify', 'spoiler', 'quick-reply' ); @@ -270,19 +268,6 @@ $config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f'; $config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_'; - $config['imgcaptcha'] = false; - $config['imgcaptcha_key'] = "cos losowego"; // max 32 znaki - $config['imgcaptcha_list'] = "/sciezka/do/pliku.txt"; - $config['imgcaptcha_images'] = "/sciezka/do/obrazkow"; // without a slash at the end - $config['imgcaptcha_question'] = "Was ist das?"; - $config['imgcaptcha_time_limit'] = 90; // Kapcza wazna przez 90 sekund po wejsciu - $config['imgcaptcha_filler'] = "/plik/kliknijmie.png"; - $config['imgcaptcha_width'] = 128; - $config['imgcaptcha_height'] = 96; - - // JESLI DODAJESZ IMGKAPCZE, NIE ZAPOMNIJ O TYM - // Wymagane tez jQuery - o tam, nizej. - //$config['additional_javascript'][] = 'js/imgcaptcha.js'; /* * ==================== * Post settings diff --git a/inc/ic-encrypt.php b/inc/ic-encrypt.php deleted file mode 100644 index 5d73126b..00000000 --- a/inc/ic-encrypt.php +++ /dev/null @@ -1,37 +0,0 @@ -safe_b64encode($crypttext)); - } - - public function decode($key, $value){ - if(!$value){return false;} - $crypttext = $this->safe_b64decode($value); - $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); - $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv); - return trim($decrypttext); - } -} -?> diff --git a/inc/imgcaptcha.php b/inc/imgcaptcha.php deleted file mode 100644 index ab6db68f..00000000 --- a/inc/imgcaptcha.php +++ /dev/null @@ -1,136 +0,0 @@ -255) { return 255; } - if($a<0) { return 0; } - return $a; - } - function randString($length, $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=') - { - $str = ''; - $count = strlen($charset); - while ($length--) { - $str .= $charset[rand(0, $count-1)]; - } - return $str; - } - function generateCaptchaHash() { - global $config; - $lines = getImages(); - $pick = pickImage($lines); - $enctext = $pick . ",," . time() . ",," . $_SERVER["REMOTE_ADDR"] . ",," . randString(12); - $converter = new Encryption; - return $converter->encode($config["imgcaptcha_key"],$enctext); - } - function ic_verifyHash($enctext, $output) { - global $config; - //print "VERIFY: " . $enctext . " " . $output . "
"; - $converter = new Encryption; - $dectext = explode(",,",$converter->decode($config["imgcaptcha_key"],$enctext)); - if(count($dectext)<4) return true; - $lines = getImages(); - $pick = $dectext[0]; - $time = time()-$dectext[1]; - if($time>$config["imgcaptcha_time_limit"]) return true; - $lp = $lines[$pick]; - for($i=1;$idecode($config["imgcaptcha_key"],$enctext)); - if(count($dectext)<=1) return; //SC - $lines = getImages(); - return $dectext[0]; - } - function generateImage($enctext) - { - global $config; - $lines = getImages(); - $pick = getPick($enctext); - if(!isset($lines[$pick])) return; //SC - $src = imagecreatefrompng(getIPath($lines[$pick][0])); - if($src == FALSE) return; //SC - $maxc = 8; - $icw = $config["imgcaptcha_width"]; - $ich = $config["imgcaptcha_height"]; - $dst = imagecreatetruecolor($icw,$ich); - $srcxm = imagesx($src)-$icw; - $srcym = imagesy($src)-$ich; - $srcx = rand(0,$srcxm-1); - $srcy = rand(0,$srcym-1); - imagecopy($dst,$src,0,0,$srcx,$srcy,$icw,$ich); - - // Obfuscation step 1 - imagecopymergegray($dst,$dst,0,0,0,0,$icw,$ich,rand(20,45)); - // Obfuscation step 1.5 - for($i=0;$i<8;$i++) { - $w = rand(5,10); $h = rand(5,10); - $x = rand(0,$icw-1-$w); $y = rand(0,$ich-1-$h); - $x2 = rand(0,$icw-1); $y2 = rand(0,$ich-1); - imagefilledrectangle($dst,$x,$y,$x+$w,$y+$h,imagecolorat($dst,$x2,$y2)); - } - for($i=0;$i<5;$i++) { - $w = rand(20,40); $h = rand(20,40); - $x = rand(0,$icw-1-$w); $y = rand(0,$ich-1-$h); - imagecopymergegray($dst,$dst,$x,$y,$x,$y,$w,$h,0); - } - // Obfuscation step 2 - for($i=0;$i<$icw*$ich;$i++) { - $x = $i%$icw; $y = $i/$icw; - $c = imagecolorat($dst,$x,$y); - if(rand(0,4) == 2) { $nc = $c ^ rand(0,16777215); } - else { $nc = imagecolorat($dst,rand(0,$icw-1),rand(0,$ich-1)); } - if(rand(18,24)!=21 and $c != 0 and $c != 0xFF00FF) - { - $nc = ncfix(($c&0xFF) + rand(-16,16)) | ncfix((($c>>8)&0xFF) + rand(-8,8))<<8 | ncfix((($c>>16)&0xFF) + rand(-32,32))<<16; - $nc1 = $nc&0xFF ^ ($nc>>8)&0xFF ^ ($nc>>16)&0xFF; - } else { - $nc1 = $nc&0xFF; - if($nc1>($maxc*25)) $nc1 = $nc % ($maxc*25); - } - $nc2 = $nc1 | $nc1<<8 | $nc1<<16; - if(rand(0,1)==0) $nc2=$nc; - imagesetpixel($dst,$x,$y,$nc2); - } - // Obfuscation step 3 - for($i=0;$i diff --git a/js/imgcaptcha.js b/js/imgcaptcha.js deleted file mode 100644 index 99aad414..00000000 --- a/js/imgcaptcha.js +++ /dev/null @@ -1,12 +0,0 @@ -function ic_odswiezKapcze() { - $.get(configRoot + "imgcaptcha_p.php", function(data) { - $("#imgcaptcha_hash").val(data); - $("#imgcaptcha_img").prop("src",configRoot + "imgcaptcha_im.php?cr=" + data); - }); -} -//function resetujKapcze() { -// $("#imgcaptcha_img").prop("src",configRoot + "zakrytek.png"); -//} -//$(document).ready(function(){ -// //resetujKapcze(); - to nie powinno byc na razie potrzebne -//}); diff --git a/post.php b/post.php index 4ded8622..91d5a2f5 100644 --- a/post.php +++ b/post.php @@ -6,7 +6,6 @@ require 'inc/functions.php'; require 'inc/anti-bot.php'; -require 'inc/imgcaptcha.php'; // Fix for magic quotes if (get_magic_quotes_gpc()) { @@ -198,12 +197,7 @@ if (isset($_POST['delete'])) { error($config['error']['captcha']); } } - if ($config['imgcaptcha']) { - if (!isset($_POST['imgcaptcha_verify']) || !isset($_POST['imgcaptcha_hash'])) - error($config['error']['bot']); - if (ic_verifyHash($_POST['imgcaptcha_hash'],$_POST['imgcaptcha_verify'])) - error($config['error']['captcha']); - } + if ($post['mod'] = isset($_POST['mod']) && $_POST['mod']) { require 'inc/mod.php'; if (!$mod) { 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 %} From 308f557fd503898406d7cb54ef7e6e6efb0f84ae Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 21 Jul 2013 15:50:45 -0400 Subject: [PATCH 003/289] Option to automatically strip EXIF metadata from JPEGs --- inc/config.php | 3 +++ inc/image.php | 12 ++++++++++-- post.php | 11 ++++++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/inc/config.php b/inc/config.php index 424d07d6..c2a68e6c 100644 --- a/inc/config.php +++ b/inc/config.php @@ -418,6 +418,9 @@ // - 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in PHP Imagick. $config['thumb_method'] = 'gd'; + // 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 $config['ie_mime_type_detection'] = '/<(?:body|head|html|img|plaintext|pre|script|table|title|a href|channel|scriptlet)/i'; diff --git a/inc/image.php b/inc/image.php index abe27bcb..eb98ceda 100644 --- a/inc/image.php +++ b/inc/image.php @@ -166,6 +166,9 @@ class ImageImagick extends ImageBase { } } public function to($src) { + if ($config['strip_exif']) { + $this->image->stripImage(); + } if (preg_match('/\.gif$/i', $src)) $this->image->writeImages($src, true); else @@ -236,9 +239,14 @@ class ImageConvert extends ImageBase { } } public function to($src) { + global $config; + if (!$this->temp) { - // $config['redraw_image'] - shell_exec('convert ' . escapeshellarg($this->src) . ' ' . escapeshellarg($src)); + if ($config['strip_exif']) { + shell_exec('convert ' . escapeshellarg($this->src) . ' -strip ' . escapeshellarg($src)); + } else { + shell_exec('convert ' . escapeshellarg($this->src) . ' ' . escapeshellarg($src)); + } } else { rename($this->temp, $src); chmod($src, 0664); diff --git a/post.php b/post.php index 4e10c0cf..4e3a1a9f 100644 --- a/post.php +++ b/post.php @@ -420,10 +420,11 @@ if (isset($_POST['delete'])) { error($config['error']['maxsize']); } - // The following code corrects the image orientation based on EXIF. - // Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered. - if ($config['thumb_method'] == 'convert') { - if ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg') { + + if ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg') { + // The following code corrects the image orientation. + // Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered. + if ($config['thumb_method'] == 'convert') { $exif = exif_read_data($upload); if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { shell_exec('convert ' . escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload)); @@ -473,7 +474,7 @@ if (isset($_POST['delete'])) { $thumb->_destroy(); } - if ($config['redraw_image']) { + if ($config['redraw_image'] || ($config['strip_exif'] && ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg'))) { $image->to($post['file']); $dont_copy_file = true; } From 9123161870f0bf935624f7668d28fd62d2a60f8e Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 21 Jul 2013 21:12:30 -0400 Subject: [PATCH 004/289] js/hide-threads.js: Simple thread-minimizing script --- js/hide-threads.js | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 js/hide-threads.js diff --git a/js/hide-threads.js b/js/hide-threads.js new file mode 100644 index 00000000..42475d2a --- /dev/null +++ b/js/hide-threads.js @@ -0,0 +1,74 @@ +/* + * hide-threads.js + * https://github.com/savetheinternet/Tinyboard/blob/master/js/hide-threads.js + * + * Released under the MIT license + * Copyright (c) 2013 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/hide-threads.js'; + * + */ + +$(document).ready(function(){ + if($('div.banner').length != 0) + return; // not index + + var board = $('form input[name="board"]').val().toString(); + + if (!localStorage.hiddenthreads) + localStorage.hiddenthreads = '{}'; + + // Load data from HTML5 localStorage + var hidden_data = JSON.parse(localStorage.hiddenthreads); + + var store_data = function() { + localStorage.hiddenthreads = JSON.stringify(hidden_data); + }; + + // Delete old hidden threads (7+ days old) + for (var key in hidden_data) { + for (var id in hidden_data[key]) { + if (hidden_data[key][id] < Math.round(Date.now() / 1000) - 60 * 60 * 24 * 7) { + delete hidden_data[key][id]; + store_data(); + } + } + } + + if (!hidden_data[board]) { + hidden_data[board] = {}; // id : timestamp + } + + $('div.post.op').each(function() { + var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); + var thread_container = $(this).parent(); + $('[-] ') + .insertBefore(thread_container.find('p.fileinfo')) + .click(function() { + hidden_data[board][id] = Math.round(Date.now() / 1000); + store_data(); + + thread_container.find('div.post,img,p.fileinfo,a.hide-thread-link,br').hide(); + + var hidden_div = thread_container.find('div.post.op > p.intro').clone(); + hidden_div.addClass('thread-hidden'); + hidden_div.find('a[href],input').remove(); + + $('[+] ') + .insertAfter(thread_container.find('a.hide-thread-link')) + .click(function() { + delete hidden_data[board][id]; + store_data(); + thread_container.find('div.post,img,p.fileinfo,a.hide-thread-link,br').show(); + $(this).remove(); + hidden_div.remove(); + }); + + hidden_div.insertAfter(thread_container.find('p.fileinfo')); + }); + if (hidden_data[board][id]) + thread_container.find('.hide-thread-link').click(); + }); +}); From 51361d02fb4b66a198dcdb5cd6350e6dada0aac9 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 21 Jul 2013 21:18:57 -0400 Subject: [PATCH 005/289] Strange bug in last commit --- js/hide-threads.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 42475d2a..135fbf51 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -45,7 +45,7 @@ $(document).ready(function(){ var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); var thread_container = $(this).parent(); $('[-] ') - .insertBefore(thread_container.find('p.fileinfo')) + .insertBefore(thread_container.find('p.fileinfo:first')) .click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); @@ -66,7 +66,7 @@ $(document).ready(function(){ hidden_div.remove(); }); - hidden_div.insertAfter(thread_container.find('p.fileinfo')); + hidden_div.insertAfter(thread_container.find('p.fileinfo:first')); }); if (hidden_data[board][id]) thread_container.find('.hide-thread-link').click(); From e5663953b534f8098acff8f2942fdb81c2942acf Mon Sep 17 00:00:00 2001 From: czaks Date: Mon, 22 Jul 2013 10:14:08 -0400 Subject: [PATCH 006/289] Remove our post-hider script in favour of STI's one, leave symlink for compatibility --- js/post-hider.js | 54 +----------------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) mode change 100644 => 120000 js/post-hider.js diff --git a/js/post-hider.js b/js/post-hider.js deleted file mode 100644 index f4cde66a..00000000 --- a/js/post-hider.js +++ /dev/null @@ -1,53 +0,0 @@ -function phGetCookieName(board, id) { - return "ph_hide_" + board + "_" + id; -} -function phPostHidden(board, id) { - return (localStorage.getItem(phGetCookieName(board, id)) != null); -} -function phPostToggle(board, id) { - if(phPostHidden(board, id)) { localStorage.removeItem(phGetCookieName(board, id)); } - else { localStorage.setItem(phGetCookieName(board, id),"yes"); } -} -function phGetInnerText(board, id) { - if(phPostHidden(board, id)) { return "[+]"; } - else { return "[–]"; } -} -function phGetOpID(element) { - return Number(element.children("div.post.op").children("p.intro").children("a.post_no:eq(1)").text()); -} -function phGetOpBoard(element) { - return element.data("board"); -} -function phPostHandle(element) { - var id = phGetOpID(element); - var board = phGetOpBoard(element); - var preplies = element.children("div.post.reply"); - var pbody = element.children("div.post.op").children("div.body"); - var pimage = element.children("a:first").children("img"); - var pbutton = element.children("div.post.op").children("p.intro").children("a.posthider"); - var pomitted = element.children("div.post.op").children("span.omitted"); - if(phPostHidden(board, id)) { element.addClass("thread-hidden"); pomitted.hide(); preplies.hide(); pbody.hide(); pimage.hide(); pbutton.text("[+]"); } - else { element.removeClass("thread-hidden"); pomitted.show(); preplies.show(); pbody.show(); pimage.show(); pbutton.text("[–]"); } -} - -function phHandleThread(index, element) { - // Get thread ID. - var pin = $(this).children("div.post.op").children("p.intro"); - var tid = phGetOpID($(this)); - if(tid != NaN) { - $("[?]").insertAfter(pin.children('a:last')).click(function(e) { - var eO = $(e.target); - var par = eO.parent().parent().parent(); - phPostToggle(phGetOpBoard(par), phGetOpID(par)); - phPostHandle(par); - return false; - }); - phPostHandle($(this)); - } -} - -$(document).ready(function(){ - if (active_page != "thread") { - $('form[name="postcontrols"] > div[id^="thread"]').each(phHandleThread); - } -}); diff --git a/js/post-hider.js b/js/post-hider.js new file mode 120000 index 00000000..693c14d6 --- /dev/null +++ b/js/post-hider.js @@ -0,0 +1 @@ +hide-threads.js \ No newline at end of file From d111c6ab8c9ef12440c52974fc12ea61aa5c6ca1 Mon Sep 17 00:00:00 2001 From: czaks Date: Mon, 22 Jul 2013 10:26:14 -0400 Subject: [PATCH 007/289] hide-threads.js: a bigger minus character --- js/hide-threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 135fbf51..5a9908f1 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -44,7 +44,7 @@ $(document).ready(function(){ $('div.post.op').each(function() { var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); var thread_container = $(this).parent(); - $('[-] ') + $('[–] ') .insertBefore(thread_container.find('p.fileinfo:first')) .click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); From ed8fe6c27a39222604e65acdb09de27fd85fb0a2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 22 Jul 2013 17:51:13 -0400 Subject: [PATCH 008/289] 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(-) 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 %} From 46edec0f2d8c31b55e36e160c7d9bac8bf4d3aa4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 23 Jul 2013 09:46:29 -0400 Subject: [PATCH 022/289] Bug with last commit --- templates/index.html | 2 +- templates/thread.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 %} From 4e609da2b75f5fe6d694617735cad77014a504f1 Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 23 Jul 2013 10:34:23 -0400 Subject: [PATCH 023/289] fix merge --- templates/post_thread.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 %} From 31f657e550ab8b1ea00953cc3a26f4661ee4458c Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 24 Jul 2013 11:15:55 -0400 Subject: [PATCH 024/289] Long overdue: Salted password hashes --- inc/mod/auth.php | 34 +++++++++++++++++++++------------- inc/mod/pages.php | 24 ++++++++++++++++++------ install.php | 21 ++++++++++++++++++++- install.sql | 7 ++++--- 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/inc/mod/auth.php b/inc/mod/auth.php index 173190ab..1bc27dff 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -29,6 +29,11 @@ function mkhash($username, $password, $salt = false) { return $hash; } +function generate_salt() { + mt_srand(microtime(true) * 100000 + memory_get_usage(true)); + return md5(uniqid(mt_rand(), true)); +} + function login($username, $password, $makehash=true) { global $mod; @@ -37,20 +42,23 @@ function login($username, $password, $makehash=true) { $password = sha1($password); } - $query = prepare("SELECT `id`,`type`,`boards` FROM `mods` WHERE `username` = :username AND `password` = :password LIMIT 1"); + $query = prepare("SELECT `id`, `type`, `boards`, `password`, `salt` FROM `mods` WHERE `username` = :username"); $query->bindValue(':username', $username); - $query->bindValue(':password', $password); $query->execute() or error(db_error($query)); - if ($user = $query->fetch()) { - return $mod = array( - 'id' => $user['id'], - 'type' => $user['type'], - 'username' => $username, - 'hash' => mkhash($username, $password), - 'boards' => explode(',', $user['boards']) - ); - } else return false; + if ($user = $query->fetch(PDO::FETCH_ASSOC)) { + if ($user['password'] === hash('sha256', $user['salt'] . $password)) { + return $mod = array( + 'id' => $user['id'], + 'type' => $user['type'], + 'username' => $username, + 'hash' => mkhash($username, $user['password']), + 'boards' => explode(',', $user['boards']) + ); + } + } + + return false; } function setCookies() { @@ -104,10 +112,10 @@ if (isset($_COOKIE[$config['cookies']['mod']])) { exit; } - $query = prepare("SELECT `id`, `type`, `boards`, `password` FROM `mods` WHERE `username` = :username LIMIT 1"); + $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(); + $user = $query->fetch(PDO::FETCH_ASSOC); // validate password hash if ($cookie[1] !== mkhash($cookie[0], $user['password'], $cookie[2])) { diff --git a/inc/mod/pages.php b/inc/mod/pages.php index cddecad0..1ed9a94b 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1407,9 +1407,13 @@ function mod_user($uid) { } if ($_POST['password'] != '') { - $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); + $salt = generate_salt(); + $password = hash('sha256', $salt . sha1($_POST['password'])); + + $query = prepare('UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); $query->bindValue(':id', $uid); - $query->bindValue(':password', $_POST['password']); + $query->bindValue(':password', $password); + $query->bindValue(':salt', $salt); $query->execute() or error(db_error($query)); modLog('Changed password for ' . utf8tohtml($_POST['username']) . ' (#' . $user['id'] . ')'); @@ -1430,9 +1434,13 @@ function mod_user($uid) { if (hasPermission($config['mod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { if ($_POST['password'] != '') { - $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); + $salt = generate_salt(); + $password = hash('sha256', $salt . sha1($_POST['password'])); + + $query = prepare('UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id'); $query->bindValue(':id', $uid); - $query->bindValue(':password', $_POST['password']); + $query->bindValue(':password', $password); + $query->bindValue(':salt', $salt); $query->execute() or error(db_error($query)); modLog('Changed own password'); @@ -1494,9 +1502,13 @@ function mod_user_new() { if ($_POST['type'] !== JANITOR && $_POST['type'] !== MOD && $_POST['type'] !== ADMIN) error(sprintf($config['error']['invalidfield'], 'type')); - $query = prepare('INSERT INTO `mods` VALUES (NULL, :username, SHA1(:password), :type, :boards)'); + $salt = generate_salt(); + $password = hash('sha256', $salt . sha1($_POST['password'])); + + $query = prepare('INSERT INTO `mods` VALUES (NULL, :username, :password, :salt, :type, :boards)'); $query->bindValue(':username', $_POST['username']); - $query->bindValue(':password', $_POST['password']); + $query->bindValue(':password', $password); + $query->bindValue(':salt', $salt); $query->bindValue(':type', $_POST['type']); $query->bindValue(':boards', implode(',', $boards)); $query->execute() or error(db_error($query)); diff --git a/install.php b/install.php index 71d1c910..3c65a4b8 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ fetch(PDO::FETCH_ASSOC)) { + if (strlen($user['password']) == 40) { + mt_srand(microtime(true) * 100000 + memory_get_usage(true)); + $salt = md5(uniqid(mt_rand(), true)); + + $user['salt'] = $salt; + $user['password'] = hash('sha256', $user['salt'] . $user['password']); + + $_query = prepare("UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id"); + $_query->bindValue(':username', $user['id']); + $_query->bindValue(':password', $user['password']); + $_query->bindValue(':salt', $user['salt']); + $_query->execute() or error(db_error($_query)); + } + } case false: // Update version number file_write($config['has_installed'], VERSION); diff --git a/install.sql b/install.sql index 04896681..d32c3e3e 100644 --- a/install.sql +++ b/install.sql @@ -129,9 +129,10 @@ CREATE TABLE IF NOT EXISTS `modlogs` ( -- CREATE TABLE IF NOT EXISTS `mods` ( - `id` smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT, + `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(30) NOT NULL, - `password` char(40) NOT NULL COMMENT 'SHA1', + `password` char(64) NOT NULL COMMENT 'SHA256', + `salt` char(32) NOT NULL, `type` smallint(1) NOT NULL COMMENT '0: janitor, 1: mod, 2: admin', `boards` text NOT NULL, PRIMARY KEY (`id`), @@ -143,7 +144,7 @@ CREATE TABLE IF NOT EXISTS `mods` ( -- INSERT INTO `mods` (`id`, `username`, `password`, `type`, `boards`) VALUES -(1, 'admin', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 2, '*'); +(1, 'admin', 'cedad442efeef7112fed0f50b011b2b9bf83f6898082f995f69dd7865ca19fb7', '4a44c6c55df862ae901b413feecb0d49', 2, '*'); -- -------------------------------------------------------- From 6c2c18514ee49d4d9e20c8d8ed7f3e0fa3c61307 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 24 Jul 2013 11:17:09 -0400 Subject: [PATCH 025/289] Small mistake with last commit --- install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.php b/install.php index 3c65a4b8..08e8046a 100644 --- a/install.php +++ b/install.php @@ -242,7 +242,7 @@ if (file_exists($config['has_installed'])) { $user['password'] = hash('sha256', $user['salt'] . $user['password']); $_query = prepare("UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id"); - $_query->bindValue(':username', $user['id']); + $_query->bindValue(':id', $user['id']); $_query->bindValue(':password', $user['password']); $_query->bindValue(':salt', $user['salt']); $_query->execute() or error(db_error($_query)); From 33a1c00bd51618a4b54fd6fdab721aaaa03bfd33 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 24 Jul 2013 11:30:01 -0400 Subject: [PATCH 026/289] %length% in public ban messages --- inc/config.php | 4 +++- inc/mod/pages.php | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/inc/config.php b/inc/config.php index b32f4266..98e127b3 100644 --- a/inc/config.php +++ b/inc/config.php @@ -879,8 +879,10 @@ // Check public ban message by default $config['mod']['check_ban_message'] = false; - // Default public ban message + // 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']['ban_message'] = '(%s)'; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 1ed9a94b..01794d2e 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1152,6 +1152,9 @@ function mod_ban_post($board, $delete, $post, $token = false) { if (isset($_POST['public_message'], $_POST['message'])) { // public ban message + $length_english = parse_time($_POST['length']) ? 'for ' . until(parse_time($_POST['length'])) : 'permanently'; + $_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` = CONCAT(`body`, :body) WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->bindValue(':body', sprintf($config['mod']['ban_message'], utf8tohtml($_POST['message']))); From 37d5846e4ecf61a534ba19ecbd3f66388233e5d4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 26 Jul 2013 11:01:13 -0400 Subject: [PATCH 027/289] Fix markup overlapping. Issue #124 --- inc/functions.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index af810f31..b5660664 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1437,13 +1437,15 @@ function markup(&$body, $track_cites = false) { $tracked_cites = array(); // Cites - if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites)) { + if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } - for ($index=0;$indexbindValue(':id', $cite); $query->execute() or error(db_error($query)); @@ -1453,23 +1455,26 @@ function markup(&$body, $track_cites = false) { $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread']?$post['thread']:$post['id']) . '.html#' . $cite . '">' . '>>' . $cite . ''; - $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[3][$index], $body); + $body = substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) $tracked_cites[] = array($board['uri'], $post['id']); } } } - + // Cross-board linking - if (preg_match_all('/(^|\s)>>>\/(\w+?)\/(\d+)?([\s,.)?]|$)/m', $body, $cites)) { + if (preg_match_all('/(^|\s)>>>\/(\w+?)\/(\d+)?([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } - for ($index=0;$index' . '>>>/' . $_board . '/' . $cite . ''; - $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); + $body = substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) $tracked_cites[] = array($board['uri'], $post['id']); @@ -1496,7 +1502,8 @@ function markup(&$body, $track_cites = false) { $config['root'] . $board['dir'] . $config['file_index'] . '">' . '>>>/' . $_board . '/' . ''; - $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); + $body = substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } From c217069f2bc7f9b38a4ddbe3d1043fe3b06ecf17 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 14:27:38 -0400 Subject: [PATCH 028/289] hide-threads.js: show post hider even in posts without an image --- js/hide-threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 75339455..cc06ad0b 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -46,7 +46,7 @@ $(document).ready(function(){ } $('[–] ') - .insertBefore(thread_container.find('p.fileinfo:first')) + .insertBefore(thread_container.find(':first')) .click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); From 95c50ae778d4e47b2076a6af0df61a05180c3dd1 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 14:57:08 -0400 Subject: [PATCH 029/289] hide-threads.js: fix previous commit --- js/hide-threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index cc06ad0b..00ddbc48 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -68,7 +68,7 @@ $(document).ready(function(){ hidden_div.remove(); }); - hidden_div.insertAfter(thread_container.find('p.fileinfo:first')); + hidden_div.insertAfter(thread_container.find(':first')); }); if (hidden_data[board][id]) thread_container.find('.hide-thread-link').click(); From 1a43b8731525e7268b1c4e167b8116fdf97b28c4 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 15:31:20 -0400 Subject: [PATCH 030/289] hide-threads.js: further fixes and customisations, mainly due to unexpanding previously not working here, but working on another boards (4chon, etc.) --- js/hide-threads.js | 7 ++++--- stylesheets/style.css | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 00ddbc48..abaa700f 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -55,11 +55,12 @@ $(document).ready(function(){ var hidden_div = thread_container.find('div.post.op > p.intro').clone(); hidden_div.addClass('thread-hidden'); - hidden_div.find('a[href],input').remove(); + hidden_div.find('a[href]:not([href$=".html"]),input').remove(); + hidden_div.html(hidden_div.html().replace(' [] ', ' ')); hidden_div.html(hidden_div.html().replace(' [] ', ' ')); - $('[+] ') - .insertAfter(thread_container.find('a.hide-thread-link')) + $('[+] ') + .insertBefore(hidden_div.find(':first')) .click(function() { delete hidden_data[board][id]; store_data(); diff --git a/stylesheets/style.css b/stylesheets/style.css index 0339864b..393f9faa 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -458,6 +458,7 @@ table.mod.config-editor input[type="text"] { background-color: #fff; opacity: 0.8; } -.thread-hidden { - opacity: 0.5; +p.intro.thread-hidden { + margin: 0px; + padding: 0px; } From 595a165fa317c5fa967345dd6fdb10bd2a585a2a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 26 Jul 2013 18:22:48 -0400 Subject: [PATCH 031/289] install.sql mistake --- install.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sql b/install.sql index d32c3e3e..ee2ca8a9 100644 --- a/install.sql +++ b/install.sql @@ -143,7 +143,7 @@ CREATE TABLE IF NOT EXISTS `mods` ( -- Dumping data for table `mods` -- -INSERT INTO `mods` (`id`, `username`, `password`, `type`, `boards`) VALUES +INSERT INTO `mods` (`id`, `username`, `password`, `salt`, `type`, `boards`) VALUES (1, 'admin', 'cedad442efeef7112fed0f50b011b2b9bf83f6898082f995f69dd7865ca19fb7', '4a44c6c55df862ae901b413feecb0d49', 2, '*'); -- -------------------------------------------------------- From baa6793516242890222d3b4c94cac3f31649bd3b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 26 Jul 2013 19:39:11 -0400 Subject: [PATCH 032/289] toggle-images.js (this was written last year, but I never pushed it to git) --- js/toggle-images.js | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 js/toggle-images.js diff --git a/js/toggle-images.js b/js/toggle-images.js new file mode 100644 index 00000000..006b3622 --- /dev/null +++ b/js/toggle-images.js @@ -0,0 +1,50 @@ +/* + * toggle-images.js + * + * Released under the MIT license + * Copyright (c) 2012 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/toggle-images.js'; + * + */ + +$(document).ready(function(){ + var hide_images = localStorage['hideimages'] ? true : false; + + $('').appendTo($('head')); + + var hideImage = function() { + $(this) + .attr('data-orig', this.src) + .attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') + .addClass('hidden'); + }; + + var restoreImage = function() { + $(this) + .attr('src', $(this).attr('data-orig')) + .removeClass('hidden'); + }; + + $('hr:first').before(''); + $('div#toggle-images a') + .text((hide_images ? 'Show' : 'Hide') + ' images') + .click(function() { + hide_images = !hide_images; + if (hide_images) { + $('div > a > img').each(hideImage); + localStorage.hideimages = true; + } else { + $('div > a > img').each(restoreImage); + delete localStorage.hideimages; + } + + $(this).text((hide_images ? 'Show' : 'Hide') + ' images') + }); + + if (hide_images) { + $('div > a > img').each(hideImage); + } +}); From a11c8981fe87f58d7205fc478c8ba68dca9aa3c2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 26 Jul 2013 19:55:28 -0400 Subject: [PATCH 033/289] js/hide-images.js: Hide individual images --- js/hide-images.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 js/hide-images.js diff --git a/js/hide-images.js b/js/hide-images.js new file mode 100644 index 00000000..75dc07c2 --- /dev/null +++ b/js/hide-images.js @@ -0,0 +1,81 @@ +/* + * hide-images.js + * https://github.com/savetheinternet/Tinyboard/blob/master/js/hide-images.js + * + * Hide individual images. + * + * Released under the MIT license + * Copyright (c) 2013 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/hide-images.js'; + * + */ + +$(document).ready(function(){ + $('').appendTo($('head')); + + var board = $('form input[name="board"]').val().toString(); + + if (!localStorage.hiddenimages) + localStorage.hiddenimages = '{}'; + + // Load data from HTML5 localStorage + var hidden_data = JSON.parse(localStorage.hiddenimages); + + var store_data = function() { + localStorage.hiddenimages = JSON.stringify(hidden_data); + }; + + // Delete old hidden images (30+ days old) + for (var key in hidden_data) { + for (var id in hidden_data[key]) { + if (hidden_data[key][id] < Math.round(Date.now() / 1000) - 60 * 60 * 24 * 30) { + delete hidden_data[key][id]; + store_data(); + } + } + } + + if (!hidden_data[board]) { + hidden_data[board] = {}; // id : timestamp + } + + $('div.post > a > img, div > a > img').each(function() { + var img = this; + var fileinfo = $(this).parent().prev(); + var id = $(this).parent().parent().find('>p.intro>a.post_no:eq(1),>div.post.op>p.intro>a.post_no:eq(1)').text(); + + var replacement = $('File (hide): '); + + replacement.find('a').click(function() { + hidden_data[board][id] = Math.round(Date.now() / 1000); + store_data(); + + var show_link = $('show').click(function() { + delete hidden_data[board][id]; + store_data(); + + $(img) + .removeClass('hidden') + .attr('src', $(img).data('orig')); + $(this).prev().show(); + $(this).remove(); + }); + + $(this).hide().after(show_link); + + $(img) + .data('orig', img.src) + .attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') + .addClass('hidden'); + }); + + $(this).parent().prev().contents().first().replaceWith(replacement); + + if (hidden_data[board][id]) + $(this).parent().prev().find('.hide-image-link').click(); + + }); +}); From a28b5fc3a1975af863d348d3851b90b3c398baaf Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 22:34:06 -0400 Subject: [PATCH 034/289] expand.js: fix a weird bug - thread expand not always worked due to post being loaded in DOM, but not put in a right place in a thread, or so, so check if it has been loaded in a thread instead of if it exists in DOM --- js/expand.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/expand.js b/js/expand.js index 0e3537a8..1a719fad 100644 --- a/js/expand.js +++ b/js/expand.js @@ -27,7 +27,7 @@ $(document).ready(function(){ success: function(data) { var last_expanded = false; $(data).find('div.post.reply').each(function() { - if($('#' + $(this).attr('id')).length == 0) { + if(thread.find('#' + $(this).attr('id')).length == 0) { if(last_expanded) { $(this).addClass('expanded').insertAfter(last_expanded).before('
'); } else { From e5bdf63692487e07833bbc4197ae7cd98e5af7e4 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 22:39:00 -0400 Subject: [PATCH 035/289] expand.js: fix post order when new posts appear between loading index and expanding --- js/expand.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/expand.js b/js/expand.js index 1a719fad..a737ee7f 100644 --- a/js/expand.js +++ b/js/expand.js @@ -27,7 +27,8 @@ $(document).ready(function(){ success: function(data) { var last_expanded = false; $(data).find('div.post.reply').each(function() { - if(thread.find('#' + $(this).attr('id')).length == 0) { + var post_in_doc = thread.find('#' + $(this).attr('id')); + if(post_in_doc.length == 0) { if(last_expanded) { $(this).addClass('expanded').insertAfter(last_expanded).before('
'); } else { @@ -37,6 +38,9 @@ $(document).ready(function(){ $(document).trigger('new_post', this); } + else { + last_expanded = post_in_doc; + } }); $('' + _('Hide expanded replies') + '.') .insertAfter(thread.find('span.omitted').css('display', 'none')) From 35f8730f40d745b93cefbca92d5e83a18599f70c Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 00:13:54 -0400 Subject: [PATCH 036/289] ukko: fix top boardlist losing its fixed status --- templates/themes/ukko/ukko.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 +}); From c0a45ba1237fd54c0d5050d3a70abdea022ff6c3 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 27 Jul 2013 00:14:43 -0400 Subject: [PATCH 037/289] Allow hide-images.js, toggle-images.js and inline-expanding.js to work together --- js/hide-images.js | 5 ++++- js/inline-expanding.js | 33 ++++++++++++++++++++------------- js/toggle-images.js | 29 ++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/js/hide-images.js b/js/hide-images.js index 75dc07c2..7344cd8f 100644 --- a/js/hide-images.js +++ b/js/hide-images.js @@ -53,7 +53,7 @@ $(document).ready(function(){ hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); - var show_link = $('show').click(function() { + var show_link = $('show').click(function() { delete hidden_data[board][id]; store_data(); @@ -66,6 +66,9 @@ $(document).ready(function(){ $(this).hide().after(show_link); + if ($(img).parent()[0].dataset.expanded == 'true') { + $(img).parent().click(); + } $(img) .data('orig', img.src) .attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') diff --git a/js/inline-expanding.js b/js/inline-expanding.js index f6714d7f..2e924f05 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -3,7 +3,7 @@ * https://github.com/savetheinternet/Tinyboard/blob/master/js/inline-expanding.js * * Released under the MIT license - * Copyright (c) 2012 Michael Save + * Copyright (c) 2012-2013 Michael Save * * Usage: * $config['additional_javascript'][] = 'js/inline-expanding.js'; @@ -13,30 +13,37 @@ onready(function(){ var link = document.getElementsByTagName('a'); - for(var i = 0; i < link.length; i++) { - if(typeof link[i] == "object" && link[i].childNodes[0].src && link[i].className != 'file') { + for (var i = 0; i < link.length; i++) { + if (typeof link[i] == "object" && link[i].childNodes && link[i].childNodes[0].src && link[i].className != 'file') { link[i].childNodes[0].style.maxWidth = '95%'; link[i].childNodes[0].style.maxHeight = '95%'; link[i].onclick = function(e) { - if(e.which == 2) { + if (this.childNodes[0].className == 'hidden') + return false; + if (e.which == 2) return true; - } - if(!this.tag) { - this.tag = this.childNodes[0].src; + if (!this.dataset.src) { + this.dataset.expanded = 'true'; + this.dataset.src= this.childNodes[0].src; + this.dataset.width = this.childNodes[0].style.width; + this.dataset.height = this.childNodes[0].style.height; this.childNodes[0].src = this.href; this.childNodes[0].style.width = 'auto'; this.childNodes[0].style.height = 'auto'; this.childNodes[0].style.opacity = '0.4'; this.childNodes[0].style.filter = 'alpha(opacity=40)'; this.childNodes[0].onload = function() { - this.style.opacity = '1'; - this.style.filter = ''; + this.style.opacity = ''; + delete this.style.filter; } } else { - this.childNodes[0].src = this.tag; - this.childNodes[0].style.width = 'auto'; - this.childNodes[0].style.height = 'auto'; - this.tag = ''; + this.childNodes[0].src = this.dataset.src; + this.childNodes[0].style.width = this.dataset.width; + this.childNodes[0].style.height = this.dataset.height; + delete this.dataset.expanded; + delete this.dataset.src; + delete this.childNodes[0].style.opacity; + delete this.childNodes[0].style.filter; } return false; } diff --git a/js/toggle-images.js b/js/toggle-images.js index 006b3622..74f2fab4 100644 --- a/js/toggle-images.js +++ b/js/toggle-images.js @@ -16,6 +16,9 @@ $(document).ready(function(){ $('').appendTo($('head')); var hideImage = function() { + if ($(this).parent()[0].dataset.expanded == 'true') { + $(this).parent().click(); + } $(this) .attr('data-orig', this.src) .attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') @@ -28,6 +31,27 @@ $(document).ready(function(){ .removeClass('hidden'); }; + // Fix for hide-images.js + var show_hide_hide_images_buttons = function() { + if (hide_images) { + $('a.hide-image-link').each(function() { + if ($(this).next().hasClass('show-image-link')) { + $(this).next().hide(); + } + $(this).hide().after('hidden'); + }); + } else { + $('span.toggle-images-placeholder').remove(); + $('a.hide-image-link').each(function() { + if ($(this).next().hasClass('show-image-link')) { + $(this).next().show(); + } else { + $(this).show(); + } + }); + } + }; + $('hr:first').before(''); $('div#toggle-images a') .text((hide_images ? 'Show' : 'Hide') + ' images') @@ -40,11 +64,14 @@ $(document).ready(function(){ $('div > a > img').each(restoreImage); delete localStorage.hideimages; } - + + show_hide_hide_images_buttons(); + $(this).text((hide_images ? 'Show' : 'Hide') + ' images') }); if (hide_images) { $('div > a > img').each(hideImage); + show_hide_hide_images_buttons(); } }); From 6bf217941a3342cdcf7768ab5269f7d35b050984 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 22:34:06 -0400 Subject: [PATCH 038/289] expand.js: fix a weird bug - thread expand not always worked due to post being loaded in DOM, but not put in a right place in a thread, or so, so check if it has been loaded in a thread instead of if it exists in DOM --- js/expand.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/expand.js b/js/expand.js index 05aece95..d0b4583c 100644 --- a/js/expand.js +++ b/js/expand.js @@ -27,7 +27,7 @@ $(document).ready(function(){ success: function(data) { var last_expanded = false; $(data).find('div.post.reply').each(function() { - if($('#' + $(this).attr('id')).length == 0) { + if(thread.find('#' + $(this).attr('id')).length == 0) { if(last_expanded) { $(this).addClass('expanded').insertAfter(last_expanded).before('
'); } else { From d82cd9b7bd03708f4940b4508acd0394713b8869 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 22:39:00 -0400 Subject: [PATCH 039/289] expand.js: fix post order when new posts appear between loading index and expanding --- js/expand.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/expand.js b/js/expand.js index d0b4583c..16a0efb2 100644 --- a/js/expand.js +++ b/js/expand.js @@ -27,7 +27,8 @@ $(document).ready(function(){ success: function(data) { var last_expanded = false; $(data).find('div.post.reply').each(function() { - if(thread.find('#' + $(this).attr('id')).length == 0) { + var post_in_doc = thread.find('#' + $(this).attr('id')); + if(post_in_doc.length == 0) { if(last_expanded) { $(this).addClass('expanded').insertAfter(last_expanded).before('
'); } else { @@ -36,6 +37,9 @@ $(document).ready(function(){ last_expanded = $(this); } + else { + last_expanded = post_in_doc; + } }); $('Hide expanded replies.') .insertAfter(thread.find('span.omitted').css('display', 'none')) From c51dc146e2248a09d97941a73ac5ef65ee4e1085 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 14:27:38 -0400 Subject: [PATCH 040/289] hide-threads.js: show post hider even in posts without an image --- js/hide-threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 734dfe78..03c33a3f 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -45,7 +45,7 @@ $(document).ready(function(){ var id = $(this).children('p.intro').children('a.post_no:eq(1)').text(); var thread_container = $(this).parent(); $('[–] ') - .insertBefore(thread_container.find('p.fileinfo:first')) + .insertBefore(thread_container.find(':first')) .click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); From 4b50f1475e5cdf6afa2db0aef0345ad00a9d6a7f Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 14:57:08 -0400 Subject: [PATCH 041/289] hide-threads.js: fix previous commit --- js/hide-threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 03c33a3f..14893e05 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -67,7 +67,7 @@ $(document).ready(function(){ hidden_div.remove(); }); - hidden_div.insertAfter(thread_container.find('p.fileinfo:first')); + hidden_div.insertAfter(thread_container.find(':first')); }); if (hidden_data[board][id]) thread_container.find('.hide-thread-link').click(); From 1c33285c81efe174f09e99b15be81f527c0f8ae0 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 26 Jul 2013 15:31:20 -0400 Subject: [PATCH 042/289] hide-threads.js: further fixes and customisations, mainly due to unexpanding previously not working here, but working on another boards (4chon, etc.) Conflicts: stylesheets/style.css --- js/hide-threads.js | 7 ++++--- stylesheets/style.css | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/js/hide-threads.js b/js/hide-threads.js index 14893e05..faa1289c 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -54,11 +54,12 @@ $(document).ready(function(){ var hidden_div = thread_container.find('div.post.op > p.intro').clone(); hidden_div.addClass('thread-hidden'); - hidden_div.find('a[href],input').remove(); + hidden_div.find('a[href]:not([href$=".html"]),input').remove(); + hidden_div.html(hidden_div.html().replace(' [] ', ' ')); hidden_div.html(hidden_div.html().replace(' [] ', ' ')); - $('[+] ') - .insertAfter(thread_container.find('a.hide-thread-link')) + $('[+] ') + .insertBefore(hidden_div.find(':first')) .click(function() { delete hidden_data[board][id]; store_data(); diff --git a/stylesheets/style.css b/stylesheets/style.css index 12cc54d5..c0430b7c 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -404,3 +404,8 @@ table.mod.config-editor td { table.mod.config-editor input[type="text"] { width: 98%; } +p.intro.thread-hidden { + margin: 0px; + padding: 0px; +} + From e3cb427feefbbb4fd6a5e76ce77ef80a240941f1 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 00:57:12 -0400 Subject: [PATCH 043/289] 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(-) 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() { } } }); - }); From 880cf25366797affa6279508f3ba8779e3b6da46 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:08:26 -0400 Subject: [PATCH 044/289] fix merge --- js/expand.js | 3 --- js/inline-expanding.js | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/js/expand.js b/js/expand.js index 6b8657bd..06151627 100644 --- a/js/expand.js +++ b/js/expand.js @@ -41,9 +41,6 @@ $(document).ready(function(){ else { last_expanded = post_in_doc; } - else { - last_expanded = post_in_doc; - } }); $('' + _('Hide expanded replies') + '.') .insertAfter(thread.find('span.omitted').css('display', 'none')) diff --git a/js/inline-expanding.js b/js/inline-expanding.js index fb78c222..1849b078 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -16,9 +16,8 @@ onready(function(){ var link = this.getElementsByTagName('a'); for (var i = 0; i < link.length; i++) { - if (typeof link[i] == "object" && link[i].childNodes && link[i].childNodes[0].src && link[i].className != 'file') { + if (typeof link[i] == "object" && link[i].childNodes && typeof link[i].childNodes[0] !== 'undefined' && link[i].childNodes[0].src && link[i].className != 'file') { link[i].childNodes[0].style.maxWidth = '95%'; - link[i].childNodes[0].style.maxHeight = '95%'; link[i].onclick = function(e) { if (this.childNodes[0].className == 'hidden') return false; From d09ef2215433892dbd6e79fe41084dedd0e47931 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:12:22 -0400 Subject: [PATCH 045/289] hide-images.js: javascript i18n --- js/hide-images.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/hide-images.js b/js/hide-images.js index 7344cd8f..365ebac6 100644 --- a/js/hide-images.js +++ b/js/hide-images.js @@ -47,13 +47,13 @@ $(document).ready(function(){ var fileinfo = $(this).parent().prev(); var id = $(this).parent().parent().find('>p.intro>a.post_no:eq(1),>div.post.op>p.intro>a.post_no:eq(1)').text(); - var replacement = $('File (hide): '); + var replacement = $(''+_('File')+' ('+_('hide')+'): '); replacement.find('a').click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); - var show_link = $('show').click(function() { + var show_link = $(''+_('show')+'').click(function() { delete hidden_data[board][id]; store_data(); From 3e5234e54e3052cbdc6e17691182766e17824fe7 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:16:12 -0400 Subject: [PATCH 046/289] toggle-images.js: javascript i18n --- js/toggle-images.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/toggle-images.js b/js/toggle-images.js index 74f2fab4..de1d47b3 100644 --- a/js/toggle-images.js +++ b/js/toggle-images.js @@ -38,7 +38,7 @@ $(document).ready(function(){ if ($(this).next().hasClass('show-image-link')) { $(this).next().hide(); } - $(this).hide().after('hidden'); + $(this).hide().after(''+_('hidden')+''); }); } else { $('span.toggle-images-placeholder').remove(); @@ -54,7 +54,7 @@ $(document).ready(function(){ $('hr:first').before(''); $('div#toggle-images a') - .text((hide_images ? 'Show' : 'Hide') + ' images') + .text(hide_images ? _('Show images') : _('Hide images')) .click(function() { hide_images = !hide_images; if (hide_images) { @@ -67,7 +67,7 @@ $(document).ready(function(){ show_hide_hide_images_buttons(); - $(this).text((hide_images ? 'Show' : 'Hide') + ' images') + $(this).text(hide_images ? _('Show images') : _('Hide images')) }); if (hide_images) { From 1157864612957cbb23a19655315abab9b197e203 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:19:30 -0400 Subject: [PATCH 047/289] banned.php: remove polish strings; html5; needs further work --- banned.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/banned.php b/banned.php index 5ab85312..57e4a9bc 100644 --- a/banned.php +++ b/banned.php @@ -1,7 +1,7 @@ Banned?"; - print "

Nie jestes zbanowany.

"; + print ""._("Banned?").""; + print "

"._("You are not banned.")."

"; print ""; ?> From ae99c6dd0d8e2b523adfa279e8590c34f93eea13 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:21:30 -0400 Subject: [PATCH 048/289] i18n one more string in inc/functions.php --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index cd5cb75b..371a01f1 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -591,7 +591,7 @@ function displayBan($ban) { // Show banned page and exit die( Element('page.html', array( - 'title' => 'Banned!', + 'title' => _('Banned!'), 'config' => $config, 'body' => Element('banned.html', array( 'config' => $config, From 3f2ea6b936d5cb2153f50e51c9a15cf883f6529a Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:33:21 -0400 Subject: [PATCH 049/289] i18n some strings in inc/config.php --- inc/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/config.php b/inc/config.php index adfaa5e8..f046392b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -327,7 +327,7 @@ $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; - $config['robot_mute_descritpion'] = 'You have been muted for unoriginal content.'; + $config['robot_mute_descritpion'] = _('You have been muted for unoriginal content.'); // Automatically convert things like "..." to Unicode characters ("…") $config['auto_unicode'] = true; @@ -908,7 +908,7 @@ $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). - $config['mod']['default_ban_message'] = 'USER WAS BANNED FOR THIS POST'; + $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']['ban_message'] = '(%s)'; From e2b1034f091313e89143d40503d51d67e00f2f98 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:38:03 -0400 Subject: [PATCH 050/289] categories theme: fix title displaying twice, put boardlist there instead --- templates/themes/categories/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 }}
From b31487b53d4ec715616d40a3aadf6f3fc345d697 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:43:09 -0400 Subject: [PATCH 051/289] categories theme: i18n some strings --- templates/themes/categories/news.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 %} From 065a6f97c813da1ecc6cf4d431aba9a418092acf Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:50:38 -0400 Subject: [PATCH 052/289] localise time values --- inc/functions.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 371a01f1..180c74d5 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -546,35 +546,35 @@ function checkFlood($post) { function until($timestamp) { $difference = $timestamp - time(); if ($difference < 60) { - return $difference . ' second' . ($difference != 1 ? 's' : ''); + return $difference . ' ' . ngettext('second', 'seconds', $difference); } elseif ($difference < 60*60) { - return ($num = round($difference/(60))) . ' minute' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); } elseif ($difference < 60*60*24) { - return ($num = round($difference/(60*60))) . ' hour' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60))) . ' ' . ngettext('hour', 'hours', $num); } elseif ($difference < 60*60*24*7) { - return ($num = round($difference/(60*60*24))) . ' day' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24))) . ' ' . ngettext('day', 'days', $num); } elseif ($difference < 60*60*24*365) { - return ($num = round($difference/(60*60*24*7))) . ' week' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*7))) . ' ' . ngettext('week', 'weeks', $num); } - return ($num = round($difference/(60*60*24*365))) . ' year' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*365))) . ' ' . ngettext('year', 'years', $num); } function ago($timestamp) { $difference = time() - $timestamp; if ($difference < 60) { - return $difference . ' second' . ($difference != 1 ? 's' : ''); + return $difference . ' ' . ngettext('second', 'seconds', $difference); } elseif ($difference < 60*60) { - return ($num = round($difference/(60))) . ' minute' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); } elseif ($difference < 60*60*24) { - return ($num = round($difference/(60*60))) . ' hour' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60))) . ' ' . ngettext('hour', 'hours', $num); } elseif ($difference < 60*60*24*7) { - return ($num = round($difference/(60*60*24))) . ' day' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24))) . ' ' . ngettext('day', 'days', $num); } elseif ($difference < 60*60*24*365) { - return ($num = round($difference/(60*60*24*7))) . ' week' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*7))) . ' ' . ngettext('week', 'weeks', $num); } - return ($num = round($difference/(60*60*24*365))) . ' year' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*365))) . ' ' . ngettext('year', 'years', $num); } function displayBan($ban) { From 396492aad6b7271752214d4806b0aba3a4048cb1 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:01:42 -0400 Subject: [PATCH 053/289] Update Polish locale --- inc/locale/pl_PL/LC_MESSAGES/javascript.js | 2 +- inc/locale/pl_PL/LC_MESSAGES/javascript.po | 26 +- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 18730 -> 19790 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 338 +++++++++++++++++++-- 4 files changed, 342 insertions(+), 24 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.js b/inc/locale/pl_PL/LC_MESSAGES/javascript.js index 44857b98..caf4a66c 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.js +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.js @@ -1 +1 @@ -l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie"}; \ No newline at end of file +l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie","hide":"ukryj","show":"poka\u017c","hidden":"ukryte","Show images":"Poka\u017c obrazki","Hide images":"Ukryj obrazki"}; \ No newline at end of file diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po index 3c16c8d7..482ec45f 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.po +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-18 16:31-0400\n" +"POT-Creation-Date: 2013-07-27 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,7 @@ msgstr "Kliknij Odpowiedź aby zobaczyć." msgid "Click to expand" msgstr "Kliknij aby rozwinąć" -#: ../../../../js/expand.js:41 +#: ../../../../js/expand.js:41 ../../../../js/expand.js:45 msgid "Hide expanded replies" msgstr "Schowaj rozwinięte odpowiedzi" @@ -104,7 +104,7 @@ msgstr "Hasło" msgid "Delete file only" msgstr "Usuń tylko plik" -#: ../../../../js/quick-post-controls.js:30 +#: ../../../../js/quick-post-controls.js:30 ../../../../js/hide-images.js:50 msgid "File" msgstr "Plik" @@ -119,3 +119,23 @@ msgstr "Powód" #: ../../../../js/quick-post-controls.js:37 msgid "Report" msgstr "Zgłoszenie" + +#: ../../../../js/hide-images.js:50 +msgid "hide" +msgstr "ukryj" + +#: ../../../../js/hide-images.js:56 +msgid "show" +msgstr "pokaż" + +#: ../../../../js/toggle-images.js:41 +msgid "hidden" +msgstr "ukryte" + +#: ../../../../js/toggle-images.js:57 ../../../../js/toggle-images.js:70 +msgid "Show images" +msgstr "Pokaż obrazki" + +#: ../../../../js/toggle-images.js:57 ../../../../js/toggle-images.js:70 +msgid "Hide images" +msgstr "Ukryj obrazki" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index b1ccc28dccca8e142bb299e8262d99d762ed7270..2a31d64e2b739bc537600e64426544aa1e58a4fe 100644 GIT binary patch delta 6892 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 XB<7_u\n" "Language-Team: LANGUAGE \n" @@ -52,10 +52,11 @@ msgstr "Stwórz nowy board" #: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:75 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:150 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:207 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:155 msgid "all boards" msgstr "wszystkie boardy" -#: /var/www/html/Tinyboard/inc/config.php:305 +#: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 msgid "You have been muted for unoriginal content." msgstr "Zostałeś zagłuszony za nieoryginalną treść." @@ -83,16 +84,19 @@ msgstr "Szybka odpowiedź" #. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 #: ../../../../inc/config.php:692 ../../../../inc/config.php:698 +#: ../../../../inc/config.php:695 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 #: ../../../../inc/config.php:693 ../../../../inc/config.php:699 +#: ../../../../inc/config.php:696 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 #: ../../../../inc/config.php:694 ../../../../inc/config.php:700 +#: ../../../../inc/config.php:697 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " @@ -100,135 +104,161 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 #: ../../../../inc/config.php:695 ../../../../inc/config.php:701 +#: ../../../../inc/config.php:698 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 #: ../../../../inc/config.php:696 ../../../../inc/config.php:702 +#: ../../../../inc/config.php:699 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 #: ../../../../inc/config.php:697 ../../../../inc/config.php:703 +#: ../../../../inc/config.php:700 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 #: ../../../../inc/config.php:698 ../../../../inc/config.php:704 +#: ../../../../inc/config.php:701 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 #: ../../../../inc/config.php:699 ../../../../inc/config.php:705 +#: ../../../../inc/config.php:702 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 #: ../../../../inc/config.php:700 ../../../../inc/config.php:706 +#: ../../../../inc/config.php:703 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 #: ../../../../inc/config.php:701 ../../../../inc/config.php:707 +#: ../../../../inc/config.php:704 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 #: ../../../../inc/config.php:702 ../../../../inc/config.php:708 +#: ../../../../inc/config.php:705 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 #: ../../../../inc/config.php:703 ../../../../inc/config.php:709 +#: ../../../../inc/config.php:706 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 #: ../../../../inc/config.php:706 ../../../../inc/config.php:712 +#: ../../../../inc/config.php:709 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 #: ../../../../inc/config.php:707 ../../../../inc/config.php:713 +#: ../../../../inc/config.php:710 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 #: ../../../../inc/config.php:708 ../../../../inc/config.php:714 +#: ../../../../inc/config.php:711 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 #: ../../../../inc/config.php:709 ../../../../inc/config.php:715 +#: ../../../../inc/config.php:712 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 #: ../../../../inc/config.php:710 ../../../../inc/config.php:716 +#: ../../../../inc/config.php:713 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 +#: ../../../../inc/config.php:714 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 +#: ../../../../inc/config.php:715 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 +#: ../../../../inc/config.php:716 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 +#: ../../../../inc/config.php:717 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 #: ../../../../inc/config.php:715 ../../../../inc/config.php:721 +#: ../../../../inc/config.php:718 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 #: ../../../../inc/config.php:716 ../../../../inc/config.php:722 +#: ../../../../inc/config.php:719 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 #: ../../../../inc/config.php:717 ../../../../inc/config.php:723 +#: ../../../../inc/config.php:720 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 #: ../../../../inc/config.php:718 ../../../../inc/config.php:724 +#: ../../../../inc/config.php:721 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 #: ../../../../inc/config.php:719 ../../../../inc/config.php:725 +#: ../../../../inc/config.php:722 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 #: ../../../../inc/config.php:720 ../../../../inc/config.php:726 +#: ../../../../inc/config.php:723 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 #: ../../../../inc/config.php:721 ../../../../inc/config.php:727 +#: ../../../../inc/config.php:724 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 #: ../../../../inc/config.php:722 ../../../../inc/config.php:728 +#: ../../../../inc/config.php:725 msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
Rozmiar twojego pliku: %filesz% " @@ -236,28 +266,33 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 #: ../../../../inc/config.php:723 ../../../../inc/config.php:729 +#: ../../../../inc/config.php:726 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 #: ../../../../inc/config.php:724 ../../../../inc/config.php:730 +#: ../../../../inc/config.php:727 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 #: ../../../../inc/config.php:725 ../../../../inc/config.php:731 +#: ../../../../inc/config.php:728 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 #: ../../../../inc/config.php:727 ../../../../inc/config.php:733 +#: ../../../../inc/config.php:730 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 #: ../../../../inc/config.php:728 ../../../../inc/config.php:734 +#: ../../../../inc/config.php:731 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " @@ -265,26 +300,31 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 #: ../../../../inc/config.php:729 ../../../../inc/config.php:735 +#: ../../../../inc/config.php:732 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 #: ../../../../inc/config.php:730 ../../../../inc/config.php:736 +#: ../../../../inc/config.php:733 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 #: ../../../../inc/config.php:734 ../../../../inc/config.php:740 +#: ../../../../inc/config.php:737 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 #: ../../../../inc/config.php:735 ../../../../inc/config.php:741 +#: ../../../../inc/config.php:738 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 #: ../../../../inc/config.php:736 ../../../../inc/config.php:742 +#: ../../../../inc/config.php:739 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -293,55 +333,65 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 #: ../../../../inc/config.php:737 ../../../../inc/config.php:743 +#: ../../../../inc/config.php:740 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 #: ../../../../inc/config.php:738 ../../../../inc/config.php:744 +#: ../../../../inc/config.php:741 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 #: ../../../../inc/config.php:739 ../../../../inc/config.php:745 +#: ../../../../inc/config.php:742 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 #: ../../../../inc/config.php:740 ../../../../inc/config.php:746 +#: ../../../../inc/config.php:743 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 #: ../../../../inc/config.php:741 ../../../../inc/config.php:747 +#: ../../../../inc/config.php:744 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 #: ../../../../inc/config.php:742 ../../../../inc/config.php:748 +#: ../../../../inc/config.php:745 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 #: ../../../../inc/config.php:743 ../../../../inc/config.php:749 +#: ../../../../inc/config.php:746 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 #: ../../../../inc/config.php:744 ../../../../inc/config.php:750 +#: ../../../../inc/config.php:747 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 #: ../../../../inc/config.php:745 ../../../../inc/config.php:751 +#: ../../../../inc/config.php:748 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 #: ../../../../inc/config.php:746 ../../../../inc/config.php:752 +#: ../../../../inc/config.php:749 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -377,7 +427,9 @@ msgstr "[Edytuj]" msgid "[Move]" msgstr "[Przenieś]" -#: /var/www/html/Tinyboard/inc/config.php:801 +#. Default public ban message. +#. In public ban messages, %length% is replaced with "for x days" or "permanently" (with %LENGTH% being the uppercase equivalent). +#: /var/www/html/Tinyboard/inc/config.php:801 ../../../../inc/config.php:911 msgid "USER WAS BANNED FOR THIS POST" msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" @@ -453,7 +505,7 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:292 #: /var/www/html/Tinyboard/inc/display.php:408 #: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 -#: ../../../../inc/mod/pages.php:1239 +#: ../../../../inc/mod/pages.php:1239 ../../../../inc/mod/pages.php:1242 msgid "Edit post" msgstr "Edytuj post" @@ -485,12 +537,17 @@ msgstr "Zablokuj wątek" msgid "Move thread to another board" msgstr "Przenieś wątek na inny board" +#. line 11 +#. line 7 #. line 11 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:48 #: /var/www/html/Tinyboard/mod.php:667 /var/www/html/Tinyboard/mod.php:750 #: /var/www/html/Tinyboard/mod.php:833 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:55 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:55 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:31 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:36 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:33 msgid "Name" msgstr "Nazwa" @@ -501,11 +558,14 @@ msgstr "Nazwa" msgid "Email" msgstr "E-mail" +#. line 34 +#. line 23 #. line 34 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:96 #: /var/www/html/Tinyboard/mod.php:753 /var/www/html/Tinyboard/mod.php:839 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:95 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:116 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:63 msgid "Subject" msgstr "Temat" @@ -579,6 +639,7 @@ msgstr "Komentarz" #. line 73 #. line 61 #. line 73 +#. line 61 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:191 @@ -638,26 +699,35 @@ msgstr "Weryfikacja" #. line 87 #. line 3 #. line 87 +#. line 3 +#. line 72 +#. line 3 +#. line 72 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:22 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:22 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:250 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:214 msgid "File" msgstr "Plik" #. line 97 +#. line 82 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:163 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:183 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:268 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:232 msgid "Embed" msgstr "Osadź" #. line 109 +#. line 94 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:179 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:206 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:291 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:255 msgid "Flags" msgstr "Flagi" @@ -713,12 +783,18 @@ msgstr "Flagi" #. line 114 #. line 113 #. line 114 +#. line 98 +#. line 99 +#. line 98 +#. line 99 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:218 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:300 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:303 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:264 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:267 msgid "Sticky" msgstr "Przyklejony" @@ -774,12 +850,18 @@ msgstr "Przyklejony" #. line 118 #. line 117 #. line 118 +#. line 102 +#. line 103 +#. line 102 +#. line 103 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:230 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:312 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:315 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:276 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:279 msgid "Lock" msgstr "Zablokowany" @@ -835,18 +917,25 @@ msgstr "Zablokowany" #. line 122 #. line 121 #. line 122 +#. line 106 +#. line 107 +#. line 106 +#. line 107 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:242 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:324 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:327 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:288 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:291 msgid "Raw HTML" msgstr "Czysty HTML" #. line 129 #. line 14 #. line 129 +#. line 114 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:230 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:23 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:257 @@ -854,13 +943,16 @@ msgstr "Czysty HTML" #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:23 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:342 #: ../../../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:41 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:306 msgid "Password" msgstr "Hasło" #. line 134 +#. line 119 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:236 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:266 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:351 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:315 msgid "(For file deletion.)" msgstr "(do usuwania postów)" @@ -887,6 +979,7 @@ msgstr "Odśwież" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:415 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:461 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:472 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:506 msgid "Reply" msgstr "Odpowiedź" @@ -894,6 +987,7 @@ msgstr "Odpowiedź" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:442 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:488 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:499 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:533 msgid "1 post" msgid_plural "%count% posts" msgstr[0] "1 post" @@ -905,6 +999,7 @@ msgstr[2] "%count% postów" #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:494 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 #: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:114 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:539 msgid "and" msgstr "oraz" @@ -912,6 +1007,7 @@ msgstr "oraz" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:459 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:516 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:550 msgid "1 image reply" msgid_plural "%count% image replies" msgstr[0] "1 obrazek" @@ -922,6 +1018,7 @@ msgstr[2] "%count% obrazków" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:464 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:510 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:521 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:555 msgid "omitted. Click reply to view." msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." @@ -935,15 +1032,19 @@ msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." #: ../../../../templates/cache/62/8c/21348d46377c3e1b3f8c476ba376.php:62 #: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:131 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:115 +#: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:132 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:116 msgid "Return to dashboard" msgstr "Powróć na tablicę" #. line 27 #. line 31 +#. line 32 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:165 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:177 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:106 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:123 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:124 msgid "Posting mode: Reply" msgstr "Tryb postowania: Odpowiedź" @@ -955,6 +1056,8 @@ msgstr "Tryb postowania: Odpowiedź" #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:155 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:126 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:172 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:127 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:173 msgid "Return" msgstr "Powrót" @@ -970,6 +1073,12 @@ msgstr "Usuń post" #. line 8 #. line 32 #. line 48 +#. line 106 +#. line 8 +#. line 32 +#. line 106 +#. line 8 +#. line 32 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 @@ -990,6 +1099,8 @@ msgstr "Zgłoszenie" #: /var/www/html/Tinyboard/mod.php:104 /var/www/html/Tinyboard/mod.php:776 #: /var/www/html/Tinyboard/mod.php:862 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:120 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:125 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:89 msgid "no subject" msgstr "brak tematu" @@ -1012,6 +1123,7 @@ msgstr "Aktualności" #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 #: ../../../../inc/mod/pages.php:1682 ../../../../inc/mod/pages.php:1816 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 +#: ../../../../inc/mod/pages.php:1831 msgid "Report queue" msgstr "Kolejka zgłoszeń" @@ -1026,6 +1138,7 @@ msgstr "Lista banów" #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 #: ../../../../inc/mod/pages.php:1394 ../../../../inc/mod/pages.php:1528 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 +#: ../../../../inc/mod/pages.php:1543 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -1059,11 +1172,13 @@ msgstr "Pokaż konfigurację" #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 #: ../../../../inc/mod/pages.php:1830 ../../../../inc/mod/pages.php:1964 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 +#: ../../../../inc/mod/pages.php:1979 msgid "Manage themes" msgstr "Zarządzaj dodatkami" #. line 2 #. line 5 +#. line 2 #: /var/www/html/Tinyboard/mod.php:170 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:19 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:24 @@ -1074,11 +1189,14 @@ msgstr "Wyrażenie:" #. line 2 #. line 106 #. line 2 +#. line 16 +#. line 106 #: /var/www/html/Tinyboard/mod.php:172 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:72 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:19 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:286 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:19 +#: ../../../../search.php:165 msgid "Search" msgstr "Szukaj" @@ -1097,8 +1215,10 @@ msgid "Could not find current version! (Check .installed)" msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" #. line 146 +#. line 158 #: /var/www/html/Tinyboard/mod.php:233 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:364 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:397 msgid "Logout" msgstr "Wyloguj" @@ -1128,17 +1248,25 @@ msgstr "temu" #. line 65 #. line 49 #. line 136 +#. line 116 +#. line 182 +#. line 65 +#. line 116 +#. line 182 +#. line 65 #: /var/www/html/Tinyboard/mod.php:405 /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:278 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:427 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:142 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:131 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:355 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:147 msgid "Board" msgstr "Board" #. line 183 #. line 137 +#. line 183 #: /var/www/html/Tinyboard/mod.php:406 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:430 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:358 @@ -1147,42 +1275,54 @@ msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 #: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 -#: ../../../../inc/mod/pages.php:1948 +#: ../../../../inc/mod/pages.php:1948 ../../../../inc/mod/pages.php:1963 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 #: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 -#: ../../../../inc/mod/pages.php:1950 +#: ../../../../inc/mod/pages.php:1950 ../../../../inc/mod/pages.php:1965 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." +#. line 11 #: /var/www/html/Tinyboard/mod.php:671 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:42 msgid "Version" msgstr "Wersja" +#. line 15 #: /var/www/html/Tinyboard/mod.php:675 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:51 msgid "Description" msgstr "Opis" +#. line 19 #: /var/www/html/Tinyboard/mod.php:679 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:60 msgid "Thumbnail" msgstr "Miniatura" +#. line 25 #: /var/www/html/Tinyboard/mod.php:687 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:86 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:77 msgid "Actions" msgstr "Akcje" +#. line 27 #: /var/www/html/Tinyboard/mod.php:689 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:81 msgid "Use theme" msgstr "Użyj dodatku" #: /var/www/html/Tinyboard/mod.php:690 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:87 msgid "Reconfigure" msgstr "Rekonfiguruj" #: /var/www/html/Tinyboard/mod.php:690 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:88 msgid "Install" msgstr "Instaluj" @@ -1192,10 +1332,13 @@ msgstr "Instaluj" #: ../../../../inc/mod/pages.php:1596 ../../../../inc/mod/pages.php:1726 #: ../../../../inc/mod/pages.php:1730 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 +#: ../../../../inc/mod/pages.php:1741 ../../../../inc/mod/pages.php:1745 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:98 msgid "Rebuild" msgstr "Przebuduj" #: /var/www/html/Tinyboard/mod.php:694 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:103 msgid "Uninstall" msgstr "Odinstaluj" @@ -1203,7 +1346,9 @@ msgstr "Odinstaluj" msgid "Uninstall all themes." msgstr "Odinstaluj wszystkie dodatki" +#. line 27 #: /var/www/html/Tinyboard/mod.php:756 /var/www/html/Tinyboard/mod.php:842 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:69 msgid "Body" msgstr "Zawartość" @@ -1269,6 +1414,7 @@ msgstr "Nie można się ponownie zalogować po zmianie hasła. (?)" #. line 126 #. line 50 +#. line 126 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:300 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:134 @@ -1277,6 +1423,7 @@ msgstr "Ustawione" #. line 130 #. line 52 +#. line 130 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:309 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:140 @@ -1290,6 +1437,14 @@ msgstr "Wygasa" #. line 17 #. line 54 #. line 133 +#. line 24 +#. line 62 +#. line 150 +#. line 180 +#. line 24 +#. line 62 +#. line 150 +#. line 180 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:74 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:169 @@ -1328,7 +1483,7 @@ msgid "No board to move to; there is only one." msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." #: ../../../../inc/config.php:689 ../../../../inc/config.php:747 -#: ../../../../inc/config.php:753 +#: ../../../../inc/config.php:753 ../../../../inc/config.php:750 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." @@ -1346,6 +1501,10 @@ msgstr "Edytuj board" msgid "New board" msgstr "Nowy board" +#. line 102 +#. line 20 +#. line 102 +#. line 20 #. line 102 #. line 20 #: ../../../../inc/mod/pages.php:586 ../../../../inc/mod/pages.php:612 @@ -1361,6 +1520,7 @@ msgstr "adres IP" #: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 #: ../../../../inc/mod/pages.php:772 ../../../../inc/mod/pages.php:1187 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:398 +#: ../../../../inc/mod/pages.php:1190 msgid "New ban" msgstr "Nowy ban" @@ -1380,6 +1540,7 @@ msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1307 ../../../../inc/mod/pages.php:1356 #: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 #: ../../../../inc/mod/pages.php:1466 ../../../../inc/mod/pages.php:1515 +#: ../../../../inc/mod/pages.php:1477 ../../../../inc/mod/pages.php:1530 msgid "Edit user" msgstr "Edytuj użytkownika" @@ -1388,11 +1549,13 @@ msgstr "Edytuj użytkownika" #: ../../../../inc/mod/pages.php:1431 ../../../../inc/mod/pages.php:1503 #: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 #: ../../../../inc/mod/pages.php:1590 ../../../../inc/mod/pages.php:1662 +#: ../../../../inc/mod/pages.php:1605 ../../../../inc/mod/pages.php:1677 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 #: ../../../../inc/mod/pages.php:1460 ../../../../inc/mod/pages.php:1594 +#: ../../../../inc/mod/pages.php:1609 msgid "Private message" msgstr "Prywatna wiadomość" @@ -1400,33 +1563,39 @@ msgstr "Prywatna wiadomość" #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 #: ../../../../inc/mod/pages.php:1481 ../../../../inc/mod/pages.php:1615 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 +#: ../../../../inc/mod/pages.php:1630 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 #: ../../../../inc/mod/pages.php:1804 ../../../../inc/mod/pages.php:1938 +#: ../../../../inc/mod/pages.php:1953 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 #: ../../../../inc/mod/pages.php:1970 ../../../../inc/mod/pages.php:2104 +#: ../../../../inc/mod/pages.php:2119 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 #: ../../../../inc/mod/pages.php:1892 ../../../../inc/mod/pages.php:2026 +#: ../../../../inc/mod/pages.php:2041 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 #: ../../../../inc/mod/pages.php:1903 ../../../../inc/mod/pages.php:2037 +#: ../../../../inc/mod/pages.php:2052 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 #: ../../../../inc/mod/pages.php:1931 ../../../../inc/mod/pages.php:2065 +#: ../../../../inc/mod/pages.php:2080 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1438,20 +1607,24 @@ msgid "" msgstr "" #: ../../../../inc/config.php:704 ../../../../inc/config.php:710 +#: ../../../../inc/config.php:707 msgid "Thread has reached its maximum reply limit." msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." #: ../../../../inc/config.php:705 ../../../../inc/config.php:711 +#: ../../../../inc/config.php:708 msgid "Thread has reached its maximum image limit." msgstr "Ten temat osiągnął swój maksymalny limit obrazków." #: ../../../../inc/config.php:726 ../../../../inc/config.php:732 +#: ../../../../inc/config.php:729 #, php-format msgid "That file already exists in this thread!" msgstr "Ten plik już istnieje w tym temacie!" #. Moderator errors #: ../../../../inc/config.php:733 ../../../../inc/config.php:739 +#: ../../../../inc/config.php:736 #, php-format msgid "" "You are only allowed to unban %s users at a time. You tried to unban %u " @@ -1460,12 +1633,12 @@ msgstr "" "Możesz odbanować tylko %s użytkowników na raz. Próbowałeś odbanować %u users." #: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 -#: ../../../../inc/mod/pages.php:2128 +#: ../../../../inc/mod/pages.php:2128 ../../../../inc/mod/pages.php:2143 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" #: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 -#: ../../../../inc/mod/pages.php:2152 +#: ../../../../inc/mod/pages.php:2152 ../../../../inc/mod/pages.php:2167 msgid "Debug: SQL" msgstr "Debug: SQL" @@ -1500,9 +1673,9 @@ msgid "" "(Search is case-insensitive and based on keywords. To match exact phrases, " "use \"quotes\". Use an asterisk (*) for wildcard.)" msgstr "" -"(Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " -"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " -"wieloznacznego.)" +"(Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach " +"kluczowych. Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki " +"(*) jako symbolu wieloznacznego.)" #. line 8 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:32 @@ -1520,14 +1693,14 @@ msgid "" "example, name:Anonymous or subject:\"Some Thread\". " "Wildcards cannot be used in filters." msgstr "" -"Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " -"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " -"wieloznacznego.

Możesz zastosować poniższe " -"filtry do swojego wyszukiwania: id, thread, " -"subject, i name. Aby wykorzystać filtr, " -"po prostu dodaj do swojego zapytania, na przykład: name:Anonymous " -"albo subject:\"Jakiś temat\". Symbole wieloznaczne nie mogą być " -"wykorzystane w filtrach." +"Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach " +"kluczowych. Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki " +"(*) jako symbolu wieloznacznego.

Możesz zastosować poniższe filtry do swojego wyszukiwania: id, thread, subject, i name. Aby wykorzystać filtr, po prostu dodaj do swojego zapytania, na " +"przykład: name:Anonymous albo subject:\"Jakiś temat\". " +"Symbole wieloznaczne nie mogą być wykorzystane w filtrach." #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:57 msgid "edit" @@ -1552,32 +1725,45 @@ msgid "Change password" msgstr "Zmień hasło" #. line 118 +#. line 130 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:308 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:341 msgid "Debug" msgstr "Debug" #. line 120 +#. line 132 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:312 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:345 msgid "Anti-spam" msgstr "Antyspam" #. line 121 +#. line 133 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:315 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:348 msgid "Recent posts" msgstr "Ostatnie posty" #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:321 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:354 msgid "SQL" msgstr "SQL" #. line 143 +#. line 155 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:359 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:392 msgid "User account" msgstr "Konto użytkownika" #. line 25 #. line 67 #. line 18 +#. line 25 +#. line 67 +#. line 25 +#. line 67 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:77 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:179 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:54 @@ -1586,6 +1772,7 @@ msgstr "Notka" #. line 26 #. line 19 +#. line 26 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:80 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:57 msgid "Date" @@ -1634,6 +1821,7 @@ msgstr "nigdy" #. line 140 #. line 53 +#. line 140 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:331 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:143 msgid "Seen" @@ -1656,6 +1844,7 @@ msgstr "Usuń ban" #. line 181 #. line 135 +#. line 181 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:424 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:352 msgid "Time" @@ -1753,16 +1942,19 @@ msgstr "Wiadomość" #. line 46 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:117 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:122 msgid "public; attached to post" msgstr "publiczny; dołączony do posta" #. line 58 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:133 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:138 msgid "Length" msgstr "Długość" #. line 88 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:192 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:197 msgid "New Ban" msgstr "Nowy ban" @@ -1799,3 +1991,109 @@ msgstr[2] "%d wyników na" #: ../../../../search.php:160 msgid "No results." msgstr "Brak wyników." + +#: ../../../../inc/functions.php:594 +msgid "Banned!" +msgstr "Zbanowany!" + +#: ../../../../banned.php:4 +msgid "Banned?" +msgstr "Zbanowany?" + +#: ../../../../banned.php:5 +msgid "You are not banned." +msgstr "Nie jesteś zbanowany." + +#: ../../../../inc/functions.php:549 ../../../../inc/functions.php:566 +msgid "second" +msgid_plural "seconds" +msgstr[0] "sekunda" +msgstr[1] "sekundy" +msgstr[2] "sekund" + +#: ../../../../inc/functions.php:551 ../../../../inc/functions.php:568 +msgid "minute" +msgid_plural "minutes" +msgstr[0] "minuta" +msgstr[1] "minuty" +msgstr[2] "minut" + +#: ../../../../inc/functions.php:553 ../../../../inc/functions.php:570 +msgid "hour" +msgid_plural "hours" +msgstr[0] "godzina" +msgstr[1] "godziny" +msgstr[2] "godzin" + +#: ../../../../inc/functions.php:555 ../../../../inc/functions.php:572 +msgid "day" +msgid_plural "days" +msgstr[0] "dzień" +msgstr[1] "dni" +msgstr[2] "dni" + +#: ../../../../inc/functions.php:557 ../../../../inc/functions.php:574 +msgid "week" +msgid_plural "weeks" +msgstr[0] "tydzień" +msgstr[1] "tygodnie" +msgstr[2] "tygodni" + +#: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 +msgid "year" +msgid_plural "years" +msgstr[0] "rok" +msgstr[1] "lata" +msgstr[2] "lat" + +#. line 118 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:308 +msgid "Other" +msgstr "Inne" + +#: ../../../../templates/cache/b7/7d/de31d12a1684acbc7c0d7ee71653.php:30 +msgid "Successfully installed and built theme." +msgstr "Pomyślnie zainstalowano i zbudowano dodatek." + +#. line 9 +#: ../../../../templates/cache/b7/7d/de31d12a1684acbc7c0d7ee71653.php:37 +msgid "Go back to themes" +msgstr "Wróć do dodatków" + +#. line 3 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:21 +msgid "New post" +msgstr "Nowy post" + +#. line 32 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:76 +msgid "Post news entry" +msgstr "Zapostuj newsa" + +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:100 +msgid "delete" +msgstr "usuń" + +#. line 55 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:133 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:94 +msgid "by" +msgstr "przez" + +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:136 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:97 +msgid "at" +msgstr "dnia" + +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:66 +msgid "(No news to show.)" +msgstr "(Nie ma newsów do wyświetlenia.)" + +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:19 +msgid "There are no themes available." +msgstr "Nie ma dostępnych dodatków." + +#. line 25 +#: ../../../../templates/cache/d1/99/467985632043e204070d354b8290.php:91 +msgid "Install theme" +msgstr "Zainstaluj dodatek" From 7af28a6e14a87cbd73bf0bc9b9fafecfdf5719f7 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:06:50 -0400 Subject: [PATCH 054/289] Tag as vichan-devel-4.0.4-gold --- install.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.php b/install.php index 7c095c53..458344a0 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ vichan-devel-4.0.3'); +define('VERSION', 'v0.9.6-dev-9 + vichan-devel-4.0.4-gold'); require 'inc/functions.php'; @@ -253,6 +253,7 @@ if (file_exists($config['has_installed'])) { } } case 'v0.9.6-dev-9': + case 'v0.9.6-dev-9 + vichan-devel-4.0.3': case false: // Update version number file_write($config['has_installed'], VERSION); From 07ea457aa53729212e345eb0907b932f3939a3d9 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:19:58 -0400 Subject: [PATCH 055/289] inline-expanding.js: missed preventing default action; shouldn't open new window when unwanted anymore --- js/inline-expanding.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/inline-expanding.js b/js/inline-expanding.js index 1849b078..0f7b7229 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -46,6 +46,7 @@ onready(function(){ delete this.childNodes[0].style.opacity; delete this.childNodes[0].style.filter; } + return false; } } } From 4ffbbe7a23f04855a72082cdedecc9d6b919afff Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:21:08 -0400 Subject: [PATCH 056/289] Tag for vichan-devel-4.0.5-gold after bugfix --- install.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.php b/install.php index 458344a0..20a51775 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ vichan-devel-4.0.4-gold'); +define('VERSION', 'v0.9.6-dev-9 + vichan-devel-4.0.5-gold'); require 'inc/functions.php'; @@ -254,6 +254,7 @@ if (file_exists($config['has_installed'])) { } case 'v0.9.6-dev-9': case 'v0.9.6-dev-9 + vichan-devel-4.0.3': + case 'v0.9.6-dev-9 + vichan-devel-4.0.4-gold': case false: // Update version number file_write($config['has_installed'], VERSION); From 26b6dfb126fd3522cac3594fc7064b899465b856 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:34:15 -0400 Subject: [PATCH 057/289] dark.css stylesheet fixes --- stylesheets/dark.css | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/stylesheets/dark.css b/stylesheets/dark.css index 920debe8..bb342e05 100644 --- a/stylesheets/dark.css +++ b/stylesheets/dark.css @@ -25,13 +25,13 @@ div.title p { } a:link, a:visited, p.intro a.email span.name { color: #CCCCCC; - text-decoration: underline; + text-decoration: none; font-family: sans-serif; } a:link:hover, a:visited:hover { color: #fff; font-family: sans-serif; - text-decoration: underline overline; + text-decoration: none; } a.post_no { @@ -45,9 +45,14 @@ a.post_no:hover { div.post.reply { background: #333333; border: #555555 1px solid; + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + } div.post.reply.highlighted { - background: transparent; + background: #555; border: transparent 1px solid; } div.post.reply div.body a:link, div.post.reply div.body a:visited { From 98187303d77c41fa94430fa1302f071041c58bfc Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:38:03 -0400 Subject: [PATCH 058/289] categories theme: fix title displaying twice, put boardlist there instead --- templates/themes/categories/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 }}
From cea7881749e85b4ba5c8444e738d42a27d91244f Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:43:09 -0400 Subject: [PATCH 059/289] categories theme: i18n some strings --- templates/themes/categories/news.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 %} From 57c8e4ee7cea126e68ade4913c57a46f06d1a2b0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 28 Jul 2013 20:33:26 -0400 Subject: [PATCH 060/289] Strip combining characters from Unicode strings (eg. Zalgo) --- inc/config.php | 2 ++ inc/functions.php | 48 ++++++++++++++++++++++++++++++++++++++++++++++- post.php | 9 ++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/inc/config.php b/inc/config.php index 98e127b3..d7580a8b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -282,6 +282,8 @@ $config['strip_superfluous_returns'] = true; // Require an image for threads? $config['force_image_op'] = true; + // Strip combining characters from Unicode strings (eg. "Zalgo") + $config['strip_combining_chars'] = true; // Max body length $config['max_body'] = 1800; diff --git a/inc/functions.php b/inc/functions.php index b5660664..9d398002 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1526,7 +1526,53 @@ function utf8tohtml($utf8) { return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); } -function buildThread($id, $return=false, $mod=false) { +function ordutf8($string, &$offset) { + $code = ord(substr($string, $offset,1)); + if ($code >= 128) { // otherwise 0xxxxxxx + if ($code < 224) + $bytesnumber = 2; // 110xxxxx + else if ($code < 240) + $bytesnumber = 3; // 1110xxxx + else if ($code < 248) + $bytesnumber = 4; // 11110xxx + $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0); + for ($i = 2; $i <= $bytesnumber; $i++) { + $offset ++; + $code2 = ord(substr($string, $offset, 1)) - 128; //10xxxxxx + $codetemp = $codetemp*64 + $code2; + } + $code = $codetemp; + } + $offset += 1; + if ($offset >= strlen($string)) + $offset = -1; + return $code; +} + +function strip_combining_chars($str) { + $chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY); + $str = ''; + foreach ($chars as $char) { + $ord = ordutf8($char, $o = 0); + + if ($ord >= 768 && $ord <= 879) + continue; + + if ($ord >= 7616 && $ord <= 7679) + continue; + + if ($ord >= 8400 && $ord <= 8447) + continue; + + if ($ord >= 65056 && $ord <= 65071) + continue; + + $str .= $char; + } + return $str; +} + +function buildThread($id, $return = false, $mod = false) { global $board, $config; $id = round($id); diff --git a/post.php b/post.php index 4e3a1a9f..6855fe14 100644 --- a/post.php +++ b/post.php @@ -357,6 +357,13 @@ if (isset($_POST['delete'])) { $post['thumb'] = $board['dir'] . $config['dir']['thumb'] . $post['file_id'] . '.' . ($config['thumb_ext'] ? $config['thumb_ext'] : $post['extension']); } + if ($config['strip_combining_chars']) { + $post['name'] = strip_combining_chars($post['name']); + $post['email'] = strip_combining_chars($post['email']); + $post['subject'] = strip_combining_chars($post['name']); + $post['body'] = strip_combining_chars($post['body']); + } + // Check string lengths if (mb_strlen($post['name']) > 35) error(sprintf($config['error']['toolong'], 'name')); @@ -368,7 +375,7 @@ if (isset($_POST['delete'])) { error($config['error']['toolong_body']); if (mb_strlen($post['password']) > 20) error(sprintf($config['error']['toolong'], 'password')); - + wordfilters($post['body']); $post['body_nomarkup'] = $post['body']; From bd8bd3c02e6cb8e130058649e646a8c8071d3386 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 28 Jul 2013 20:46:00 -0400 Subject: [PATCH 061/289] Fix for last commit --- inc/functions.php | 5 +++-- post.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 9d398002..2915e1b6 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1552,8 +1552,9 @@ function ordutf8($string, &$offset) { function strip_combining_chars($str) { $chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY); $str = ''; - foreach ($chars as $char) { - $ord = ordutf8($char, $o = 0); + foreach ($chars as $char) { + $o = 0; + $ord = ordutf8($char, $o); if ($ord >= 768 && $ord <= 879) continue; diff --git a/post.php b/post.php index 6855fe14..ad045b66 100644 --- a/post.php +++ b/post.php @@ -360,7 +360,7 @@ if (isset($_POST['delete'])) { if ($config['strip_combining_chars']) { $post['name'] = strip_combining_chars($post['name']); $post['email'] = strip_combining_chars($post['email']); - $post['subject'] = strip_combining_chars($post['name']); + $post['subject'] = strip_combining_chars($post['subject']); $post['body'] = strip_combining_chars($post['body']); } From 5bab0418142fb2b9d37389f68733faa76c381ffe Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 12:27:10 -0400 Subject: [PATCH 062/289] Make font-awesome enabled by default --- inc/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/config.php b/inc/config.php index d7580a8b..7dda86ab 100644 --- a/inc/config.php +++ b/inc/config.php @@ -568,7 +568,7 @@ // 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'] = false; + $config['font_awesome'] = true; $config['font_awesome_css'] = 'stylesheets/font-awesome/css/font-awesome.min.css'; // Boardlinks From c0e0a5db7d566aed16d5d9d9036a1f46f658e9eb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 13:14:21 -0400 Subject: [PATCH 063/289] Error in news template --- templates/mod/news.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) }}

From 58306bdc63b7dcaf964ab3541fe4b5a8e0c813b0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:18:06 -0400 Subject: [PATCH 064/289] Search posts --- inc/config.php | 2 + inc/mod/pages.php | 41 +++++++++++-- templates/mod/search_results.html | 97 ++++++++++++++++++++++++++++++- 3 files changed, 132 insertions(+), 8 deletions(-) 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 %}

From c8e93f04d2522224dd84b7d93e526b918a105451 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:24:11 -0400 Subject: [PATCH 065/289] Update search results template --- templates/mod/search_results.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 %} From e0bc0a622de2e4b9a8e02f9b48979d14dba04c94 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:26:32 -0400 Subject: [PATCH 066/289] 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(-) 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 }} From d44b4f19a8760699a8895cbf9856a4cc0a0f5a65 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 16:31:36 -0400 Subject: [PATCH 067/289] See last commit --- templates/mod/debug/recent_posts.html | 2 +- templates/mod/search_results.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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
+
From 1759ac2ea30d3c374beb6b5b6fa76bfa5501da9f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 29 Jul 2013 20:20:07 -0400 Subject: [PATCH 068/289] Post search: Search other fields too --- inc/mod/pages.php | 16 ++++++++++++++-- templates/mod/search_results.html | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) 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)) %} From 7c8bbe8527be504804893672cc26430d11c272f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Sun, 23 Dec 2012 04:38:20 +0100 Subject: [PATCH 097/289] 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(+) 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 %} )

From daca11113e5c96e11c9c5518fa55bae0b27054a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Fri, 28 Dec 2012 19:08:25 +0100 Subject: [PATCH 098/289] image identification: add imgops.com button --- templates/post_reply.html | 1 + templates/post_thread.html | 1 + 2 files changed, 2 insertions(+) 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 %} From 64bc410484d9c161275f8a47e212bef345433fb1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 04:02:40 -0400 Subject: [PATCH 099/289] Small comment change --- inc/config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/config.php b/inc/config.php index 55c49045..0ff0600b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -486,7 +486,7 @@ // Display the file's original filename $config['show_filename']= true; - // Image identification buttons using regex.info/exif, tineye and google images + // 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) @@ -757,9 +757,9 @@ 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://"; + // 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'; // If for some reason the folders and static HTML index files aren't in the current working direcotry, From cbab1f9ac219b7b01a59e09ee59b95087b23b860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Tue, 18 Dec 2012 04:53:24 +0100 Subject: [PATCH 100/289] Updated Polish translation --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 12437 -> 13437 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 256 ++++++++++++++++------ 2 files changed, 186 insertions(+), 70 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 53bc309ac3f56b48ac595c2e38f35167828648b6..f1f40e8e210ecc7f8e3129089a569a5d70cdf3bf 100644 GIT binary patch delta 5284 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 A_y7O^ delta 4270 zcmeyHF*ULNo)F7a1_lO(jSLJ7G7Jn1OIR5g-ZL;T=x~EX85myhF))ZQFfhF2V_>LZ zU|{&i$H1V>z`#(=4-ucw&%nUOz`(GDpMim$fq`K+KLZ0Z0|Ucheg+0f1_p-X{0t1D z3=9kp`572E85kJ8^D{8mGB7YO3NSFJGBDIL*b6{3qzW)F@GvkiWC}1aa4;}1lnF2} zure?()C)i?Xcb^!U}0cj=n;SzI8lIs!GM8*VYvVUgD?XF!wmrj29TTI2tXY2Lx6#S z7vu*)1_mPr1_nMs1_pfw1_nn#1_pZu28KdGkVonn7&ZzrFbFU(FkBU6VBlw9V0b17 zap^Zfh{X&-5QEu;7#PGD7#M`1d@Uh}Ix``NLmi;B8-kY`|ED1s`SB*ehL#K6EXONfDii-Cb*E>wJl5X7Mygcun37#J81Lg@=a z3=E143=H>$7#Ms(K`YF_AjQDI;4chuc$P54;xZ_|S{UNsc3}pFdQjZ;3NtXsF)%Pp z5oTbpV_;y|EDZ7KCt(JV=NULfAVDc30*N9m5e5bq1_lOm5r{)-L?CIW8!Ep-1Y+S< z5l9H_g3?Ez;^(0BWf6vY26a%}K@9+<6i^(>ibB$WrYIyzjG%lcQAkjFi$WX{EDDMH z1W^VC4+aK?5-5MKC645Fh^*g@g#B7{q*Dv3f`xiHSiBmKB4fYE?0a zLMy1a8h+070vvL z5QAkD8Ng+}k|HFRXevU2+*FZ)!JUDD!B-Iy=Tj9S7Oqr;gv<#=NR(buWMHrY6meHRlpzKeL+MIoh|BAt3g;<9isYrrkhog` zr8g==qGFda#K9MoL5Yfi;juErBR`ZG7?K$n7?f2Qzy)2q3M53=t3VvOuU-XG!ktoq z1ko)Ohzp;nKz#m2g@GZ6fq{WT6_TBzRUzs#RUsBtszMTPpDF`G2m=Gd3aGljst^xw zt3jedOAX>dJ2i+sE@}`5)cdJH;v@>HAYBbow&$urT)asQ;L*1a_!5WY>5DTRp9M8{JyicTuy{QK!vPIQ zkY3e*1kqEdL9e0w?-~pYIt&a9e>EUQsFo%JgDC?8L$D?Tg9HNuL#HOhfr~UDA+QI^ zzpM$#6>l{mA;78yNfU}%kSOs1@j>}NK?`DVw-&^JEm{l=)(i{`r?ntK$*v6v2^DQf z{?^lm6i~t13=B#P3=AFGknFlz8?g&On+Dle=HX=17ALVO;k3kkVAT}UpO ztqVy58+9Rd$pu}8dT<-=gD$j|(}M&}upT66)Ablq=g*+@JAH@;zUf1`d63~3Ay z2WB%s>Xak~28Lcx;}sPD5ey6ru?!3htD%ZPwOcooUC6+|u!aHRxam+aP@g7#J2YK$_l> z3=9lw86Z(s#K6GN#=yWZA5>9++W-Cx3=HX@wi^Qj!$JlIhG`6tlB@yRDFGQ)#lXPO z!T@Qggn|SZAnmA0L*K7s` zh6xM|468sbT&T)821wQe)q;~jr5aRxF{md5YQjVLASxe3FfcGQF)%QMGcYhTLir#H z)PE>vfaC@cp8*vAU>CK;FhI(N3I+y-nV=j3>QO<(K@{A6P={kFNQ42>KXYP$vJ$ z%;d=q;%SrDi=UX>F5$TOmV_5OtAU=Sp6O&`1p{saV_id21p`YfW6Q~T3KI2328Kqu zNP^l1h6V;)K8eL8x*oDinDcTPqagloloC*yh>V8YsHuUOHnt`prUppZ zz{b!(p{52b4pL*FsbH^Qs9>dFw7F4n6BCbjeqLH;dTCK&a#rHz1{Gz-$(vPOAmJ*b z7BA=s3RMNq0BE?DW=(#jX1}>qU72a}N=?nl_cX;Ob7-xYyhrQH +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. # +#, fuzzy msgid "" msgstr "" -"Project-Id-Version: 0.9.5\n" +"Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-15 09:39+0100\n" -"PO-Revision-Date: 2012-03-15 09:39+0100\n" -"Last-Translator: Marcin \"czaks\" Łabanowski \n" -"Language-Team: POLISH \n" -"Language: Polish\n" +"POT-Creation-Date: 2012-12-18 04:43+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: /var/www/html/Tinyboard/inc/functions.php:958 #: /var/www/html/Tinyboard/inc/functions.php:972 +#: ../../../../inc/functions.php:1041 ../../../../inc/functions.php:1055 msgid "Previous" msgstr "Wstecz" #: /var/www/html/Tinyboard/inc/functions.php:977 #: /var/www/html/Tinyboard/inc/functions.php:986 +#: ../../../../inc/functions.php:1060 ../../../../inc/functions.php:1069 msgid "Next" msgstr "Dalej" @@ -61,218 +63,218 @@ msgstr "Odpowiedz" msgid "Quick Reply" msgstr "Szybka odpowiedź" -#: /var/www/html/Tinyboard/inc/config.php:600 +#: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." -#: /var/www/html/Tinyboard/inc/config.php:601 +#: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 msgid "You look like a bot." msgstr "Wyglądasz jak bot." -#: /var/www/html/Tinyboard/inc/config.php:602 +#: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " "odsyłaczu w nagłówku" -#: /var/www/html/Tinyboard/inc/config.php:603 +#: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" -#: /var/www/html/Tinyboard/inc/config.php:604 +#: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 msgid "The body was too long." msgstr "Zawartość jest za długa." -#: /var/www/html/Tinyboard/inc/config.php:605 +#: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." -#: /var/www/html/Tinyboard/inc/config.php:606 +#: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." -#: /var/www/html/Tinyboard/inc/config.php:607 +#: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." -#: /var/www/html/Tinyboard/inc/config.php:608 +#: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." -#: /var/www/html/Tinyboard/inc/config.php:609 +#: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 msgid "Invalid board!" msgstr "Niepoprawny board!" -#: /var/www/html/Tinyboard/inc/config.php:610 +#: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." -#: /var/www/html/Tinyboard/inc/config.php:611 +#: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." -#: /var/www/html/Tinyboard/inc/config.php:612 +#: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." -#: /var/www/html/Tinyboard/inc/config.php:613 +#: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." -#: /var/www/html/Tinyboard/inc/config.php:614 +#: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." -#: /var/www/html/Tinyboard/inc/config.php:615 +#: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" -#: /var/www/html/Tinyboard/inc/config.php:616 +#: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." -#: /var/www/html/Tinyboard/inc/config.php:617 +#: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." -#: /var/www/html/Tinyboard/inc/config.php:618 +#: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." -#: /var/www/html/Tinyboard/inc/config.php:619 +#: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." -#: /var/www/html/Tinyboard/inc/config.php:620 +#: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." -#: /var/www/html/Tinyboard/inc/config.php:621 +#: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." -#: /var/www/html/Tinyboard/inc/config.php:622 +#: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." -#: /var/www/html/Tinyboard/inc/config.php:623 +#: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." -#: /var/www/html/Tinyboard/inc/config.php:624 +#: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." -#: /var/www/html/Tinyboard/inc/config.php:625 +#: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 msgid "Wrong password…" msgstr "Niepoprawne hasło" -#: /var/www/html/Tinyboard/inc/config.php:626 +#: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 msgid "Invalid image." msgstr "Niepoprawny obrazek." -#: /var/www/html/Tinyboard/inc/config.php:627 +#: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." -#: /var/www/html/Tinyboard/inc/config.php:628 +#: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
Rozmiar twojego pliku: %filesz% " "bajtów" -#: /var/www/html/Tinyboard/inc/config.php:629 +#: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 msgid "The file was too big." msgstr "Plik jest za duży." -#: /var/www/html/Tinyboard/inc/config.php:630 +#: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" -#: /var/www/html/Tinyboard/inc/config.php:631 +#: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" -#: /var/www/html/Tinyboard/inc/config.php:632 +#: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." -#: /var/www/html/Tinyboard/inc/config.php:633 +#: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " "odrzucony" -#: /var/www/html/Tinyboard/inc/config.php:634 +#: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." -#: /var/www/html/Tinyboard/inc/config.php:635 +#: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." -#: /var/www/html/Tinyboard/inc/config.php:638 +#: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" -#: /var/www/html/Tinyboard/inc/config.php:639 +#: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" -#: /var/www/html/Tinyboard/inc/config.php:640 +#: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" "Niepoprawna nazwa użytkownika, bądź hasło. Twoje konto mogło zostać usunięte " "albo zmienione." -#: /var/www/html/Tinyboard/inc/config.php:641 +#: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." -#: /var/www/html/Tinyboard/inc/config.php:642 +#: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." -#: /var/www/html/Tinyboard/inc/config.php:643 +#: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." -#: /var/www/html/Tinyboard/inc/config.php:644 +#: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." -#: /var/www/html/Tinyboard/inc/config.php:645 +#: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" -#: /var/www/html/Tinyboard/inc/config.php:646 +#: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." -#: /var/www/html/Tinyboard/inc/config.php:647 +#: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." -#: /var/www/html/Tinyboard/inc/config.php:648 +#: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 msgid "Page not found." msgstr "Strona nie znaleziona." -#: /var/www/html/Tinyboard/inc/config.php:649 +#: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" -#: /var/www/html/Tinyboard/inc/config.php:650 +#: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -329,7 +331,8 @@ msgstr "Wystąpił błąd." msgid "Go back" msgstr "Wróć" -#: /var/www/html/Tinyboard/inc/display.php:97 +#: /var/www/html/Tinyboard/inc/display.php:97 ../../../../inc/display.php:91 +#: ../../../../inc/mod/pages.php:59 msgid "Login" msgstr "Logowanie" @@ -344,6 +347,7 @@ msgstr "" #: /var/www/html/Tinyboard/inc/display.php:272 #: /var/www/html/Tinyboard/inc/display.php:365 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:27 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:27 msgid "Delete" msgstr "Usuń" @@ -413,69 +417,90 @@ msgstr "Przenieś wątek na inny board" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:48 #: /var/www/html/Tinyboard/mod.php:667 /var/www/html/Tinyboard/mod.php:750 #: /var/www/html/Tinyboard/mod.php:833 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:55 msgid "Name" msgstr "Nazwa" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:62 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:76 msgid "Email" msgstr "E-mail" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:96 #: /var/www/html/Tinyboard/mod.php:753 /var/www/html/Tinyboard/mod.php:839 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:95 msgid "Subject" msgstr "Temat" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:110 #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:119 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:112 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:117 msgid "Spoiler Image" msgstr "Spoiler obrazek" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:119 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:121 msgid "Comment" msgstr "Komentarz" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 msgid "Verification" msgstr "Weryfikacja" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:22 msgid "File" msgstr "Plik" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:163 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:183 msgid "Embed" msgstr "Osadź" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:179 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:206 msgid "Flags" msgstr "Flagi" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:218 msgid "Sticky" msgstr "Przyklejony" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:230 msgid "Lock" msgstr "Zablokowany" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:242 msgid "Raw HTML" msgstr "Czysty HTML" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:230 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:23 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:257 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:23 msgid "Password" msgstr "Hasło" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:236 +#: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:266 msgid "(For file deletion.)" msgstr "(do usuwania postów)" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:107 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:105 msgid "File:" msgstr "Plik:" @@ -493,10 +518,12 @@ msgid "Refresh" msgstr "Odśwież" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:478 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:415 msgid "Reply" msgstr "Odpowiedź" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:511 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:442 msgid "1 post" msgid_plural "%count% posts" msgstr[0] "1 post" @@ -504,10 +531,12 @@ msgstr[1] "%count% posty" msgstr[2] "%count% postów" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:517 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:448 msgid "and" msgstr "oraz" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:528 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:459 msgid "1 image reply" msgid_plural "%count% image replies" msgstr[0] "1 obrazek" @@ -515,34 +544,43 @@ msgstr[1] "%count% obrazki" msgstr[2] "%count% obrazków" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:533 +#: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:464 msgid "omitted. Click reply to view." msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." #: /var/www/html/Tinyboard/templates/cache/c9/45/de4b7a1b91ef4b1ce35c7a930347.php:82 #: /var/www/html/Tinyboard/templates/cache/56/25/feb68d2e52b15e0d38ae0093f0f4.php:158 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:159 +#: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:169 +#: ../../../../templates/cache/7a/d3/9236b821893e6bc57b16919988fd.php:169 msgid "Return to dashboard" msgstr "Powróć na tablicę" #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:165 +#: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:177 msgid "Posting mode: Reply" msgstr "Tryb postowania: Odpowiedź" #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:168 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:210 +#: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:180 +#: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:222 msgid "Return" msgstr "Powrót" #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:19 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:19 msgid "Delete Post" msgstr "Usuń post" #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 msgid "Reason" msgstr "Powód" #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:36 +#: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:36 msgid "Report" msgstr "Zgłoszenie" @@ -560,18 +598,22 @@ msgid "PM Inbox" msgstr "Wiadomości prywatne" #: /var/www/html/Tinyboard/mod.php:136 /var/www/html/Tinyboard/mod.php:874 +#: ../../../../inc/mod/pages.php:376 msgid "News" msgstr "Aktualności" #: /var/www/html/Tinyboard/mod.php:141 /var/www/html/Tinyboard/mod.php:1614 +#: ../../../../inc/mod/pages.php:1557 msgid "Report queue" msgstr "Kolejna zgłoszeń" #: /var/www/html/Tinyboard/mod.php:144 /var/www/html/Tinyboard/mod.php:1882 +#: ../../../../inc/mod/pages.php:664 msgid "Ban list" msgstr "Lista banów" #: /var/www/html/Tinyboard/mod.php:147 /var/www/html/Tinyboard/mod.php:1288 +#: ../../../../inc/mod/pages.php:1271 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -580,6 +622,7 @@ msgid "Change own password" msgstr "Zmień swoje hasło" #: /var/www/html/Tinyboard/mod.php:152 /var/www/html/Tinyboard/mod.php:477 +#: ../../../../inc/mod/pages.php:416 ../../../../inc/mod/pages.php:443 msgid "Moderation log" msgstr "Log moderacji" @@ -596,6 +639,7 @@ msgid "Show configuration" msgstr "Pokaż konfigurację" #: /var/www/html/Tinyboard/mod.php:165 /var/www/html/Tinyboard/mod.php:709 +#: ../../../../inc/mod/pages.php:1739 msgid "Manage themes" msgstr "Zarządzaj dodatkami" @@ -616,7 +660,7 @@ msgstr "" "kluczowych. Aby dopasować dokładne frazy użyj \"cudzysłowi\". Używaj " "gwiazdki (*) jako znak wieloznaczny." -#: /var/www/html/Tinyboard/mod.php:180 +#: /var/www/html/Tinyboard/mod.php:180 ../../../../inc/mod/pages.php:106 msgid "Could not find current version! (Check .installed)" msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" @@ -624,7 +668,7 @@ msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" msgid "Logout" msgstr "Wyloguj" -#: /var/www/html/Tinyboard/mod.php:245 +#: /var/www/html/Tinyboard/mod.php:245 ../../../../inc/mod/pages.php:147 msgid "Dashboard" msgstr "Tablica" @@ -648,11 +692,11 @@ msgstr "Board" msgid "Action" msgstr "Akcja" -#: /var/www/html/Tinyboard/mod.php:528 +#: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" -#: /var/www/html/Tinyboard/mod.php:530 +#: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -684,7 +728,8 @@ msgstr "Rekonfiguruj" msgid "Install" msgstr "Instaluj" -#: /var/www/html/Tinyboard/mod.php:693 +#: /var/www/html/Tinyboard/mod.php:693 ../../../../inc/mod/pages.php:1467 +#: ../../../../inc/mod/pages.php:1471 msgid "Rebuild" msgstr "Przebuduj" @@ -704,7 +749,7 @@ msgstr "Zawartość" msgid "Post to noticeboard" msgstr "Postuj na tablicy ogłoszeń" -#: /var/www/html/Tinyboard/mod.php:792 +#: /var/www/html/Tinyboard/mod.php:792 ../../../../inc/mod/pages.php:316 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -773,14 +818,85 @@ msgstr "Cache jest wyłączone." msgid "Configuration" msgstr "Konfiguracja" -#: /var/www/html/Tinyboard/mod.php:2174 +#: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." -#: /var/www/html/Tinyboard/mod.php:2678 +#: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." #: /var/www/html/Tinyboard/mod.php:2795 msgid "No board to move to; there is only one." msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." + +#: ../../../../inc/config.php:689 +msgid "Invalid security token! Please go back and try again." +msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." + +#: ../../../../inc/mod/pages.php:63 +msgid "Confirm action" +msgstr "Potwierdź akcję" + +#: ../../../../inc/mod/pages.php:222 +msgid "Edit board" +msgstr "Edytuj board" + +#: ../../../../inc/mod/pages.php:270 +msgid "New board" +msgstr "Nowy board" + +#: ../../../../inc/mod/pages.php:586 +msgid "IP" +msgstr "adres IP" + +#: ../../../../inc/mod/pages.php:596 ../../../../inc/mod/pages.php:985 +msgid "New ban" +msgstr "Nowy ban" + +#: ../../../../inc/mod/pages.php:919 +msgid "Impossible to move thread; there is only one board." +msgstr "Nie można przenieść wątku; istnieje tylko jeden board." + +#: ../../../../inc/mod/pages.php:923 +msgid "Move thread" +msgstr "Przenieś wątek" + +#: ../../../../inc/mod/pages.php:1209 ../../../../inc/mod/pages.php:1258 +msgid "Edit user" +msgstr "Edytuj użytkownika" + +#: ../../../../inc/mod/pages.php:1333 ../../../../inc/mod/pages.php:1405 +msgid "New PM for" +msgstr "Nowe PW dla" + +#: ../../../../inc/mod/pages.php:1337 +msgid "Private message" +msgstr "Prywatna wiadomość" + +#: ../../../../inc/mod/pages.php:1358 +msgid "PM inbox" +msgstr "Odebrane PW" + +#: ../../../../inc/mod/pages.php:1679 +msgid "Config editor" +msgstr "Edytor konfiguracji" + +#: ../../../../inc/mod/pages.php:1713 +msgid "Debug: Anti-spam" +msgstr "Debug: Antyspam" + +#: ../../../../inc/mod/pages.php:1801 +#, php-format +msgid "Installed theme: %s" +msgstr "Zainstalowano dodatek: %s" + +#: ../../../../inc/mod/pages.php:1811 +#, php-format +msgid "Configuring theme: %s" +msgstr "Konfigurowanie dodatku: %s" + +#: ../../../../inc/mod/pages.php:1839 +#, php-format +msgid "Rebuilt theme: %s" +msgstr "Przebudowano dodatek: %s" From 4266c412b55b5d5b4c2a76578561340ccf993b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Tue, 18 Dec 2012 04:58:53 +0100 Subject: [PATCH 101/289] Updated Polish translation (2) --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 13437 -> 13437 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index f1f40e8e210ecc7f8e3129089a569a5d70cdf3bf..592ca18d0fe7e35dc265dcf3d28b6322a15f021c 100644 GIT binary patch delta 19 bcmeyH@i$|`J{`8?jQsM%tj$MscCrHiW=;u8 delta 19 bcmeyH@i$|`J{`7#{LGxxqRmHicCrHiX5k50 diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 3d70a91b..d24cbd8e 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -437,7 +437,7 @@ msgstr "Temat" #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:112 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:117 msgid "Spoiler Image" -msgstr "Spoiler obrazek" +msgstr "Schowaj obrazek" #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:119 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:121 From 39cf9e7de560d0b09e1d13a040727eb031bbc0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Tue, 18 Dec 2012 06:42:20 +0100 Subject: [PATCH 102/289] Updated Polish translation (3) --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 13437 -> 13500 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 21 ++++++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 592ca18d0fe7e35dc265dcf3d28b6322a15f021c..4a0e0f221160a0e575b184a63e55f50ce5569416 100644 GIT binary patch delta 1748 zcmeyHu_tqb4qN>uMg|4}1qKFD1_p-1iVO@p85kIDDl#x=GcYhrR$^dKVPIg`uf)K> z%D}+z1WLbBVqjolU|{&5#K0iOz`*cTiGe|gfq_9pnSp_mfq_9?nSsHMfq}tL8DdU> zG6MrM0|UbxWd;U51_p)&$_xxV3=9nGl^N>62Jca3U|?flU^t}Az`)JGz;IHTfkB*s zf#Iq$1A{vQ1H)To1_ogU1_o0Vh=rai5Q{QYAmT+T5Chv(7#O5L4p(7d5M*FrSf|3k zV8y_|Z~#jGR$*Z9WME)0Q)OV#VqjosP_2i!e6=bAgERvJ!#-6826hGphFhu(4EziX z43AVHKL4c3z`(`8!0d;tU|?ckVA!t4z`()4z_1HSA6A3-@C=mCuFk+9 z$-uxMpbm*rEp>L$tg4G!qycrl6GSnd+nfP_Sw1|-O*X+V6iKm!tDD>N7wf*2SWj%YA2@G>wkh-*UBt7<|lG}VMS z$V-!fA%uZ}Aw?6SZl@*#g8&0VJ;QNLh)-{5LW1tQCL|=dwIB`<)Ph(n3+1b8K|;V- z3lb$ZT97Dk*MjH^(PCh5VPIg0(t>zsz7`||j%z_2bPHW?*25)Q0$Ytv1BLC$%B^UT8xMeh=ld=s*%5w+_TS zSsjQvO&y3w40IqNVx_~tAW_f2z!0JX@j)(BL6r`~XDv{=A8ODn9f(hs=|G}jrw+v8 zgHQ{uLG|B-ia*zZM8zK+NXYQ$LL4Nd3*pP@GBDKZFfcHv=rS;9FfcF#>M}5xGB7Yy z=`t`#FfcG|(1p14q%I^x9z*%RbRpSOL=O@oI(m@A+N!eS`DT@PaJCOwG$+jW&#e65nG3NJxA%fad?dPyqo$NL+ue7#NH}MXnLV$GpZ23}y@r3gdz4C%%U3^oi53>Sh{KJb;+9aps|h5;d`!UEjUn6wQgCIMK+=F@E>uIY2?K*J0|P_7 z2_*lo-E7J8TG-G)&r;7!Hzl=9*NiJDwIIK!MAx@CJu^kusWiPAt3=9knN(>CF z3=9lQq4a7c1_l-e28NAF3=DD%3=G?p7#M^Y7#OZ9F)(m4FfhDOVqmaiU|{&91Tn`@ znSp_sfq@}bnSp_ifq@}WnSp_afq|hwnV}wRaIG=}0~-SaL$fji12+Q$LzglGgE#{N z!!%_E26qMqhIPse48jZy4BwO?7ILXTEYehgh#RXw40KmvV2}biT!n!_kb!|AUxk6e zih+Tl5lZh-VPNoNU|{&J!oZ-#z`)?BS`Tq~jw%C#Gy?-ey($9(I|Bp5Y*hvZeg+1H z#i|gWZ&qbs;9_84*s03EpvJ(!a6}an0hX%#4~tp+jQ z2+FsrSA!Vjs0Ojf4NCi{L3|nnRamITz`(@7z)+#az`()4z)%gPTht&v?1l1As4*}| zGB7Y)RD(q6Yc+@m8PypWL>L$tMAR7=ycrl6G}R#?P+zLfz>v(qz_37_fkB;tfq_K> z5=S~35Fc4_(}5_k)`9rU6-o!_Kn#l3f%qg{2NDHUIuMJS zbRZ6y4%I&oD!xJo5_NlZAR%)WYR+XS|Go|bL%j|I1H)4t1_liV1_mKr1_o0G1_oUm;m^k$yQD~wE;d|&o%q`Y~=%1s< zz+lb5z_3{l60-0080x_V29G|Zpb^t&U@!qWK%ap@2~qC6XVF0m6!T@5Cz5&F6*#;2x?FNvjP-Y#10ACK^NH z{2Y|NW(@JcJ!432cx4Q6_-Cm2FDReQ1QKGrCgAMGAYlS2Z!}FHX+l!Z1Y(eh2?K*J z0|SGD2_*mLZMNijEzBR_=AXrL40zkLXW(Uqn~>yNW#X)#~~+E zFTW_=j>{)8FTFG|J=IEKGK*r7l&4>atGjEEwL(EoX;EU1t!qR;kZUl=n9T, YEAR. -# -#, fuzzy +# Polish Tinyboard Translation +# Copyright (C) 2011 Marcin Łabanowski +# Ten plik jest wydany na takiej samej licencji co paczka PACKAGE. +# Marcin Łabanowski (2011) msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" +"Project-Id-Version: 0.9.6-dev-6\n" +"Report-Msgid-Bugs-To: marcin@6irc.net\n" "POT-Creation-Date: 2012-12-18 04:43+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" +"Language-Team: POLISH \n" +"Language: Polish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2;\n" #: /var/www/html/Tinyboard/inc/functions.php:958 #: /var/www/html/Tinyboard/inc/functions.php:972 From 5ea2f02e7de1bdde17d0b8f0bc729a2c8e11767c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Tue, 18 Dec 2012 08:07:26 +0100 Subject: [PATCH 103/289] Fixed typo in Polish translation --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 13500 -> 13500 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 4a0e0f221160a0e575b184a63e55f50ce5569416..98f2ab5c05cbb3c3da101717c85ffd25cf98f1b0 100644 GIT binary patch delta 14 Vcmdm!xhHeOY8}Sx&1-Z7H~=)I1>pby delta 14 Vcmdm!xhHeOY8}SB&1-Z7H~=)a1>^t# diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index ea0469e9..374278df 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -604,7 +604,7 @@ msgstr "Aktualności" #: /var/www/html/Tinyboard/mod.php:141 /var/www/html/Tinyboard/mod.php:1614 #: ../../../../inc/mod/pages.php:1557 msgid "Report queue" -msgstr "Kolejna zgłoszeń" +msgstr "Kolejka zgłoszeń" #: /var/www/html/Tinyboard/mod.php:144 /var/www/html/Tinyboard/mod.php:1882 #: ../../../../inc/mod/pages.php:664 From dd01c8308defcb25e7e129724281906b8b6b3e08 Mon Sep 17 00:00:00 2001 From: 55ch Date: Sat, 15 Jun 2013 07:07:16 -0400 Subject: [PATCH 104/289] Brazilian Portuguese translation for Tinyboard --- inc/locale/pt_BR/LC_MESSAGES/tinyboard.mo | Bin 0 -> 12327 bytes inc/locale/pt_BR/LC_MESSAGES/tinyboard.po | 844 ++++++++++++++++++++++ 2 files changed, 844 insertions(+) create mode 100644 inc/locale/pt_BR/LC_MESSAGES/tinyboard.mo create mode 100644 inc/locale/pt_BR/LC_MESSAGES/tinyboard.po diff --git a/inc/locale/pt_BR/LC_MESSAGES/tinyboard.mo b/inc/locale/pt_BR/LC_MESSAGES/tinyboard.mo new file mode 100644 index 0000000000000000000000000000000000000000..3bb6778be52ae4702ed016b249c024d500b0f3f2 GIT binary patch literal 12327 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, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-21 11:29-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural==(n != 1);n" + +#: ../../inc/lib/gettext/examples/pigs_dropin.php:77 +msgid "" +"This is how the story goes.\n" +"\n" +msgstr "Era uma vez\n\n" + +#: ../../inc/functions.php:1046 ../../inc/functions.php:1060 +msgid "Previous" +msgstr "Anterior" + +#: ../../inc/functions.php:1065 ../../inc/functions.php:1074 +msgid "Next" +msgstr "Proximo" + +#: ../../inc/display.php:91 ../../inc/mod/pages.php:62 +msgid "Login" +msgstr "Login" + +#: ../../inc/config.php:687 +msgid "Lurk some more before posting." +msgstr "Lurke mais antes de postar." + +#: ../../inc/config.php:688 +msgid "You look like a bot." +msgstr "Você não parece humano." + +#: ../../inc/config.php:689 +msgid "Your browser sent an invalid or no HTTP referer." +msgstr "Seu browser enviou um referial HTTP inválido ou não enviou o referencial." + +#: ../../inc/config.php:690 +#, php-format +msgid "The %s field was too long." +msgstr "O campo %s é longo demais." + +#: ../../inc/config.php:691 +msgid "The body was too long." +msgstr "O corpo do texto é longo demais." + +#: ../../inc/config.php:692 +msgid "The body was too short or empty." +msgstr "O corpo do texto é pequeno demais ou inexistente." + +#: ../../inc/config.php:693 +msgid "You must upload an image." +msgstr "Você deve fazer upload de uma imagem." + +#: ../../inc/config.php:694 +msgid "The server failed to handle your upload." +msgstr "O servidor não conseguiu lidar com seu upload." + +#: ../../inc/config.php:695 +msgid "Unsupported image format." +msgstr "Tipo de imagem não aceito." + +#: ../../inc/config.php:696 +msgid "Invalid board!" +msgstr "Board inválida!" + +#: ../../inc/config.php:697 +msgid "Thread specified does not exist." +msgstr "O tópico especificado não existe.." + +#: ../../inc/config.php:698 +msgid "Thread locked. You may not reply at this time." +msgstr "Tópico trancado, você não pode postar." + +#: ../../inc/config.php:699 +msgid "You didn't make a post." +msgstr "Você não escreveu uma mensagem." + +#: ../../inc/config.php:700 +msgid "Flood detected; Post discarded." +msgstr "Flood detectado; Sua mensagem foi descartada." + +#: ../../inc/config.php:701 +msgid "Your request looks automated; Post discarded." +msgstr "Sua requisição parece automatizada; Mensagem descartada." + +#: ../../inc/config.php:702 +msgid "Unoriginal content!" +msgstr "Conteudo não original!" + +#: ../../inc/config.php:703 +#, php-format +msgid "Unoriginal content! You have been muted for %d seconds." +msgstr "Conteudo não original! Você está impedido de postar por %d segundos." + +#: ../../inc/config.php:704 +#, php-format +msgid "You are muted! Expires in %d seconds." +msgstr "Você está impedido de postar! Expira em %d segundos." + +#: ../../inc/config.php:705 +#, php-format +msgid "Your IP address is listed in %s." +msgstr "Seu IP está listado em %s." + +#: ../../inc/config.php:706 +msgid "Too many links; flood detected." +msgstr "Links demais; Flood detectado." + +#: ../../inc/config.php:707 +msgid "Too many cites; post discarded." +msgstr "Citações demais; Post descartado." + +#: ../../inc/config.php:708 +msgid "Too many cross-board links; post discarded." +msgstr "Links entre boards demais; Post descartado." + +#: ../../inc/config.php:709 +msgid "You didn't select anything to delete." +msgstr "Você não selecionou nada para deletar." + +#: ../../inc/config.php:710 +msgid "You didn't select anything to report." +msgstr "Você não selecionou nada para denunciar." + +#: ../../inc/config.php:711 +msgid "You can't report that many posts at once." +msgstr "Você não pode denunciar tantas mensagens ao mesmo tempo." + +#: ../../inc/config.php:712 +msgid "Wrong password…" +msgstr "Senha incorreta…" + +#: ../../inc/config.php:713 +msgid "Invalid image." +msgstr "Imagem inválida." + +#: ../../inc/config.php:714 +msgid "Unknown file extension." +msgstr "Extenção de arquivo desconhecida." + +#: ../../inc/config.php:715 +msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" +msgstr "Tamanho maximo de arquivos: %maxsz% bytes
O tamanho do seu arquivo: %filesz% bytes" + +#: ../../inc/config.php:716 +msgid "The file was too big." +msgstr "Seu arquivo é grande demais." + +#: ../../inc/config.php:717 +msgid "Invalid archive!" +msgstr "Arquivo inválido!" + +#: ../../inc/config.php:718 +#, php-format +msgid "That file already exists!" +msgstr "O arquivo já existe!" + +#: ../../inc/config.php:719 +#, php-format +msgid "That file already exists in this thread!" +msgstr "O arquivo já existe neste tópico!" + +#: ../../inc/config.php:720 +#, php-format +msgid "You'll have to wait another %s before deleting that." +msgstr "Você terá que esperar %s segundos antes de deletar isso." + +#: ../../inc/config.php:721 +msgid "MIME type detection XSS exploit (IE) detected; post discarded." +msgstr "Exploit XSS do tipo MIME (IE) detectado; mensagem descartada." + +#: ../../inc/config.php:722 +msgid "Couldn't make sense of the URL of the video you tried to embed." +msgstr "Não consegui processar a URL do video que você tentou integrar" + +#: ../../inc/config.php:723 +msgid "You seem to have mistyped the verification." +msgstr "Você errou o codigo de verificação." + +#: ../../inc/config.php:726 +msgid "Invalid username and/or password." +msgstr "Login e/ou senha inválido(s)." + +#: ../../inc/config.php:727 +msgid "You are not a mod…" +msgstr "Você não é mod…" + +#: ../../inc/config.php:728 +msgid "" +"Invalid username and/or password. Your user may have been deleted or changed." +msgstr "Login e/ou senha inválido(s). Seu login deve ter sido mudado ou removido." + +#: ../../inc/config.php:729 +msgid "Invalid/malformed cookies." +msgstr "Cookies inválidos ou mal formados." + +#: ../../inc/config.php:730 +msgid "Your browser didn't submit an input when it should have." +msgstr "Seu browser não enviou uma entrada quando ele deveria." + +#: ../../inc/config.php:731 +#, php-format +msgid "The %s field is required." +msgstr "O campo %s é necessário." + +#: ../../inc/config.php:732 +#, php-format +msgid "The %s field was invalid." +msgstr "O campo %s é inválido." + +#: ../../inc/config.php:733 +#, php-format +msgid "There is already a %s board." +msgstr "A board %s já existe." + +#: ../../inc/config.php:734 +msgid "You don't have permission to do that." +msgstr "Você não tem permissão para fazer isso." + +#: ../../inc/config.php:735 +msgid "That post doesn't exist…" +msgstr "Este post já existe…" + +#: ../../inc/config.php:736 +msgid "Page not found." +msgstr "Pagina não encontrada." + +#: ../../inc/config.php:737 +#, php-format +msgid "That mod already exists!" +msgstr "Este mod já existe!" + +#: ../../inc/config.php:738 +msgid "That theme doesn't exist!" +msgstr "Este tema não existe!" + +#: ../../inc/config.php:739 +msgid "Invalid security token! Please go back and try again." +msgstr "Token de segurança inválido! Retorne e tente de novo." + +#: ../../inc/mod/pages.php:66 +msgid "Confirm action" +msgstr "Confirmar ação" + +#: ../../inc/mod/pages.php:110 +msgid "Could not find current version! (Check .installed)" +msgstr "Não foi possivel encontrar a versão atual! (Cheque o .installed)" + +#: ../../inc/mod/pages.php:151 +msgid "Dashboard" +msgstr "Dashboard" + +#: ../../inc/mod/pages.php:228 +msgid "Edit board" +msgstr "Editar board" + +#: ../../inc/mod/pages.php:261 +msgid "Couldn't open board after creation." +msgstr "Não foi possivel abrir a board após a criação." + +#: ../../inc/mod/pages.php:276 +msgid "New board" +msgstr "Nova board" + +#: ../../inc/mod/pages.php:322 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:96 +msgid "Noticeboard" +msgstr "Quadro de noticias" + +#: ../../inc/mod/pages.php:382 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:166 +msgid "News" +msgstr "Noticias" + +#: ../../inc/mod/pages.php:422 ../../inc/mod/pages.php:449 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:255 +msgid "Moderation log" +msgstr "Log da moderação" + +#: ../../inc/mod/pages.php:592 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:247 +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:65 +msgid "IP" +msgstr "IP" + +#: ../../inc/mod/pages.php:602 ../../inc/mod/pages.php:993 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:377 +msgid "New ban" +msgstr "Nova expulsão" + +#: ../../inc/mod/pages.php:670 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:224 +msgid "Ban list" +msgstr "Lista de expulsões" + +#: ../../inc/mod/pages.php:765 +msgid "Target and source board are the same." +msgstr "Board alvo e fonte são as mesmas." + +#: ../../inc/mod/pages.php:927 +msgid "Impossible to move thread; there is only one board." +msgstr "Impossivel de mover o tópico; Só existe uma board." + +#: ../../inc/mod/pages.php:931 +msgid "Move thread" +msgstr "Mover tópico" + +#: ../../inc/mod/pages.php:1045 +msgid "Edit post" +msgstr "Editar mensagem" + +#: ../../inc/mod/pages.php:1271 ../../inc/mod/pages.php:1320 +msgid "Edit user" +msgstr "Editar usuário" + +#: ../../inc/mod/pages.php:1333 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 +msgid "Manage users" +msgstr "Administrar usuários" + +#: ../../inc/mod/pages.php:1395 ../../inc/mod/pages.php:1467 +msgid "New PM for" +msgstr "Nova MP para" + +#: ../../inc/mod/pages.php:1399 +msgid "Private message" +msgstr "Mensagem pessoal" + +#: ../../inc/mod/pages.php:1420 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 +msgid "PM inbox" +msgstr "Entrada de MP" + +#: ../../inc/mod/pages.php:1531 ../../inc/mod/pages.php:1535 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 +msgid "Rebuild" +msgstr "Reconstruir" + +#: ../../inc/mod/pages.php:1621 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 +msgid "Report queue" +msgstr "Fila de denuncias" + +#: ../../inc/mod/pages.php:1743 +msgid "Config editor" +msgstr "Editor de configurações" + +#: ../../inc/mod/pages.php:1753 +msgid "Themes directory doesn't exist!" +msgstr "Diretório de temas não existe!" + +#: ../../inc/mod/pages.php:1755 +msgid "Cannot open themes directory; check permissions." +msgstr "Não é possivel abrir diretorio de temas; reveja suas permissões." + +#: ../../inc/mod/pages.php:1769 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 +msgid "Manage themes" +msgstr "Administrar temas" + +#: ../../inc/mod/pages.php:1831 +#, php-format +msgid "Installed theme: %s" +msgstr "Tema instalado: %s" + +#: ../../inc/mod/pages.php:1841 +#, php-format +msgid "Configuring theme: %s" +msgstr "Configurando tema: %s" + +#: ../../inc/mod/pages.php:1869 +#, php-format +msgid "Rebuilt theme: %s" +msgstr "Reconstruir tema: %s" + +#: ../../inc/mod/pages.php:1908 +msgid "Debug: Anti-spam" +msgstr "Debug: Anti-spam" + +#: ../../inc/mod/pages.php:1932 +msgid "Debug: Recent posts" +msgstr "Debug: Mensagens recentes" + +#: ../../inc/mod/pages.php:1956 +msgid "Debug: SQL" +msgstr "" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:19 +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:29 +msgid "Boards" +msgstr "Boards" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:57 +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:183 +msgid "edit" +msgstr "editar" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:74 +msgid "Create new board" +msgstr "Criar nova board" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:84 +msgid "Messages" +msgstr "Mensagens" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:120 +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:98 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:125 +msgid "no subject" +msgstr "sem assunto" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:161 +msgid "View all noticeboard entries" +msgstr "Ver todas as noticias do quadro de noticias" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:192 +msgid "Administration" +msgstr "Administração" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:239 +msgid "Change password" +msgstr "Mudar senha" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:271 +msgid "Configuration" +msgstr "Configuração" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:282 +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:293 +msgid "Search" +msgstr "Procurar" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:289 +msgid "Phrase:" +msgstr "Frase:" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:297 +msgid "" +"(Search is case-insensitive, and based on keywords. To match exact phrases, " +"use \"quotes\". Use an asterisk (*) for wildcard.)" +msgstr "" +"(A procura não diferencia maiúsculas de minusculas, e baseia-se em palavras chave. para procurar por frases exatas, " +"use \"quotes\". Utilize um asterisco (*) como coringa.)" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:309 +msgid "Debug" +msgstr "Debug" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:313 +msgid "Anti-spam" +msgstr "Anti-spam" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:316 +msgid "Recent posts" +msgstr "Mensagens recentes" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:322 +msgid "SQL" +msgstr "SQL" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:360 +msgid "User account" +msgstr "Conta de usuário" + +#: ../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:365 +msgid "Logout" +msgstr "Sair" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:21 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:21 +msgid "New post" +msgstr "Nova mensagem" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:27 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:31 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:36 +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:27 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:55 +msgid "Name" +msgstr "Nome" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:36 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:63 +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:53 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:98 +msgid "Subject" +msgstr "Assunto" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:42 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:69 +msgid "Body" +msgstr "Mensagem" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:49 +msgid "Post to noticeboard" +msgstr "Postar no quadro de notícias" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:73 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:100 +msgid "delete" +msgstr "deletar" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:106 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:133 +msgid "by" +msgstr "por" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:118 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:112 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:344 +msgid "deleted?" +msgstr "deletado?" + +#: ../../templates/cache/26/6f/05ca0da8ac09e2c2216cba2b6f95.php:125 +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:136 +msgid "at" +msgstr "em" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:74 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:169 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:331 +msgid "Staff" +msgstr "Equipe" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:77 +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:179 +msgid "Note" +msgstr "Nota" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:80 +msgid "Date" +msgstr "Data" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:86 +msgid "Actions" +msgstr "Ações" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:142 +msgid "remove" +msgstr "remover" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:189 +msgid "New note" +msgstr "Nova nota" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:226 +msgid "Status" +msgstr "Situação" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:233 +msgid "Expired" +msgstr "Expirado" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:238 +msgid "Active" +msgstr "Ativo" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:256 +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:32 +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:30 +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:90 +msgid "Reason" +msgstr "Razão" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:269 +msgid "no reason" +msgstr "sem razão especificada" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:278 +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:20 +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:142 +msgid "Board" +msgstr "Board" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:291 +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:150 +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:83 +msgid "all boards" +msgstr "todas as boards" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:300 +msgid "Set" +msgstr "Configurar" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:309 +msgid "Expires" +msgstr "Expira em" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:322 +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:137 +msgid "never" +msgstr "nunca" + +#: ../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:357 +msgid "Remove ban" +msgstr "Remover expulsão" + +#: ../../templates/cache/72/55/0d64283f30702de83ecfcb71f86a.php:25 +msgid "There are no reports." +msgstr "Não há denúncias no momento." + +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:19 +msgid "Delete Post" +msgstr "Deletar Mensagem" + +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:22 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:218 +msgid "File" +msgstr "Arquivo" + +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:23 +#: ../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:41 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:310 +msgid "Password" +msgstr "Senha" + +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:27 +msgid "Delete" +msgstr "Deletar" + +#: ../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:36 +msgid "Report" +msgstr "Denunciar" + +#: ../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:28 +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:23 +msgid "Username" +msgstr "Usuário" + +#: ../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:52 +msgid "Continue" +msgstr "Prosseguir" + +#: ../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:94 +#: ../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:175 +#: ../../templates/cache/62/8c/21348d46377c3e1b3f8c476ba376.php:63 +msgid "Return to dashboard" +msgstr "Voltar à dashboard" + +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:36 +msgid "Report date" +msgstr "Data da denúncia" + +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:45 +msgid "Reported by" +msgstr "Denunciado por" + +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:63 +msgid "Discard abuse report" +msgstr "Descartar denúncia desnecessária" + +#: ../../templates/cache/9c/7b/891291bc84f8844c30cefdb949cf.php:80 +msgid "Discard all abuse reports by this IP address" +msgstr "Descartar todas denúncias desnecessárias deste IP" + +#: ../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:183 +msgid "Posting mode: Reply" +msgstr "Modo de postagem: Resposta" + +#: ../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:186 +#: ../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:232 +msgid "Return" +msgstr "Voltar" + +#: ../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:76 +msgid "Post news entry" +msgstr "Postar nova notícia" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:66 +msgid "(or subnet)" +msgstr "(ou subnet)" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:80 +msgid "hidden" +msgstr "oculto" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:107 +msgid "Message" +msgstr "Mensagem" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:117 +msgid "public; attached to post" +msgstr "público; anexado à mensagem" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:133 +msgid "Length" +msgstr "Tamanho" + +#: ../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:192 +msgid "New Ban" +msgstr "Nova Expulsão" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:20 +msgid "ID" +msgstr "ID" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:26 +msgid "Type" +msgstr "Tipo" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:35 +msgid "Last action" +msgstr "Ultima ação" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:61 +msgid "Janitor" +msgstr "Faxineiro" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:64 +msgid "Mod" +msgstr "Moderador" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:67 +msgid "Admin" +msgstr "Administrador" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:78 +msgid "none" +msgstr "nenhum" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:153 +msgid "Promote" +msgstr "Promover" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:163 +msgid "Demote" +msgstr "Rebaixar" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:173 +msgid "log" +msgstr "registro" + +#: ../../templates/cache/c5/a7/fac83da087ee6e24edaf09e01122.php:193 +msgid "PM" +msgstr "MP" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:105 +msgid "File:" +msgstr "Arquivo:" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:117 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:129 +msgid "Spoiler Image" +msgstr "Imagem Spoiler" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:463 +msgid "Reply" +msgstr "Responder" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:490 +msgid "1 post" +msgid_plural "%count% posts" +msgstr[0] "1 mensagem" +msgstr[1] "%count% mensagens" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:496 +msgid "and" +msgstr "e" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:507 +msgid "1 image reply" +msgid_plural "%count% image replies" +msgstr[0] "1 resposta com imagem" +msgstr[1] "%count% respostas com imagem" + +#: ../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:512 +msgid "omitted. Click reply to view." +msgstr "omitidas. Clique em responder para visualizar." + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:40 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:76 +msgid "Email" +msgstr "E-mail" + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:62 +msgid "Update" +msgstr "Atualizar" + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:69 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:138 +msgid "Comment" +msgstr "Comentar" + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:89 +msgid "Currently editing raw HTML." +msgstr "Editando em HTML puro." + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:96 +msgid "Edit markup instead?" +msgstr "Editar markup em vez disso?" + +#: ../../templates/cache/39/42/cbc36382096edfa72a8bc26e4514.php:105 +msgid "Edit raw HTML instead?" +msgstr "Editar em HTML puro em vez disso?" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:111 +msgid "Submit" +msgstr "Enviar" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:159 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:185 +msgid "Verification" +msgstr "Verification" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:236 +msgid "Embed" +msgstr "Inserir" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:259 +msgid "Flags" +msgstr "Sinalizações" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:268 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:271 +msgid "Sticky" +msgstr "Fixar" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:280 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:283 +msgid "Lock" +msgstr "Trancar" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:292 +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:295 +msgid "Raw HTML" +msgstr "HTML Puro" + +#: ../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:319 +msgid "(For file deletion.)" +msgstr "(Para excluir arquivos)" From 0ffa0b3adfc5c99dec57e7f2416337a0fc155132 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:59:36 -0400 Subject: [PATCH 105/289] Update Polish translation; javascript l10n --- inc/locale/pl_PL/LC_MESSAGES/javascript.js | 1 + inc/locale/pl_PL/LC_MESSAGES/javascript.po | 121 ++++++ inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 13500 -> 14100 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 456 +++++++++++++++++++-- 4 files changed, 546 insertions(+), 32 deletions(-) create mode 100644 inc/locale/pl_PL/LC_MESSAGES/javascript.js create mode 100644 inc/locale/pl_PL/LC_MESSAGES/javascript.po diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.js b/inc/locale/pl_PL/LC_MESSAGES/javascript.js new file mode 100644 index 00000000..e1df81c7 --- /dev/null +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.js @@ -0,0 +1 @@ +l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144 to","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie"}; \ No newline at end of file diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po new file mode 100644 index 00000000..2b4fa223 --- /dev/null +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -0,0 +1,121 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-03 01:52-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../../js/quick-reply.js:20 +msgid "Submit" +msgstr "Wyślij" + +#: ../../../../js/quick-reply.js:30 +msgid "Quick reply" +msgstr "Szybka odpowiedź" + +#: ../../../../js/quick-reply.js:32 +msgid "Posting mode: Replying to >>{0}" +msgstr "Tryb postowania: Odpowiedź na >>{0}" + +#: ../../../../js/quick-reply.js:32 +msgid "Return" +msgstr "Powrót" + +#: ../../../../js/expand.js:20 +msgid "Click reply to view." +msgstr "Kliknij Odpowiedź aby zobaczyć." + +#: ../../../../js/expand.js:20 +msgid "Click to expand" +msgstr "Kliknij aby rozwinąć" + +#: ../../../../js/expand.js:41 +msgid "Hide expanded replies" +msgstr "Schowaj rozwinięte odpowiedzi" + +#: ../../../../js/local-time.js:40 +msgid "Mon" +msgstr "pon" + +#: ../../../../js/local-time.js:40 +msgid "Tue" +msgstr "wto" + +#: ../../../../js/local-time.js:40 +msgid "Wed" +msgstr "śro" + +#: ../../../../js/local-time.js:40 +msgid "Thu" +msgstr "czw" + +#: ../../../../js/local-time.js:40 +msgid "Fri" +msgstr "pią" + +#: ../../../../js/local-time.js:40 +msgid "Sat" +msgstr "sob" + +#: ../../../../js/local-time.js:40 +msgid "Sun" +msgstr "nie" + +#: ../../../../js/toggle-locked-threads.js:39 +#: ../../../../js/toggle-locked-threads.js:54 +msgid "Show locked threads" +msgstr "Pokaż zablokowane tematy" + +#: ../../../../js/toggle-locked-threads.js:39 +#: ../../../../js/toggle-locked-threads.js:54 +msgid "Hide locked threads" +msgstr "Schowaj zablokowane tematy" + +#: ../../../../js/forced-anon.js:59 ../../../../js/forced-anon.js:65 +#: ../../../../js/forced-anon.js:69 +msgid "Forced anonymity" +msgstr "Wymuszona anonimowość" + +#: ../../../../js/forced-anon.js:59 ../../../../js/forced-anon.js:65 +msgid "enabled" +msgstr "włączona" + +#: ../../../../js/forced-anon.js:59 ../../../../js/forced-anon.js:69 +msgid "disabled" +msgstr "wyłączona" + +#: ../../../../js/quick-post-controls.js:27 +msgid "Password" +msgstr "Hasło" + +#: ../../../../js/quick-post-controls.js:29 +msgid "Delete file only" +msgstr "Usuń tylko plik" + +#: ../../../../js/quick-post-controls.js:30 +msgid "File" +msgstr "Plik" + +#: ../../../../js/quick-post-controls.js:31 +msgid "Delete" +msgstr "Usuń to" + +#: ../../../../js/quick-post-controls.js:35 +msgid "Reason" +msgstr "Powód" + +#: ../../../../js/quick-post-controls.js:37 +msgid "Report" +msgstr "Zgłoszenie" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 98f2ab5c05cbb3c3da101717c85ffd25cf98f1b0..b23e55a827144eac782f6a378efd2f1abf66094c 100644 GIT binary patch delta 4996 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 delta 4494 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 py@H{Fm4eacpGrn7n|;*V*eBcTvu)$p`=d diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 374278df..edbb5212 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -1,31 +1,36 @@ -# Polish Tinyboard Translation -# Copyright (C) 2011 Marcin Łabanowski -# Ten plik jest wydany na takiej samej licencji co paczka PACKAGE. -# Marcin Łabanowski (2011) +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy msgid "" msgstr "" -"Project-Id-Version: 0.9.6-dev-6\n" -"Report-Msgid-Bugs-To: marcin@6irc.net\n" -"POT-Creation-Date: 2012-12-18 04:43+0100\n" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-03 01:52-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" -"Language-Team: POLISH \n" -"Language: Polish\n" +"Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +#. There is no previous page. #: /var/www/html/Tinyboard/inc/functions.php:958 #: /var/www/html/Tinyboard/inc/functions.php:972 #: ../../../../inc/functions.php:1041 ../../../../inc/functions.php:1055 +#: ../../../../inc/functions.php:1039 ../../../../inc/functions.php:1053 msgid "Previous" msgstr "Wstecz" +#. There is no next page. #: /var/www/html/Tinyboard/inc/functions.php:977 #: /var/www/html/Tinyboard/inc/functions.php:986 #: ../../../../inc/functions.php:1060 ../../../../inc/functions.php:1069 +#: ../../../../inc/functions.php:1058 ../../../../inc/functions.php:1067 msgid "Next" msgstr "Dalej" @@ -62,171 +67,216 @@ msgstr "Odpowiedz" msgid "Quick Reply" msgstr "Szybka odpowiedź" +#. +#. * ==================== +#. * Error messages +#. * ==================== +#. +#. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 +#: ../../../../inc/config.php:692 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 +#: ../../../../inc/config.php:693 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 +#: ../../../../inc/config.php:694 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " "odsyłaczu w nagłówku" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 +#: ../../../../inc/config.php:695 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 +#: ../../../../inc/config.php:696 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 +#: ../../../../inc/config.php:697 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 +#: ../../../../inc/config.php:698 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 +#: ../../../../inc/config.php:699 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 +#: ../../../../inc/config.php:700 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 +#: ../../../../inc/config.php:701 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 +#: ../../../../inc/config.php:702 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 +#: ../../../../inc/config.php:703 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 +#: ../../../../inc/config.php:706 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 +#: ../../../../inc/config.php:707 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 +#: ../../../../inc/config.php:708 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 +#: ../../../../inc/config.php:709 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 +#: ../../../../inc/config.php:710 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 +#: ../../../../inc/config.php:711 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 +#: ../../../../inc/config.php:712 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 +#: ../../../../inc/config.php:713 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 +#: ../../../../inc/config.php:714 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 +#: ../../../../inc/config.php:715 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 +#: ../../../../inc/config.php:716 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 +#: ../../../../inc/config.php:717 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 +#: ../../../../inc/config.php:718 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 +#: ../../../../inc/config.php:719 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 +#: ../../../../inc/config.php:720 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 +#: ../../../../inc/config.php:721 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 +#: ../../../../inc/config.php:722 msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
Rozmiar twojego pliku: %filesz% " "bajtów" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 +#: ../../../../inc/config.php:723 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 +#: ../../../../inc/config.php:724 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 +#: ../../../../inc/config.php:725 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 +#: ../../../../inc/config.php:727 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 +#: ../../../../inc/config.php:728 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " "odrzucony" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 +#: ../../../../inc/config.php:729 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 +#: ../../../../inc/config.php:730 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 +#: ../../../../inc/config.php:734 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 +#: ../../../../inc/config.php:735 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 +#: ../../../../inc/config.php:736 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -234,46 +284,56 @@ msgstr "" "albo zmienione." #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 +#: ../../../../inc/config.php:737 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 +#: ../../../../inc/config.php:738 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 +#: ../../../../inc/config.php:739 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 +#: ../../../../inc/config.php:740 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 +#: ../../../../inc/config.php:741 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 +#: ../../../../inc/config.php:742 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 +#: ../../../../inc/config.php:743 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 +#: ../../../../inc/config.php:744 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 +#: ../../../../inc/config.php:745 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 +#: ../../../../inc/config.php:746 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -331,7 +391,7 @@ msgid "Go back" msgstr "Wróć" #: /var/www/html/Tinyboard/inc/display.php:97 ../../../../inc/display.php:91 -#: ../../../../inc/mod/pages.php:59 +#: ../../../../inc/mod/pages.php:59 ../../../../inc/mod/pages.php:62 msgid "Login" msgstr "Logowanie" @@ -343,10 +403,12 @@ msgstr "" "Post za długi. Kliknij tutaj aby zobaczyć pełnego posta." +#. line 5 #: /var/www/html/Tinyboard/inc/display.php:272 #: /var/www/html/Tinyboard/inc/display.php:365 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:27 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:27 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:27 msgid "Delete" msgstr "Usuń" @@ -382,6 +444,7 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:292 #: /var/www/html/Tinyboard/inc/display.php:408 +#: ../../../../inc/mod/pages.php:1080 msgid "Edit post" msgstr "Edytuj post" @@ -413,21 +476,27 @@ msgstr "Zablokuj wątek" msgid "Move thread to another board" msgstr "Przenieś wątek na inny board" +#. line 11 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:48 #: /var/www/html/Tinyboard/mod.php:667 /var/www/html/Tinyboard/mod.php:750 #: /var/www/html/Tinyboard/mod.php:833 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:55 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:55 msgid "Name" msgstr "Nazwa" +#. line 21 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:62 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:76 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:76 msgid "Email" msgstr "E-mail" +#. line 34 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:96 #: /var/www/html/Tinyboard/mod.php:753 /var/www/html/Tinyboard/mod.php:839 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:95 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:116 msgid "Subject" msgstr "Temat" @@ -435,71 +504,327 @@ msgstr "Temat" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:119 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:112 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:117 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:119 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:100 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:133 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:172 msgid "Spoiler Image" msgstr "Schowaj obrazek" +#. line 45 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:119 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:121 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:145 msgid "Comment" msgstr "Komentarz" +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:191 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:217 msgid "Verification" msgstr "Weryfikacja" +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:22 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:22 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:250 msgid "File" msgstr "Plik" +#. line 97 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:163 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:183 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:268 msgid "Embed" msgstr "Osadź" +#. line 109 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:179 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:206 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:291 msgid "Flags" msgstr "Flagi" +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:218 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:300 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:303 msgid "Sticky" msgstr "Przyklejony" +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:230 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:312 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:315 msgid "Lock" msgstr "Zablokowany" +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:242 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:324 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:327 msgid "Raw HTML" msgstr "Czysty HTML" +#. line 129 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:230 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:23 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:257 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:23 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:23 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:342 msgid "Password" msgstr "Hasło" +#. line 134 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:236 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:266 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:351 msgid "(For file deletion.)" msgstr "(do usuwania postów)" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:107 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:105 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:107 msgid "File:" msgstr "Plik:" @@ -518,11 +843,13 @@ msgstr "Odśwież" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:478 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:415 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:461 msgid "Reply" msgstr "Odpowiedź" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:511 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:442 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:488 msgid "1 post" msgid_plural "%count% posts" msgstr[0] "1 post" @@ -531,11 +858,13 @@ msgstr[2] "%count% postów" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:517 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:448 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:494 msgid "and" msgstr "oraz" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:528 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:459 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 msgid "1 image reply" msgid_plural "%count% image replies" msgstr[0] "1 obrazek" @@ -544,6 +873,7 @@ msgstr[2] "%count% obrazków" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:533 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:464 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:510 msgid "omitted. Click reply to view." msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." @@ -552,11 +882,16 @@ msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:159 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:169 #: ../../../../templates/cache/7a/d3/9236b821893e6bc57b16919988fd.php:169 +#: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:121 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:98 +#: ../../../../templates/cache/62/8c/21348d46377c3e1b3f8c476ba376.php:62 msgid "Return to dashboard" msgstr "Powróć na tablicę" +#. line 27 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:165 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:177 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:106 msgid "Posting mode: Reply" msgstr "Tryb postowania: Odpowiedź" @@ -564,22 +899,30 @@ msgstr "Tryb postowania: Odpowiedź" #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:210 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:180 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:222 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:109 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:155 msgid "Return" msgstr "Powrót" +#. line 2 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:19 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:19 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:19 msgid "Delete Post" msgstr "Usuń post" +#. line 8 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:32 msgid "Reason" msgstr "Powód" +#. line 10 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:36 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:36 +#: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:36 msgid "Report" msgstr "Zgłoszenie" @@ -597,22 +940,22 @@ msgid "PM Inbox" msgstr "Wiadomości prywatne" #: /var/www/html/Tinyboard/mod.php:136 /var/www/html/Tinyboard/mod.php:874 -#: ../../../../inc/mod/pages.php:376 +#: ../../../../inc/mod/pages.php:376 ../../../../inc/mod/pages.php:393 msgid "News" msgstr "Aktualności" #: /var/www/html/Tinyboard/mod.php:141 /var/www/html/Tinyboard/mod.php:1614 -#: ../../../../inc/mod/pages.php:1557 +#: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 msgid "Report queue" msgstr "Kolejka zgłoszeń" #: /var/www/html/Tinyboard/mod.php:144 /var/www/html/Tinyboard/mod.php:1882 -#: ../../../../inc/mod/pages.php:664 +#: ../../../../inc/mod/pages.php:664 ../../../../inc/mod/pages.php:705 msgid "Ban list" msgstr "Lista banów" #: /var/www/html/Tinyboard/mod.php:147 /var/www/html/Tinyboard/mod.php:1288 -#: ../../../../inc/mod/pages.php:1271 +#: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -622,6 +965,7 @@ msgstr "Zmień swoje hasło" #: /var/www/html/Tinyboard/mod.php:152 /var/www/html/Tinyboard/mod.php:477 #: ../../../../inc/mod/pages.php:416 ../../../../inc/mod/pages.php:443 +#: ../../../../inc/mod/pages.php:433 ../../../../inc/mod/pages.php:460 msgid "Moderation log" msgstr "Log moderacji" @@ -638,7 +982,7 @@ msgid "Show configuration" msgstr "Pokaż konfigurację" #: /var/www/html/Tinyboard/mod.php:165 /var/www/html/Tinyboard/mod.php:709 -#: ../../../../inc/mod/pages.php:1739 +#: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 msgid "Manage themes" msgstr "Zarządzaj dodatkami" @@ -660,6 +1004,7 @@ msgstr "" "gwiazdki (*) jako znak wieloznaczny." #: /var/www/html/Tinyboard/mod.php:180 ../../../../inc/mod/pages.php:106 +#: ../../../../inc/mod/pages.php:110 msgid "Could not find current version! (Check .installed)" msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" @@ -668,6 +1013,7 @@ msgid "Logout" msgstr "Wyloguj" #: /var/www/html/Tinyboard/mod.php:245 ../../../../inc/mod/pages.php:147 +#: ../../../../inc/mod/pages.php:162 msgid "Dashboard" msgstr "Tablica" @@ -692,10 +1038,12 @@ msgid "Action" msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 +#: ../../../../inc/mod/pages.php:1789 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 +#: ../../../../inc/mod/pages.php:1791 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -728,7 +1076,8 @@ msgid "Install" msgstr "Instaluj" #: /var/www/html/Tinyboard/mod.php:693 ../../../../inc/mod/pages.php:1467 -#: ../../../../inc/mod/pages.php:1471 +#: ../../../../inc/mod/pages.php:1471 ../../../../inc/mod/pages.php:1567 +#: ../../../../inc/mod/pages.php:1571 msgid "Rebuild" msgstr "Przebuduj" @@ -749,6 +1098,7 @@ msgid "Post to noticeboard" msgstr "Postuj na tablicy ogłoszeń" #: /var/www/html/Tinyboard/mod.php:792 ../../../../inc/mod/pages.php:316 +#: ../../../../inc/mod/pages.php:333 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -818,10 +1168,12 @@ msgid "Configuration" msgstr "Konfiguracja" #: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 +#: ../../../../inc/mod/pages.php:272 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." #: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 +#: ../../../../inc/mod/pages.php:800 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." @@ -829,73 +1181,113 @@ msgstr "Docelowy i źródłowy board są takie same." msgid "No board to move to; there is only one." msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." -#: ../../../../inc/config.php:689 +#: ../../../../inc/config.php:689 ../../../../inc/config.php:747 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." -#: ../../../../inc/mod/pages.php:63 +#: ../../../../inc/mod/pages.php:63 ../../../../inc/mod/pages.php:66 msgid "Confirm action" msgstr "Potwierdź akcję" -#: ../../../../inc/mod/pages.php:222 +#: ../../../../inc/mod/pages.php:222 ../../../../inc/mod/pages.php:239 msgid "Edit board" msgstr "Edytuj board" -#: ../../../../inc/mod/pages.php:270 +#: ../../../../inc/mod/pages.php:270 ../../../../inc/mod/pages.php:287 msgid "New board" msgstr "Nowy board" -#: ../../../../inc/mod/pages.php:586 +#: ../../../../inc/mod/pages.php:586 ../../../../inc/mod/pages.php:612 msgid "IP" msgstr "adres IP" #: ../../../../inc/mod/pages.php:596 ../../../../inc/mod/pages.php:985 +#: ../../../../inc/mod/pages.php:622 ../../../../inc/mod/pages.php:1028 msgid "New ban" msgstr "Nowy ban" -#: ../../../../inc/mod/pages.php:919 +#: ../../../../inc/mod/pages.php:919 ../../../../inc/mod/pages.php:962 msgid "Impossible to move thread; there is only one board." msgstr "Nie można przenieść wątku; istnieje tylko jeden board." -#: ../../../../inc/mod/pages.php:923 +#: ../../../../inc/mod/pages.php:923 ../../../../inc/mod/pages.php:966 msgid "Move thread" msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1209 ../../../../inc/mod/pages.php:1258 +#: ../../../../inc/mod/pages.php:1307 ../../../../inc/mod/pages.php:1356 msgid "Edit user" msgstr "Edytuj użytkownika" +#. deleted? #: ../../../../inc/mod/pages.php:1333 ../../../../inc/mod/pages.php:1405 +#: ../../../../inc/mod/pages.php:1431 ../../../../inc/mod/pages.php:1503 msgid "New PM for" msgstr "Nowe PW dla" -#: ../../../../inc/mod/pages.php:1337 +#: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 msgid "Private message" msgstr "Prywatna wiadomość" -#: ../../../../inc/mod/pages.php:1358 +#: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 msgid "PM inbox" msgstr "Odebrane PW" -#: ../../../../inc/mod/pages.php:1679 +#: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 msgid "Config editor" msgstr "Edytor konfiguracji" -#: ../../../../inc/mod/pages.php:1713 +#: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" -#: ../../../../inc/mod/pages.php:1801 +#: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" -#: ../../../../inc/mod/pages.php:1811 +#: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" -#: ../../../../inc/mod/pages.php:1839 +#: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" + +#: ../../../../inc/lib/gettext/examples/pigs_dropin.php:77 +msgid "" +"This is how the story goes.\n" +"\n" +msgstr "" + +#: ../../../../inc/config.php:704 +msgid "Thread has reached its maximum reply limit." +msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." + +#: ../../../../inc/config.php:705 +msgid "Thread has reached its maximum image limit." +msgstr "Ten temat osiągnął swój maksymalny limit obrazków." + +#: ../../../../inc/config.php:726 +#, php-format +msgid "That file already exists in this thread!" +msgstr "Ten plik już istnieje w tym temacie!" + +#. Moderator errors +#: ../../../../inc/config.php:733 +#, php-format +msgid "" +"You are only allowed to unban %s users at a time. You tried to unban %u " +"users." +msgstr "" +"Możesz odbanować tylko %s użytkowników na raz. Próbowałeś odbanować %u users." + +#: ../../../../inc/mod/pages.php:1969 +msgid "Debug: Recent posts" +msgstr "Debug: Ostatnie posty" + +#: ../../../../inc/mod/pages.php:1993 +msgid "Debug: SQL" +msgstr "Debug: SQL" From ba270168134b50b955cd99925c899ee8c4096677 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 18 Jul 2013 16:34:22 -0400 Subject: [PATCH 106/289] locale: update polish translation --- inc/locale/pl_PL/LC_MESSAGES/javascript.js | 2 +- inc/locale/pl_PL/LC_MESSAGES/javascript.po | 12 +- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 14100 -> 14191 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 190 ++++++++++++++------- 4 files changed, 134 insertions(+), 70 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.js b/inc/locale/pl_PL/LC_MESSAGES/javascript.js index e1df81c7..44857b98 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.js +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.js @@ -1 +1 @@ -l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144 to","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie"}; \ No newline at end of file +l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie"}; \ No newline at end of file diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po index 2b4fa223..3c16c8d7 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.po +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-03 01:52-0400\n" +"POT-Creation-Date: 2013-07-18 16:31-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,19 +17,19 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../../js/quick-reply.js:20 +#: ../../../../js/quick-reply.js:20 ../../../../js/quick-reply.js:21 msgid "Submit" msgstr "Wyślij" -#: ../../../../js/quick-reply.js:30 +#: ../../../../js/quick-reply.js:30 ../../../../js/quick-reply.js:31 msgid "Quick reply" msgstr "Szybka odpowiedź" -#: ../../../../js/quick-reply.js:32 +#: ../../../../js/quick-reply.js:32 ../../../../js/quick-reply.js:33 msgid "Posting mode: Replying to >>{0}" msgstr "Tryb postowania: Odpowiedź na >>{0}" -#: ../../../../js/quick-reply.js:32 +#: ../../../../js/quick-reply.js:32 ../../../../js/quick-reply.js:33 msgid "Return" msgstr "Powrót" @@ -110,7 +110,7 @@ msgstr "Plik" #: ../../../../js/quick-post-controls.js:31 msgid "Delete" -msgstr "Usuń to" +msgstr "Usuń" #: ../../../../js/quick-post-controls.js:35 msgid "Reason" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index b23e55a827144eac782f6a378efd2f1abf66094c..ac57873e8d6086164123d2fe16def54f5eae177f 100644 GIT binary patch delta 4431 zcmbP|_dc)wo)F7a1_lO(lMD*YU|=W~gosZUWMB|yU|?7y$iTqHz`$@skb!}nfq~()AOiz40|UclK?Vj% z1_p-ff(#6z3=9k(1sNDP85kJYg%}uY85rsr1cewFR2di;{DmMIN`)90Kz3IOF)(m2 zFfgKPcEgc%r&7#J7=g&7$185kH^gc%s@85kJ0 z2t$1OMVNs>fPsNQLWF^VpMilvQv~7zOA&~;vk1iE5D^9jE(QjM3=xP!i$x#~sS;se z5CeGx%AX5Ww-RJdJ;)*ugMoozp9sXKC!q8>D18NL;4Kk|j~67V9CJ15G=*OpvAzz&@08jV93D0utN%xCSFNF@;$3GgqDZWmeLUUU}#38!!5QVN#IvYw)l!t`Gc6msecq|Wb*bk_vU(A#v^orG24v2$YUi zg!nW`5t7}q6(MP;Oc9c1s-WTxijbi0hU#0X$iPs{$iT2c5fb7m$_(`kI~f=ltdt=> z`l8Ihpu)hwpr8UNl3i6G23A1nIu%Gzx2Ql0l1>#!qFtc^arkZ(NWpSc1!5kHD#T$1 zs*v)-L=_S>&Z-b|161o7z_nJGDkS^GszQQ3QU&Q5BK~PO3sIysHYa=nqt! zO$}n8lo}*etE)lc*h!6n!HR)_Ap}bIt1&QmGB7ZlQiJ3c5p{^e?d#PU7^E2(7=qLx zQIMw&DHzJsAwkrp4hiBp>JS$%hw|5|Gcc%uvYR?2MDD9Y9P&gR;*pQ)5QqO&hj>s> z142tcX?YEZef4Tk0X+?fL8clIi>#oug9gOsZcufp8jwmQM+1@u@}YEv2E@mWQ2rhb zNTNKd0rALv4Tz7wYCsY#hb9AqH>m!X)r15|rX~YJGANa5LW<%anvghC(1Q3#Ukeg4 z)>@D#@YaI(AXEzyg0Wf*3_%PG43%1t?0W{P{+1TR!dF@l2mRM#UE8xjS7p!zs<7{HYm zzYfGhAv%x{sL_Eqs9%SHfg64xf`1Qnm72Z_3kdXNx3 z2sP)p9z#92ZFgCZfkB6Xf#Iee1A`d@0|T2rqz+<68N{l^XJA!YkL14t1mX2`%`4Qh-ULV~>8 z5E2qA3?T*6CPPTkdfkwLK?zi!8$k*feIrPLV{8Nov3Mhh{wyfnZUhN|B}Nd7w-`a} zIbClAiA#24hz4b2P^x5La4?1hwVyF0sH33#Tw_QOR~kbMYJkd5H-;+8Q3 zLns3S!zW`%$a2XT)wFfc4(02h%UE<-v414A{aLSbNF=mLu{FdSxJU|7t+ zz>vhiz%UEc*koW}I0%XY21x1$DOBMXSwf8{+3=9n63=9k%P&UYZFmn-@gv1S~ zFBk)AB7q7UP~Q$zTtekR*>ei0p9tlH+wo8~%rH=Y5mZpcGB7Zdf_hX?`QuO;)c}d>;_y=)2CwKD6*KY!KJs21m@nf+z`&5oz`&5j zz`(EyDz_O_af4cvP(F+THS9rbP#+0IgYZ%i!N9;Un*owfL0nKfTOE{i`xqD)ia=dc z1_p-d3=9n2AXx?m1|KLL1*Jh9aS#*K3Ty{4pm-ev1H%LcNEr(iV%WvNz_0CxS+;-IRm)258^VEFfcI8 z1G6Bl!#D;=Q3V=?IK%+yVXkFhU}yrBDo}MG>Hw&h0b(#f8VZ`AQGrAT28If#U^W8- z!)_>h1_PwP1&t)=Og<}cUd<D77G`l0h{&zcjBz70k;_-8@UsMS#Q5Lc!3?%Ghx8 jGevVIBSVG!l!E;7%+!>lyWq-ULRFbqgf`2l{15^FGzPDI delta 4341 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 I3YG6d01`Zm_y7O^ diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index edbb5212..9bc9eece 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-03 01:52-0400\n" +"POT-Creation-Date: 2013-07-18 16:31-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -23,6 +23,7 @@ msgstr "" #: /var/www/html/Tinyboard/inc/functions.php:972 #: ../../../../inc/functions.php:1041 ../../../../inc/functions.php:1055 #: ../../../../inc/functions.php:1039 ../../../../inc/functions.php:1053 +#: ../../../../inc/functions.php:1068 ../../../../inc/functions.php:1082 msgid "Previous" msgstr "Wstecz" @@ -31,6 +32,7 @@ msgstr "Wstecz" #: /var/www/html/Tinyboard/inc/functions.php:986 #: ../../../../inc/functions.php:1060 ../../../../inc/functions.php:1069 #: ../../../../inc/functions.php:1058 ../../../../inc/functions.php:1067 +#: ../../../../inc/functions.php:1087 ../../../../inc/functions.php:1096 msgid "Next" msgstr "Dalej" @@ -74,209 +76,209 @@ msgstr "Szybka odpowiedź" #. #. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 -#: ../../../../inc/config.php:692 +#: ../../../../inc/config.php:692 ../../../../inc/config.php:698 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 -#: ../../../../inc/config.php:693 +#: ../../../../inc/config.php:693 ../../../../inc/config.php:699 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 -#: ../../../../inc/config.php:694 +#: ../../../../inc/config.php:694 ../../../../inc/config.php:700 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " "odsyłaczu w nagłówku" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 -#: ../../../../inc/config.php:695 +#: ../../../../inc/config.php:695 ../../../../inc/config.php:701 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 -#: ../../../../inc/config.php:696 +#: ../../../../inc/config.php:696 ../../../../inc/config.php:702 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 -#: ../../../../inc/config.php:697 +#: ../../../../inc/config.php:697 ../../../../inc/config.php:703 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 -#: ../../../../inc/config.php:698 +#: ../../../../inc/config.php:698 ../../../../inc/config.php:704 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 -#: ../../../../inc/config.php:699 +#: ../../../../inc/config.php:699 ../../../../inc/config.php:705 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 -#: ../../../../inc/config.php:700 +#: ../../../../inc/config.php:700 ../../../../inc/config.php:706 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 -#: ../../../../inc/config.php:701 +#: ../../../../inc/config.php:701 ../../../../inc/config.php:707 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 -#: ../../../../inc/config.php:702 +#: ../../../../inc/config.php:702 ../../../../inc/config.php:708 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 -#: ../../../../inc/config.php:703 +#: ../../../../inc/config.php:703 ../../../../inc/config.php:709 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 -#: ../../../../inc/config.php:706 +#: ../../../../inc/config.php:706 ../../../../inc/config.php:712 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 -#: ../../../../inc/config.php:707 +#: ../../../../inc/config.php:707 ../../../../inc/config.php:713 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 -#: ../../../../inc/config.php:708 +#: ../../../../inc/config.php:708 ../../../../inc/config.php:714 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 -#: ../../../../inc/config.php:709 +#: ../../../../inc/config.php:709 ../../../../inc/config.php:715 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 -#: ../../../../inc/config.php:710 +#: ../../../../inc/config.php:710 ../../../../inc/config.php:716 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 -#: ../../../../inc/config.php:711 +#: ../../../../inc/config.php:711 ../../../../inc/config.php:717 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 -#: ../../../../inc/config.php:712 +#: ../../../../inc/config.php:712 ../../../../inc/config.php:718 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 -#: ../../../../inc/config.php:713 +#: ../../../../inc/config.php:713 ../../../../inc/config.php:719 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 -#: ../../../../inc/config.php:714 +#: ../../../../inc/config.php:714 ../../../../inc/config.php:720 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 -#: ../../../../inc/config.php:715 +#: ../../../../inc/config.php:715 ../../../../inc/config.php:721 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 -#: ../../../../inc/config.php:716 +#: ../../../../inc/config.php:716 ../../../../inc/config.php:722 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 -#: ../../../../inc/config.php:717 +#: ../../../../inc/config.php:717 ../../../../inc/config.php:723 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 -#: ../../../../inc/config.php:718 +#: ../../../../inc/config.php:718 ../../../../inc/config.php:724 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 -#: ../../../../inc/config.php:719 +#: ../../../../inc/config.php:719 ../../../../inc/config.php:725 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 -#: ../../../../inc/config.php:720 +#: ../../../../inc/config.php:720 ../../../../inc/config.php:726 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 -#: ../../../../inc/config.php:721 +#: ../../../../inc/config.php:721 ../../../../inc/config.php:727 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 -#: ../../../../inc/config.php:722 +#: ../../../../inc/config.php:722 ../../../../inc/config.php:728 msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
Rozmiar twojego pliku: %filesz% " "bajtów" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 -#: ../../../../inc/config.php:723 +#: ../../../../inc/config.php:723 ../../../../inc/config.php:729 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 -#: ../../../../inc/config.php:724 +#: ../../../../inc/config.php:724 ../../../../inc/config.php:730 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 -#: ../../../../inc/config.php:725 +#: ../../../../inc/config.php:725 ../../../../inc/config.php:731 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 -#: ../../../../inc/config.php:727 +#: ../../../../inc/config.php:727 ../../../../inc/config.php:733 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 -#: ../../../../inc/config.php:728 +#: ../../../../inc/config.php:728 ../../../../inc/config.php:734 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " "odrzucony" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 -#: ../../../../inc/config.php:729 +#: ../../../../inc/config.php:729 ../../../../inc/config.php:735 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 -#: ../../../../inc/config.php:730 +#: ../../../../inc/config.php:730 ../../../../inc/config.php:736 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 -#: ../../../../inc/config.php:734 +#: ../../../../inc/config.php:734 ../../../../inc/config.php:740 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 -#: ../../../../inc/config.php:735 +#: ../../../../inc/config.php:735 ../../../../inc/config.php:741 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 -#: ../../../../inc/config.php:736 +#: ../../../../inc/config.php:736 ../../../../inc/config.php:742 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -284,56 +286,56 @@ msgstr "" "albo zmienione." #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 -#: ../../../../inc/config.php:737 +#: ../../../../inc/config.php:737 ../../../../inc/config.php:743 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 -#: ../../../../inc/config.php:738 +#: ../../../../inc/config.php:738 ../../../../inc/config.php:744 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 -#: ../../../../inc/config.php:739 +#: ../../../../inc/config.php:739 ../../../../inc/config.php:745 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 -#: ../../../../inc/config.php:740 +#: ../../../../inc/config.php:740 ../../../../inc/config.php:746 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 -#: ../../../../inc/config.php:741 +#: ../../../../inc/config.php:741 ../../../../inc/config.php:747 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 -#: ../../../../inc/config.php:742 +#: ../../../../inc/config.php:742 ../../../../inc/config.php:748 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 -#: ../../../../inc/config.php:743 +#: ../../../../inc/config.php:743 ../../../../inc/config.php:749 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 -#: ../../../../inc/config.php:744 +#: ../../../../inc/config.php:744 ../../../../inc/config.php:750 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 -#: ../../../../inc/config.php:745 +#: ../../../../inc/config.php:745 ../../../../inc/config.php:751 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 -#: ../../../../inc/config.php:746 +#: ../../../../inc/config.php:746 ../../../../inc/config.php:752 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -444,7 +446,7 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:292 #: /var/www/html/Tinyboard/inc/display.php:408 -#: ../../../../inc/mod/pages.php:1080 +#: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 msgid "Edit post" msgstr "Edytuj post" @@ -564,6 +566,10 @@ msgstr "Komentarz" #. line 73 #. line 61 #. line 73 +#. line 61 +#. line 73 +#. line 61 +#. line 73 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:191 @@ -617,6 +623,10 @@ msgstr "Weryfikacja" #. line 87 #. line 3 #. line 87 +#. line 3 +#. line 87 +#. line 3 +#. line 87 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 @@ -686,6 +696,10 @@ msgstr "Flagi" #. line 114 #. line 113 #. line 114 +#. line 113 +#. line 114 +#. line 113 +#. line 114 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 @@ -741,6 +755,10 @@ msgstr "Przyklejony" #. line 118 #. line 117 #. line 118 +#. line 117 +#. line 118 +#. line 117 +#. line 118 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 @@ -796,6 +814,10 @@ msgstr "Zablokowany" #. line 122 #. line 121 #. line 122 +#. line 121 +#. line 122 +#. line 121 +#. line 122 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 @@ -844,12 +866,14 @@ msgstr "Odśwież" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:478 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:415 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:461 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:472 msgid "Reply" msgstr "Odpowiedź" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:511 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:442 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:488 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:499 msgid "1 post" msgid_plural "%count% posts" msgstr[0] "1 post" @@ -859,12 +883,14 @@ msgstr[2] "%count% postów" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:517 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:448 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:494 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 msgid "and" msgstr "oraz" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:528 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:459 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:516 msgid "1 image reply" msgid_plural "%count% image replies" msgstr[0] "1 obrazek" @@ -874,6 +900,7 @@ msgstr[2] "%count% obrazków" #: /var/www/html/Tinyboard/templates/cache/96/13/d13c7abb8d82989e547dc9be1787.php:533 #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:464 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:510 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:521 msgid "omitted. Click reply to view." msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." @@ -885,13 +912,17 @@ msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." #: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:121 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:98 #: ../../../../templates/cache/62/8c/21348d46377c3e1b3f8c476ba376.php:62 +#: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:131 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:115 msgid "Return to dashboard" msgstr "Powróć na tablicę" #. line 27 +#. line 31 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:165 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:177 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:106 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:123 msgid "Posting mode: Reply" msgstr "Tryb postowania: Odpowiedź" @@ -901,6 +932,8 @@ msgstr "Tryb postowania: Odpowiedź" #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:222 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:109 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:155 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:126 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:172 msgid "Return" msgstr "Powrót" @@ -941,21 +974,25 @@ msgstr "Wiadomości prywatne" #: /var/www/html/Tinyboard/mod.php:136 /var/www/html/Tinyboard/mod.php:874 #: ../../../../inc/mod/pages.php:376 ../../../../inc/mod/pages.php:393 +#: ../../../../inc/mod/pages.php:406 msgid "News" msgstr "Aktualności" #: /var/www/html/Tinyboard/mod.php:141 /var/www/html/Tinyboard/mod.php:1614 #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 +#: ../../../../inc/mod/pages.php:1682 msgid "Report queue" msgstr "Kolejka zgłoszeń" #: /var/www/html/Tinyboard/mod.php:144 /var/www/html/Tinyboard/mod.php:1882 #: ../../../../inc/mod/pages.php:664 ../../../../inc/mod/pages.php:705 +#: ../../../../inc/mod/pages.php:721 msgid "Ban list" msgstr "Lista banów" #: /var/www/html/Tinyboard/mod.php:147 /var/www/html/Tinyboard/mod.php:1288 #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 +#: ../../../../inc/mod/pages.php:1394 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -966,6 +1003,7 @@ msgstr "Zmień swoje hasło" #: /var/www/html/Tinyboard/mod.php:152 /var/www/html/Tinyboard/mod.php:477 #: ../../../../inc/mod/pages.php:416 ../../../../inc/mod/pages.php:443 #: ../../../../inc/mod/pages.php:433 ../../../../inc/mod/pages.php:460 +#: ../../../../inc/mod/pages.php:446 ../../../../inc/mod/pages.php:473 msgid "Moderation log" msgstr "Log moderacji" @@ -983,6 +1021,7 @@ msgstr "Pokaż konfigurację" #: /var/www/html/Tinyboard/mod.php:165 /var/www/html/Tinyboard/mod.php:709 #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 +#: ../../../../inc/mod/pages.php:1830 msgid "Manage themes" msgstr "Zarządzaj dodatkami" @@ -1038,12 +1077,12 @@ msgid "Action" msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 -#: ../../../../inc/mod/pages.php:1789 +#: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 -#: ../../../../inc/mod/pages.php:1791 +#: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -1077,7 +1116,8 @@ msgstr "Instaluj" #: /var/www/html/Tinyboard/mod.php:693 ../../../../inc/mod/pages.php:1467 #: ../../../../inc/mod/pages.php:1471 ../../../../inc/mod/pages.php:1567 -#: ../../../../inc/mod/pages.php:1571 +#: ../../../../inc/mod/pages.php:1571 ../../../../inc/mod/pages.php:1592 +#: ../../../../inc/mod/pages.php:1596 msgid "Rebuild" msgstr "Przebuduj" @@ -1098,7 +1138,7 @@ msgid "Post to noticeboard" msgstr "Postuj na tablicy ogłoszeń" #: /var/www/html/Tinyboard/mod.php:792 ../../../../inc/mod/pages.php:316 -#: ../../../../inc/mod/pages.php:333 +#: ../../../../inc/mod/pages.php:333 ../../../../inc/mod/pages.php:346 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -1168,12 +1208,12 @@ msgid "Configuration" msgstr "Konfiguracja" #: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 -#: ../../../../inc/mod/pages.php:272 +#: ../../../../inc/mod/pages.php:272 ../../../../inc/mod/pages.php:285 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." #: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 -#: ../../../../inc/mod/pages.php:800 +#: ../../../../inc/mod/pages.php:800 ../../../../inc/mod/pages.php:823 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." @@ -1182,6 +1222,7 @@ msgid "No board to move to; there is only one." msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." #: ../../../../inc/config.php:689 ../../../../inc/config.php:747 +#: ../../../../inc/config.php:753 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." @@ -1190,68 +1231,83 @@ msgid "Confirm action" msgstr "Potwierdź akcję" #: ../../../../inc/mod/pages.php:222 ../../../../inc/mod/pages.php:239 +#: ../../../../inc/mod/pages.php:252 msgid "Edit board" msgstr "Edytuj board" #: ../../../../inc/mod/pages.php:270 ../../../../inc/mod/pages.php:287 +#: ../../../../inc/mod/pages.php:300 msgid "New board" msgstr "Nowy board" #: ../../../../inc/mod/pages.php:586 ../../../../inc/mod/pages.php:612 +#: ../../../../inc/mod/pages.php:628 msgid "IP" msgstr "adres IP" #: ../../../../inc/mod/pages.php:596 ../../../../inc/mod/pages.php:985 #: ../../../../inc/mod/pages.php:622 ../../../../inc/mod/pages.php:1028 +#: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 msgid "New ban" msgstr "Nowy ban" #: ../../../../inc/mod/pages.php:919 ../../../../inc/mod/pages.php:962 +#: ../../../../inc/mod/pages.php:987 msgid "Impossible to move thread; there is only one board." msgstr "Nie można przenieść wątku; istnieje tylko jeden board." #: ../../../../inc/mod/pages.php:923 ../../../../inc/mod/pages.php:966 +#: ../../../../inc/mod/pages.php:991 msgid "Move thread" msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1209 ../../../../inc/mod/pages.php:1258 #: ../../../../inc/mod/pages.php:1307 ../../../../inc/mod/pages.php:1356 +#: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 msgid "Edit user" msgstr "Edytuj użytkownika" #. deleted? #: ../../../../inc/mod/pages.php:1333 ../../../../inc/mod/pages.php:1405 #: ../../../../inc/mod/pages.php:1431 ../../../../inc/mod/pages.php:1503 +#: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 +#: ../../../../inc/mod/pages.php:1460 msgid "Private message" msgstr "Prywatna wiadomość" #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 +#: ../../../../inc/mod/pages.php:1481 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 +#: ../../../../inc/mod/pages.php:1804 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 +#: ../../../../inc/mod/pages.php:1970 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 +#: ../../../../inc/mod/pages.php:1892 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 +#: ../../../../inc/mod/pages.php:1903 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 +#: ../../../../inc/mod/pages.php:1931 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1262,21 +1318,21 @@ msgid "" "\n" msgstr "" -#: ../../../../inc/config.php:704 +#: ../../../../inc/config.php:704 ../../../../inc/config.php:710 msgid "Thread has reached its maximum reply limit." msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." -#: ../../../../inc/config.php:705 +#: ../../../../inc/config.php:705 ../../../../inc/config.php:711 msgid "Thread has reached its maximum image limit." msgstr "Ten temat osiągnął swój maksymalny limit obrazków." -#: ../../../../inc/config.php:726 +#: ../../../../inc/config.php:726 ../../../../inc/config.php:732 #, php-format msgid "That file already exists in this thread!" msgstr "Ten plik już istnieje w tym temacie!" #. Moderator errors -#: ../../../../inc/config.php:733 +#: ../../../../inc/config.php:733 ../../../../inc/config.php:739 #, php-format msgid "" "You are only allowed to unban %s users at a time. You tried to unban %u " @@ -1284,10 +1340,18 @@ msgid "" msgstr "" "Możesz odbanować tylko %s użytkowników na raz. Próbowałeś odbanować %u users." -#: ../../../../inc/mod/pages.php:1969 +#: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" -#: ../../../../inc/mod/pages.php:1993 +#: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 msgid "Debug: SQL" msgstr "Debug: SQL" + +#. line 28 +#: ../../../../templates/cache/4b/3e/915cc5ac5fe144c331207c656528.php:104 +msgid "1 reply" +msgid_plural "%count% replies" +msgstr[0] "1 odpowiedź" +msgstr[1] "%count% odpowiedzi" +msgstr[2] "%count% odpowiedzi" From b772be7c5b37d5bbfb117e6417bd61847a645eba Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 20 Jul 2013 20:23:55 -0400 Subject: [PATCH 107/289] Update Polish translation --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 14191 -> 18730 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 482 +++++++++++++++++++++- 2 files changed, 463 insertions(+), 19 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index ac57873e8d6086164123d2fe16def54f5eae177f..b1ccc28dccca8e142bb299e8262d99d762ed7270 100644 GIT binary patch delta 8806 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 E0NM_#761SM delta 4800 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 NO|GgeNz6-S002\n" "Language-Team: LANGUAGE \n" @@ -41,11 +41,17 @@ msgid "Unsupported file format: " msgstr "Niewspierany format pliku: " #: /var/www/html/Tinyboard/inc/mod.php:129 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:74 msgid "Create new board" msgstr "Stwórz nowy board" +#. line 71 #: /var/www/html/Tinyboard/inc/mod.php:138 #: /var/www/html/Tinyboard/mod.php:1833 /var/www/html/Tinyboard/mod.php:3036 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:291 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:75 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:150 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:207 msgid "all boards" msgstr "wszystkie boardy" @@ -447,6 +453,7 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:292 #: /var/www/html/Tinyboard/inc/display.php:408 #: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 +#: ../../../../inc/mod/pages.php:1239 msgid "Edit post" msgstr "Edytuj post" @@ -570,6 +577,8 @@ msgstr "Komentarz" #. line 73 #. line 61 #. line 73 +#. line 61 +#. line 73 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:191 @@ -627,6 +636,8 @@ msgstr "Weryfikacja" #. line 87 #. line 3 #. line 87 +#. line 3 +#. line 87 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 @@ -700,6 +711,8 @@ msgstr "Flagi" #. line 114 #. line 113 #. line 114 +#. line 113 +#. line 114 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 @@ -759,6 +772,8 @@ msgstr "Przyklejony" #. line 118 #. line 117 #. line 118 +#. line 117 +#. line 118 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 @@ -818,6 +833,8 @@ msgstr "Zablokowany" #. line 122 #. line 121 #. line 122 +#. line 121 +#. line 122 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 @@ -827,6 +844,8 @@ msgstr "Zablokowany" msgid "Raw HTML" msgstr "Czysty HTML" +#. line 129 +#. line 14 #. line 129 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:230 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:23 @@ -834,6 +853,7 @@ msgstr "Czysty HTML" #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:23 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:23 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:342 +#: ../../../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:41 msgid "Password" msgstr "Hasło" @@ -884,6 +904,7 @@ msgstr[2] "%count% postów" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:448 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:494 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:114 msgid "and" msgstr "oraz" @@ -945,10 +966,17 @@ msgid "Delete Post" msgstr "Usuń post" #. line 8 +#. line 106 +#. line 8 +#. line 32 +#. line 48 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:32 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:256 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:90 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:128 msgid "Reason" msgstr "Powód" @@ -961,6 +989,7 @@ msgstr "Zgłoszenie" #: /var/www/html/Tinyboard/mod.php:104 /var/www/html/Tinyboard/mod.php:776 #: /var/www/html/Tinyboard/mod.php:862 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:120 msgid "no subject" msgstr "brak tematu" @@ -974,25 +1003,29 @@ msgstr "Wiadomości prywatne" #: /var/www/html/Tinyboard/mod.php:136 /var/www/html/Tinyboard/mod.php:874 #: ../../../../inc/mod/pages.php:376 ../../../../inc/mod/pages.php:393 -#: ../../../../inc/mod/pages.php:406 +#: ../../../../inc/mod/pages.php:406 ../../../../inc/mod/pages.php:540 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:166 msgid "News" msgstr "Aktualności" #: /var/www/html/Tinyboard/mod.php:141 /var/www/html/Tinyboard/mod.php:1614 #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 -#: ../../../../inc/mod/pages.php:1682 +#: ../../../../inc/mod/pages.php:1682 ../../../../inc/mod/pages.php:1816 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 msgid "Report queue" msgstr "Kolejka zgłoszeń" #: /var/www/html/Tinyboard/mod.php:144 /var/www/html/Tinyboard/mod.php:1882 #: ../../../../inc/mod/pages.php:664 ../../../../inc/mod/pages.php:705 -#: ../../../../inc/mod/pages.php:721 +#: ../../../../inc/mod/pages.php:721 ../../../../inc/mod/pages.php:855 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:224 msgid "Ban list" msgstr "Lista banów" #: /var/www/html/Tinyboard/mod.php:147 /var/www/html/Tinyboard/mod.php:1288 #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 -#: ../../../../inc/mod/pages.php:1394 +#: ../../../../inc/mod/pages.php:1394 ../../../../inc/mod/pages.php:1528 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -1004,6 +1037,9 @@ msgstr "Zmień swoje hasło" #: ../../../../inc/mod/pages.php:416 ../../../../inc/mod/pages.php:443 #: ../../../../inc/mod/pages.php:433 ../../../../inc/mod/pages.php:460 #: ../../../../inc/mod/pages.php:446 ../../../../inc/mod/pages.php:473 +#: ../../../../inc/mod/pages.php:580 ../../../../inc/mod/pages.php:607 +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:65 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:255 msgid "Moderation log" msgstr "Log moderacji" @@ -1021,15 +1057,28 @@ msgstr "Pokaż konfigurację" #: /var/www/html/Tinyboard/mod.php:165 /var/www/html/Tinyboard/mod.php:709 #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 -#: ../../../../inc/mod/pages.php:1830 +#: ../../../../inc/mod/pages.php:1830 ../../../../inc/mod/pages.php:1964 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 msgid "Manage themes" msgstr "Zarządzaj dodatkami" +#. line 2 +#. line 5 #: /var/www/html/Tinyboard/mod.php:170 +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:19 +#: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:24 msgid "Phrase:" msgstr "Wyrażenie:" +#. line 16 +#. line 2 +#. line 106 +#. line 2 #: /var/www/html/Tinyboard/mod.php:172 +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:72 +#: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:19 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:286 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:19 msgid "Search" msgstr "Szukaj" @@ -1047,7 +1096,9 @@ msgstr "" msgid "Could not find current version! (Check .installed)" msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" +#. line 146 #: /var/www/html/Tinyboard/mod.php:233 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:364 msgid "Logout" msgstr "Wyloguj" @@ -1060,7 +1111,11 @@ msgstr "Tablica" msgid "User" msgstr "Użytkownik" +#. line 16 +#. line 134 #: /var/www/html/Tinyboard/mod.php:403 /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:48 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:349 msgid "IP address" msgstr "Adres IP" @@ -1068,21 +1123,37 @@ msgstr "Adres IP" msgid "Ago" msgstr "temu" +#. line 116 +#. line 182 +#. line 65 +#. line 49 +#. line 136 #: /var/www/html/Tinyboard/mod.php:405 /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:278 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:427 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:142 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:131 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:355 msgid "Board" msgstr "Board" +#. line 183 +#. line 137 #: /var/www/html/Tinyboard/mod.php:406 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:430 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:358 msgid "Action" msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 #: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 +#: ../../../../inc/mod/pages.php:1948 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 #: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 +#: ../../../../inc/mod/pages.php:1950 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -1099,6 +1170,7 @@ msgid "Thumbnail" msgstr "Miniatura" #: /var/www/html/Tinyboard/mod.php:687 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:86 msgid "Actions" msgstr "Akcje" @@ -1117,7 +1189,9 @@ msgstr "Instaluj" #: /var/www/html/Tinyboard/mod.php:693 ../../../../inc/mod/pages.php:1467 #: ../../../../inc/mod/pages.php:1471 ../../../../inc/mod/pages.php:1567 #: ../../../../inc/mod/pages.php:1571 ../../../../inc/mod/pages.php:1592 -#: ../../../../inc/mod/pages.php:1596 +#: ../../../../inc/mod/pages.php:1596 ../../../../inc/mod/pages.php:1726 +#: ../../../../inc/mod/pages.php:1730 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 msgid "Rebuild" msgstr "Przebuduj" @@ -1137,8 +1211,11 @@ msgstr "Zawartość" msgid "Post to noticeboard" msgstr "Postuj na tablicy ogłoszeń" +#. line 31 #: /var/www/html/Tinyboard/mod.php:792 ../../../../inc/mod/pages.php:316 #: ../../../../inc/mod/pages.php:333 ../../../../inc/mod/pages.php:346 +#: ../../../../inc/mod/pages.php:480 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:96 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -1162,7 +1239,9 @@ msgstr "nieprzeczytane" msgid "ID" msgstr "ID" +#. line 6 #: /var/www/html/Tinyboard/mod.php:1221 +#: ../../../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:28 msgid "Username" msgstr "Nazwa użytkownika" @@ -1170,7 +1249,9 @@ msgstr "Nazwa użytkownika" msgid "Type" msgstr "Typ" +#. line 2 #: /var/www/html/Tinyboard/mod.php:1221 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:19 msgid "Boards" msgstr "Boardy" @@ -1186,15 +1267,37 @@ msgstr "Stwórz nowego użytkownika" msgid "Could not re-login after changing password. (?)" msgstr "Nie można się ponownie zalogować po zmianie hasła. (?)" +#. line 126 +#. line 50 #: /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:300 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:134 msgid "Set" msgstr "Ustawione" +#. line 130 +#. line 52 #: /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:309 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:140 msgid "Expires" msgstr "Wygasa" +#. line 24 +#. line 62 +#. line 150 +#. line 180 +#. line 17 +#. line 54 +#. line 133 #: /var/www/html/Tinyboard/mod.php:1801 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:74 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:169 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:352 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:421 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:51 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:146 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:346 msgid "Staff" msgstr "Ekipa" @@ -1204,16 +1307,19 @@ msgstr "Cache jest wyłączone." #: /var/www/html/Tinyboard/mod.php:1966 /var/www/html/Tinyboard/mod.php:2057 #: /var/www/html/Tinyboard/mod.php:2106 /var/www/html/Tinyboard/mod.php:2110 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:271 msgid "Configuration" msgstr "Konfiguracja" #: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 #: ../../../../inc/mod/pages.php:272 ../../../../inc/mod/pages.php:285 +#: ../../../../inc/mod/pages.php:419 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." #: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 #: ../../../../inc/mod/pages.php:800 ../../../../inc/mod/pages.php:823 +#: ../../../../inc/mod/pages.php:957 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." @@ -1231,39 +1337,49 @@ msgid "Confirm action" msgstr "Potwierdź akcję" #: ../../../../inc/mod/pages.php:222 ../../../../inc/mod/pages.php:239 -#: ../../../../inc/mod/pages.php:252 +#: ../../../../inc/mod/pages.php:252 ../../../../inc/mod/pages.php:386 msgid "Edit board" msgstr "Edytuj board" #: ../../../../inc/mod/pages.php:270 ../../../../inc/mod/pages.php:287 -#: ../../../../inc/mod/pages.php:300 +#: ../../../../inc/mod/pages.php:300 ../../../../inc/mod/pages.php:434 msgid "New board" msgstr "Nowy board" +#. line 102 +#. line 20 #: ../../../../inc/mod/pages.php:586 ../../../../inc/mod/pages.php:612 -#: ../../../../inc/mod/pages.php:628 +#: ../../../../inc/mod/pages.php:628 ../../../../inc/mod/pages.php:762 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:247 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:65 msgid "IP" msgstr "adres IP" +#. line 169 #: ../../../../inc/mod/pages.php:596 ../../../../inc/mod/pages.php:985 #: ../../../../inc/mod/pages.php:622 ../../../../inc/mod/pages.php:1028 #: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 +#: ../../../../inc/mod/pages.php:772 ../../../../inc/mod/pages.php:1187 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:398 msgid "New ban" msgstr "Nowy ban" #: ../../../../inc/mod/pages.php:919 ../../../../inc/mod/pages.php:962 -#: ../../../../inc/mod/pages.php:987 +#: ../../../../inc/mod/pages.php:987 ../../../../inc/mod/pages.php:1121 msgid "Impossible to move thread; there is only one board." msgstr "Nie można przenieść wątku; istnieje tylko jeden board." +#. line 39 #: ../../../../inc/mod/pages.php:923 ../../../../inc/mod/pages.php:966 -#: ../../../../inc/mod/pages.php:991 +#: ../../../../inc/mod/pages.php:991 ../../../../inc/mod/pages.php:1125 +#: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:106 msgid "Move thread" msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1209 ../../../../inc/mod/pages.php:1258 #: ../../../../inc/mod/pages.php:1307 ../../../../inc/mod/pages.php:1356 #: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 +#: ../../../../inc/mod/pages.php:1466 ../../../../inc/mod/pages.php:1515 msgid "Edit user" msgstr "Edytuj użytkownika" @@ -1271,43 +1387,46 @@ msgstr "Edytuj użytkownika" #: ../../../../inc/mod/pages.php:1333 ../../../../inc/mod/pages.php:1405 #: ../../../../inc/mod/pages.php:1431 ../../../../inc/mod/pages.php:1503 #: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 +#: ../../../../inc/mod/pages.php:1590 ../../../../inc/mod/pages.php:1662 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 -#: ../../../../inc/mod/pages.php:1460 +#: ../../../../inc/mod/pages.php:1460 ../../../../inc/mod/pages.php:1594 msgid "Private message" msgstr "Prywatna wiadomość" +#. line 62 #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 -#: ../../../../inc/mod/pages.php:1481 +#: ../../../../inc/mod/pages.php:1481 ../../../../inc/mod/pages.php:1615 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 -#: ../../../../inc/mod/pages.php:1804 +#: ../../../../inc/mod/pages.php:1804 ../../../../inc/mod/pages.php:1938 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 -#: ../../../../inc/mod/pages.php:1970 +#: ../../../../inc/mod/pages.php:1970 ../../../../inc/mod/pages.php:2104 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 -#: ../../../../inc/mod/pages.php:1892 +#: ../../../../inc/mod/pages.php:1892 ../../../../inc/mod/pages.php:2026 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 -#: ../../../../inc/mod/pages.php:1903 +#: ../../../../inc/mod/pages.php:1903 ../../../../inc/mod/pages.php:2037 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 -#: ../../../../inc/mod/pages.php:1931 +#: ../../../../inc/mod/pages.php:1931 ../../../../inc/mod/pages.php:2065 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1341,10 +1460,12 @@ msgstr "" "Możesz odbanować tylko %s użytkowników na raz. Próbowałeś odbanować %u users." #: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 +#: ../../../../inc/mod/pages.php:2128 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" #: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 +#: ../../../../inc/mod/pages.php:2152 msgid "Debug: SQL" msgstr "Debug: SQL" @@ -1355,3 +1476,326 @@ msgid_plural "%count% replies" msgstr[0] "1 odpowiedź" msgstr[1] "%count% odpowiedzi" msgstr[2] "%count% odpowiedzi" + +#. $results now contains the search results +#: ../../../../inc/mod/pages.php:290 +msgid "Search results" +msgstr "Wyniki wyszukiwania" + +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:31 +msgid "Posts" +msgstr "Posty" + +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:41 +msgid "IP address notes" +msgstr "Notatki adresu IP" + +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:53 +msgid "Bans" +msgstr "Bany" + +#. line 18 +#: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:76 +msgid "" +"(Search is case-insensitive and based on keywords. To match exact phrases, " +"use \"quotes\". Use an asterisk (*) for wildcard.)" +msgstr "" +"(Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " +"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " +"wieloznacznego.)" + +#. line 8 +#: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:32 +msgid "Select board" +msgstr "Wybierz board" + +#. line 17 +#: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:61 +msgid "" +"Search is case-insensitive and based on keywords. To match exact phrases, " +"use \"quotes\". Use an asterisk (*) for wildcard.

You may apply the following filters to your searches: " +"id, thread, subject, and " +"name. To apply a filter, simply add to your query, for " +"example, name:Anonymous or subject:\"Some Thread\". " +"Wildcards cannot be used in filters." +msgstr "" +"Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " +"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " +"wieloznacznego.

Możesz zastosować poniższe " +"filtry do swojego wyszukiwania: id, thread, " +"subject, i name. Aby wykorzystać filtr, " +"po prostu dodaj do swojego zapytania, na przykład: name:Anonymous " +"albo subject:\"Jakiś temat\". Symbole wieloznaczne nie mogą być " +"wykorzystane w filtrach." + +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:57 +msgid "edit" +msgstr "edytuj" + +#. line 26 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:84 +msgid "Messages" +msgstr "Wiadomości" + +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:161 +msgid "View all noticeboard entries" +msgstr "Pokaż wszystkie wpisy na tablicy ogłoszeń" + +#. line 70 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:192 +msgid "Administration" +msgstr "Administracja" + +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:239 +msgid "Change password" +msgstr "Zmień hasło" + +#. line 118 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:308 +msgid "Debug" +msgstr "Debug" + +#. line 120 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:312 +msgid "Anti-spam" +msgstr "Antyspam" + +#. line 121 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:315 +msgid "Recent posts" +msgstr "Ostatnie posty" + +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:321 +msgid "SQL" +msgstr "SQL" + +#. line 143 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:359 +msgid "User account" +msgstr "Konto użytkownika" + +#. line 25 +#. line 67 +#. line 18 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:77 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:179 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:54 +msgid "Note" +msgstr "Notka" + +#. line 26 +#. line 19 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:80 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:57 +msgid "Date" +msgstr "Data" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:112 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:365 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:457 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:88 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:321 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:385 +msgid "deleted?" +msgstr "usunięty?" + +#. line 49 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:142 +msgid "remove" +msgstr "usuń" + +#. line 75 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:189 +msgid "New note" +msgstr "Nowa notka" + +#. line 92 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:226 +msgid "Status" +msgstr "Status" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:233 +msgid "Expired" +msgstr "Wygasły" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:238 +msgid "Active" +msgstr "Aktywny" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:269 +msgid "no reason" +msgstr "brak powodu" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:322 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:246 +msgid "never" +msgstr "nigdy" + +#. line 140 +#. line 53 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:331 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:143 +msgid "Seen" +msgstr "Widziano" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:338 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:273 +msgid "Yes" +msgstr "Tak" + +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:343 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:278 +msgid "No" +msgstr "Nie" + +#. line 161 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:378 +msgid "Remove ban" +msgstr "Usuń ban" + +#. line 181 +#. line 135 +#: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:424 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:352 +msgid "Time" +msgstr "Czas" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:41 +msgid "You were banned! ;_;" +msgstr "Byłeś zbanowany! ;_;" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:46 +msgid "You are banned! ;_;" +msgstr "Jesteś zbanowany! ;_;" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:56 +msgid "You were banned from" +msgstr "Byłeś zbanowany na" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:61 +msgid "You have been banned from" +msgstr "Zostałeś zbanowany na" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:83 +msgid "for the following reason:" +msgstr "z następującego powodu:" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:88 +msgid "for an unspecified reason." +msgstr "z nieokreślonego powodu." + +#. line 32 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:109 +msgid "Your ban was filed on" +msgstr "Twój ban został nałożony" + +#. line 51 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:120 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:150 +msgid "has since expired. Refresh the page to continue." +msgstr "już wygasł. Odśwież stronę, aby kontynuować." + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:125 +msgid "expires" +msgstr "wygasa" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:128 +msgid "from now, which is on" +msgstr "od teraz, czyli" + +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:176 +msgid "will not expire" +msgstr "nie wygaśnie" + +#. line 78 +#: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:184 +msgid "Your IP address is" +msgstr "Twój adres IP to" + +#. line 23 +#: ../../../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:52 +msgid "Continue" +msgstr "Kontynuuj" + +#. line 6 +#: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:30 +msgid "Thread ID" +msgstr "ID wątku" + +#. line 14 +#: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:44 +msgid "Leave shadow thread" +msgstr "Pozostaw wątek-cień" + +#. line 18 +#: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:50 +msgid "locks thread; replies to it with a link." +msgstr "blokuje wątek; umieszcza link do nowego." + +#. line 22 +#: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:56 +msgid "Target board" +msgstr "Board docelowy" + +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:66 +msgid "(or subnet)" +msgstr "(lub podsieć)" + +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:80 +msgid "hidden" +msgstr "ukryty" + +#. line 41 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:107 +msgid "Message" +msgstr "Wiadomość" + +#. line 46 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:117 +msgid "public; attached to post" +msgstr "publiczny; dołączony do posta" + +#. line 58 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:133 +msgid "Length" +msgstr "Długość" + +#. line 88 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:192 +msgid "New Ban" +msgstr "Nowy ban" + +#. line 47 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:125 +msgid "IP address/mask" +msgstr "Adres IP lub maska" + +#. line 51 +#: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:137 +msgid "Duration" +msgstr "Czas trwania" + +#: ../../../../search.php:5 +msgid "Post search is disabled" +msgstr "Wyszukiwanie postów jest wyłączone" + +#: ../../../../search.php:25 ../../../../search.php:31 +msgid "Wait a while before searching again, please." +msgstr "Proszę poczekać chwilę przed ponownym szukaniem." + +#: ../../../../search.php:128 +msgid "Query too broad." +msgstr "Zapytanie zbyt szerokie." + +#: ../../../../search.php:149 +#, php-format +msgid "%d result in" +msgid_plural "%d results in" +msgstr[0] "%d wynik na" +msgstr[1] "%d wyniki na" +msgstr[2] "%d wyników na" + +#: ../../../../search.php:160 +msgid "No results." +msgstr "Brak wyników." From 22556f43f5fd845e3d0536b79c263290a70f3672 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:01:42 -0400 Subject: [PATCH 108/289] Update Polish locale --- inc/locale/pl_PL/LC_MESSAGES/javascript.js | 2 +- inc/locale/pl_PL/LC_MESSAGES/javascript.po | 26 +- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 18730 -> 19790 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 338 +++++++++++++++++++-- 4 files changed, 342 insertions(+), 24 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.js b/inc/locale/pl_PL/LC_MESSAGES/javascript.js index 44857b98..caf4a66c 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.js +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.js @@ -1 +1 @@ -l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie"}; \ No newline at end of file +l10n = {"Submit":"Wy\u015blij","Quick reply":"Szybka odpowied\u017a","Posting mode: Replying to >>{0}<\/small>":"Tryb postowania: Odpowied\u017a na >>{0}<\/small>","Return":"Powr\u00f3t","Click reply to view.":"Kliknij Odpowied\u017a aby zobaczy\u0107.","Click to expand":"Kliknij aby rozwin\u0105\u0107","Hide expanded replies":"Schowaj rozwini\u0119te odpowiedzi","Mon":"pon","Tue":"wto","Wed":"\u015bro","Thu":"czw","Fri":"pi\u0105","Sat":"sob","Sun":"nie","Show locked threads":"Poka\u017c zablokowane tematy","Hide locked threads":"Schowaj zablokowane tematy","Forced anonymity":"Wymuszona anonimowo\u015b\u0107","enabled":"w\u0142\u0105czona","disabled":"wy\u0142\u0105czona","Password":"Has\u0142o","Delete file only":"Usu\u0144 tylko plik","File":"Plik","Delete":"Usu\u0144","Reason":"Pow\u00f3d","Report":"Zg\u0142oszenie","hide":"ukryj","show":"poka\u017c","hidden":"ukryte","Show images":"Poka\u017c obrazki","Hide images":"Ukryj obrazki"}; \ No newline at end of file diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po index 3c16c8d7..482ec45f 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.po +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-18 16:31-0400\n" +"POT-Creation-Date: 2013-07-27 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,7 @@ msgstr "Kliknij Odpowiedź aby zobaczyć." msgid "Click to expand" msgstr "Kliknij aby rozwinąć" -#: ../../../../js/expand.js:41 +#: ../../../../js/expand.js:41 ../../../../js/expand.js:45 msgid "Hide expanded replies" msgstr "Schowaj rozwinięte odpowiedzi" @@ -104,7 +104,7 @@ msgstr "Hasło" msgid "Delete file only" msgstr "Usuń tylko plik" -#: ../../../../js/quick-post-controls.js:30 +#: ../../../../js/quick-post-controls.js:30 ../../../../js/hide-images.js:50 msgid "File" msgstr "Plik" @@ -119,3 +119,23 @@ msgstr "Powód" #: ../../../../js/quick-post-controls.js:37 msgid "Report" msgstr "Zgłoszenie" + +#: ../../../../js/hide-images.js:50 +msgid "hide" +msgstr "ukryj" + +#: ../../../../js/hide-images.js:56 +msgid "show" +msgstr "pokaż" + +#: ../../../../js/toggle-images.js:41 +msgid "hidden" +msgstr "ukryte" + +#: ../../../../js/toggle-images.js:57 ../../../../js/toggle-images.js:70 +msgid "Show images" +msgstr "Pokaż obrazki" + +#: ../../../../js/toggle-images.js:57 ../../../../js/toggle-images.js:70 +msgid "Hide images" +msgstr "Ukryj obrazki" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index b1ccc28dccca8e142bb299e8262d99d762ed7270..2a31d64e2b739bc537600e64426544aa1e58a4fe 100644 GIT binary patch delta 6892 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 XB<7_u\n" "Language-Team: LANGUAGE \n" @@ -52,10 +52,11 @@ msgstr "Stwórz nowy board" #: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:75 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:150 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:207 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:155 msgid "all boards" msgstr "wszystkie boardy" -#: /var/www/html/Tinyboard/inc/config.php:305 +#: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 msgid "You have been muted for unoriginal content." msgstr "Zostałeś zagłuszony za nieoryginalną treść." @@ -83,16 +84,19 @@ msgstr "Szybka odpowiedź" #. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 #: ../../../../inc/config.php:692 ../../../../inc/config.php:698 +#: ../../../../inc/config.php:695 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 #: ../../../../inc/config.php:693 ../../../../inc/config.php:699 +#: ../../../../inc/config.php:696 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 #: ../../../../inc/config.php:694 ../../../../inc/config.php:700 +#: ../../../../inc/config.php:697 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " @@ -100,135 +104,161 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 #: ../../../../inc/config.php:695 ../../../../inc/config.php:701 +#: ../../../../inc/config.php:698 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 #: ../../../../inc/config.php:696 ../../../../inc/config.php:702 +#: ../../../../inc/config.php:699 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 #: ../../../../inc/config.php:697 ../../../../inc/config.php:703 +#: ../../../../inc/config.php:700 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 #: ../../../../inc/config.php:698 ../../../../inc/config.php:704 +#: ../../../../inc/config.php:701 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 #: ../../../../inc/config.php:699 ../../../../inc/config.php:705 +#: ../../../../inc/config.php:702 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 #: ../../../../inc/config.php:700 ../../../../inc/config.php:706 +#: ../../../../inc/config.php:703 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 #: ../../../../inc/config.php:701 ../../../../inc/config.php:707 +#: ../../../../inc/config.php:704 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 #: ../../../../inc/config.php:702 ../../../../inc/config.php:708 +#: ../../../../inc/config.php:705 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 #: ../../../../inc/config.php:703 ../../../../inc/config.php:709 +#: ../../../../inc/config.php:706 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 #: ../../../../inc/config.php:706 ../../../../inc/config.php:712 +#: ../../../../inc/config.php:709 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 #: ../../../../inc/config.php:707 ../../../../inc/config.php:713 +#: ../../../../inc/config.php:710 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 #: ../../../../inc/config.php:708 ../../../../inc/config.php:714 +#: ../../../../inc/config.php:711 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 #: ../../../../inc/config.php:709 ../../../../inc/config.php:715 +#: ../../../../inc/config.php:712 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 #: ../../../../inc/config.php:710 ../../../../inc/config.php:716 +#: ../../../../inc/config.php:713 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 +#: ../../../../inc/config.php:714 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 +#: ../../../../inc/config.php:715 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 +#: ../../../../inc/config.php:716 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 +#: ../../../../inc/config.php:717 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 #: ../../../../inc/config.php:715 ../../../../inc/config.php:721 +#: ../../../../inc/config.php:718 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 #: ../../../../inc/config.php:716 ../../../../inc/config.php:722 +#: ../../../../inc/config.php:719 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 #: ../../../../inc/config.php:717 ../../../../inc/config.php:723 +#: ../../../../inc/config.php:720 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 #: ../../../../inc/config.php:718 ../../../../inc/config.php:724 +#: ../../../../inc/config.php:721 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 #: ../../../../inc/config.php:719 ../../../../inc/config.php:725 +#: ../../../../inc/config.php:722 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 #: ../../../../inc/config.php:720 ../../../../inc/config.php:726 +#: ../../../../inc/config.php:723 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 #: ../../../../inc/config.php:721 ../../../../inc/config.php:727 +#: ../../../../inc/config.php:724 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 #: ../../../../inc/config.php:722 ../../../../inc/config.php:728 +#: ../../../../inc/config.php:725 msgid "Maximum file size: %maxsz% bytes
Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
Rozmiar twojego pliku: %filesz% " @@ -236,28 +266,33 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 #: ../../../../inc/config.php:723 ../../../../inc/config.php:729 +#: ../../../../inc/config.php:726 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 #: ../../../../inc/config.php:724 ../../../../inc/config.php:730 +#: ../../../../inc/config.php:727 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 #: ../../../../inc/config.php:725 ../../../../inc/config.php:731 +#: ../../../../inc/config.php:728 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 #: ../../../../inc/config.php:727 ../../../../inc/config.php:733 +#: ../../../../inc/config.php:730 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 #: ../../../../inc/config.php:728 ../../../../inc/config.php:734 +#: ../../../../inc/config.php:731 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " @@ -265,26 +300,31 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 #: ../../../../inc/config.php:729 ../../../../inc/config.php:735 +#: ../../../../inc/config.php:732 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 #: ../../../../inc/config.php:730 ../../../../inc/config.php:736 +#: ../../../../inc/config.php:733 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 #: ../../../../inc/config.php:734 ../../../../inc/config.php:740 +#: ../../../../inc/config.php:737 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 #: ../../../../inc/config.php:735 ../../../../inc/config.php:741 +#: ../../../../inc/config.php:738 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 #: ../../../../inc/config.php:736 ../../../../inc/config.php:742 +#: ../../../../inc/config.php:739 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -293,55 +333,65 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 #: ../../../../inc/config.php:737 ../../../../inc/config.php:743 +#: ../../../../inc/config.php:740 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 #: ../../../../inc/config.php:738 ../../../../inc/config.php:744 +#: ../../../../inc/config.php:741 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 #: ../../../../inc/config.php:739 ../../../../inc/config.php:745 +#: ../../../../inc/config.php:742 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 #: ../../../../inc/config.php:740 ../../../../inc/config.php:746 +#: ../../../../inc/config.php:743 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 #: ../../../../inc/config.php:741 ../../../../inc/config.php:747 +#: ../../../../inc/config.php:744 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 #: ../../../../inc/config.php:742 ../../../../inc/config.php:748 +#: ../../../../inc/config.php:745 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 #: ../../../../inc/config.php:743 ../../../../inc/config.php:749 +#: ../../../../inc/config.php:746 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 #: ../../../../inc/config.php:744 ../../../../inc/config.php:750 +#: ../../../../inc/config.php:747 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 #: ../../../../inc/config.php:745 ../../../../inc/config.php:751 +#: ../../../../inc/config.php:748 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 #: ../../../../inc/config.php:746 ../../../../inc/config.php:752 +#: ../../../../inc/config.php:749 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -377,7 +427,9 @@ msgstr "[Edytuj]" msgid "[Move]" msgstr "[Przenieś]" -#: /var/www/html/Tinyboard/inc/config.php:801 +#. Default public ban message. +#. In public ban messages, %length% is replaced with "for x days" or "permanently" (with %LENGTH% being the uppercase equivalent). +#: /var/www/html/Tinyboard/inc/config.php:801 ../../../../inc/config.php:911 msgid "USER WAS BANNED FOR THIS POST" msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" @@ -453,7 +505,7 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:292 #: /var/www/html/Tinyboard/inc/display.php:408 #: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 -#: ../../../../inc/mod/pages.php:1239 +#: ../../../../inc/mod/pages.php:1239 ../../../../inc/mod/pages.php:1242 msgid "Edit post" msgstr "Edytuj post" @@ -485,12 +537,17 @@ msgstr "Zablokuj wątek" msgid "Move thread to another board" msgstr "Przenieś wątek na inny board" +#. line 11 +#. line 7 #. line 11 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:48 #: /var/www/html/Tinyboard/mod.php:667 /var/www/html/Tinyboard/mod.php:750 #: /var/www/html/Tinyboard/mod.php:833 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:55 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:55 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:31 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:36 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:33 msgid "Name" msgstr "Nazwa" @@ -501,11 +558,14 @@ msgstr "Nazwa" msgid "Email" msgstr "E-mail" +#. line 34 +#. line 23 #. line 34 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:96 #: /var/www/html/Tinyboard/mod.php:753 /var/www/html/Tinyboard/mod.php:839 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:95 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:116 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:63 msgid "Subject" msgstr "Temat" @@ -579,6 +639,7 @@ msgstr "Komentarz" #. line 73 #. line 61 #. line 73 +#. line 61 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:133 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:142 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:191 @@ -638,26 +699,35 @@ msgstr "Weryfikacja" #. line 87 #. line 3 #. line 87 +#. line 3 +#. line 72 +#. line 3 +#. line 72 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:22 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:22 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:250 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:214 msgid "File" msgstr "Plik" #. line 97 +#. line 82 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:163 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:183 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:268 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:232 msgid "Embed" msgstr "Osadź" #. line 109 +#. line 94 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:179 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:206 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:291 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:255 msgid "Flags" msgstr "Flagi" @@ -713,12 +783,18 @@ msgstr "Flagi" #. line 114 #. line 113 #. line 114 +#. line 98 +#. line 99 +#. line 98 +#. line 99 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:218 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:300 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:303 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:264 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:267 msgid "Sticky" msgstr "Przyklejony" @@ -774,12 +850,18 @@ msgstr "Przyklejony" #. line 118 #. line 117 #. line 118 +#. line 102 +#. line 103 +#. line 102 +#. line 103 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:230 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:312 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:315 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:276 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:279 msgid "Lock" msgstr "Zablokowany" @@ -835,18 +917,25 @@ msgstr "Zablokowany" #. line 122 #. line 121 #. line 122 +#. line 106 +#. line 107 +#. line 106 +#. line 107 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:242 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:324 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:327 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:288 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:291 msgid "Raw HTML" msgstr "Czysty HTML" #. line 129 #. line 14 #. line 129 +#. line 114 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:230 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:23 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:257 @@ -854,13 +943,16 @@ msgstr "Czysty HTML" #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:23 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:342 #: ../../../../templates/cache/04/54/656aa217f895c90eae78024fa060.php:41 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:306 msgid "Password" msgstr "Hasło" #. line 134 +#. line 119 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:236 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:266 #: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:351 +#: ../../../../templates/cache/0c/37/9331df01df7c2986d77a02d3beb0.php:315 msgid "(For file deletion.)" msgstr "(do usuwania postów)" @@ -887,6 +979,7 @@ msgstr "Odśwież" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:415 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:461 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:472 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:506 msgid "Reply" msgstr "Odpowiedź" @@ -894,6 +987,7 @@ msgstr "Odpowiedź" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:442 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:488 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:499 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:533 msgid "1 post" msgid_plural "%count% posts" msgstr[0] "1 post" @@ -905,6 +999,7 @@ msgstr[2] "%count% postów" #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:494 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 #: ../../../../templates/cache/e5/22/4711dd22e4c786b4de405db7a449.php:114 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:539 msgid "and" msgstr "oraz" @@ -912,6 +1007,7 @@ msgstr "oraz" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:459 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:505 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:516 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:550 msgid "1 image reply" msgid_plural "%count% image replies" msgstr[0] "1 obrazek" @@ -922,6 +1018,7 @@ msgstr[2] "%count% obrazków" #: ../../../../templates/cache/cf/0c/61af144f478f5c035cb3a2799e48.php:464 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:510 #: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:521 +#: ../../../../templates/cache/d8/f2/7780eb1adcdbda7e332659e3fb4f.php:555 msgid "omitted. Click reply to view." msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." @@ -935,15 +1032,19 @@ msgstr "pominięte. Kliknij Odpowiedź aby zobaczyć." #: ../../../../templates/cache/62/8c/21348d46377c3e1b3f8c476ba376.php:62 #: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:131 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:115 +#: ../../../../templates/cache/f5/e3/343716327c6183713f70a3fb57f1.php:132 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:116 msgid "Return to dashboard" msgstr "Powróć na tablicę" #. line 27 #. line 31 +#. line 32 #: /var/www/html/Tinyboard/templates/cache/0b/22/d0c24fb343dd5fe77600d77dcc1b.php:165 #: ../../../../templates/cache/82/20/1c3352a2eb8f4503c0f7634bca15.php:177 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:106 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:123 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:124 msgid "Posting mode: Reply" msgstr "Tryb postowania: Odpowiedź" @@ -955,6 +1056,8 @@ msgstr "Tryb postowania: Odpowiedź" #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:155 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:126 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:172 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:127 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:173 msgid "Return" msgstr "Powrót" @@ -970,6 +1073,12 @@ msgstr "Usuń post" #. line 8 #. line 32 #. line 48 +#. line 106 +#. line 8 +#. line 32 +#. line 106 +#. line 8 +#. line 32 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 @@ -990,6 +1099,8 @@ msgstr "Zgłoszenie" #: /var/www/html/Tinyboard/mod.php:104 /var/www/html/Tinyboard/mod.php:776 #: /var/www/html/Tinyboard/mod.php:862 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:120 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:125 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:89 msgid "no subject" msgstr "brak tematu" @@ -1012,6 +1123,7 @@ msgstr "Aktualności" #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 #: ../../../../inc/mod/pages.php:1682 ../../../../inc/mod/pages.php:1816 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 +#: ../../../../inc/mod/pages.php:1831 msgid "Report queue" msgstr "Kolejka zgłoszeń" @@ -1026,6 +1138,7 @@ msgstr "Lista banów" #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 #: ../../../../inc/mod/pages.php:1394 ../../../../inc/mod/pages.php:1528 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 +#: ../../../../inc/mod/pages.php:1543 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -1059,11 +1172,13 @@ msgstr "Pokaż konfigurację" #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 #: ../../../../inc/mod/pages.php:1830 ../../../../inc/mod/pages.php:1964 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 +#: ../../../../inc/mod/pages.php:1979 msgid "Manage themes" msgstr "Zarządzaj dodatkami" #. line 2 #. line 5 +#. line 2 #: /var/www/html/Tinyboard/mod.php:170 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:19 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:24 @@ -1074,11 +1189,14 @@ msgstr "Wyrażenie:" #. line 2 #. line 106 #. line 2 +#. line 16 +#. line 106 #: /var/www/html/Tinyboard/mod.php:172 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:72 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:19 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:286 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:19 +#: ../../../../search.php:165 msgid "Search" msgstr "Szukaj" @@ -1097,8 +1215,10 @@ msgid "Could not find current version! (Check .installed)" msgstr "Nie można znaleźć obecnej wersji! (Sprawdź .installed)" #. line 146 +#. line 158 #: /var/www/html/Tinyboard/mod.php:233 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:364 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:397 msgid "Logout" msgstr "Wyloguj" @@ -1128,17 +1248,25 @@ msgstr "temu" #. line 65 #. line 49 #. line 136 +#. line 116 +#. line 182 +#. line 65 +#. line 116 +#. line 182 +#. line 65 #: /var/www/html/Tinyboard/mod.php:405 /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:278 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:427 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:142 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:131 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:355 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:147 msgid "Board" msgstr "Board" #. line 183 #. line 137 +#. line 183 #: /var/www/html/Tinyboard/mod.php:406 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:430 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:358 @@ -1147,42 +1275,54 @@ msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 #: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 -#: ../../../../inc/mod/pages.php:1948 +#: ../../../../inc/mod/pages.php:1948 ../../../../inc/mod/pages.php:1963 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 #: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 -#: ../../../../inc/mod/pages.php:1950 +#: ../../../../inc/mod/pages.php:1950 ../../../../inc/mod/pages.php:1965 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." +#. line 11 #: /var/www/html/Tinyboard/mod.php:671 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:42 msgid "Version" msgstr "Wersja" +#. line 15 #: /var/www/html/Tinyboard/mod.php:675 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:51 msgid "Description" msgstr "Opis" +#. line 19 #: /var/www/html/Tinyboard/mod.php:679 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:60 msgid "Thumbnail" msgstr "Miniatura" +#. line 25 #: /var/www/html/Tinyboard/mod.php:687 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:86 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:77 msgid "Actions" msgstr "Akcje" +#. line 27 #: /var/www/html/Tinyboard/mod.php:689 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:81 msgid "Use theme" msgstr "Użyj dodatku" #: /var/www/html/Tinyboard/mod.php:690 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:87 msgid "Reconfigure" msgstr "Rekonfiguruj" #: /var/www/html/Tinyboard/mod.php:690 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:88 msgid "Install" msgstr "Instaluj" @@ -1192,10 +1332,13 @@ msgstr "Instaluj" #: ../../../../inc/mod/pages.php:1596 ../../../../inc/mod/pages.php:1726 #: ../../../../inc/mod/pages.php:1730 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 +#: ../../../../inc/mod/pages.php:1741 ../../../../inc/mod/pages.php:1745 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:98 msgid "Rebuild" msgstr "Przebuduj" #: /var/www/html/Tinyboard/mod.php:694 +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:103 msgid "Uninstall" msgstr "Odinstaluj" @@ -1203,7 +1346,9 @@ msgstr "Odinstaluj" msgid "Uninstall all themes." msgstr "Odinstaluj wszystkie dodatki" +#. line 27 #: /var/www/html/Tinyboard/mod.php:756 /var/www/html/Tinyboard/mod.php:842 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:69 msgid "Body" msgstr "Zawartość" @@ -1269,6 +1414,7 @@ msgstr "Nie można się ponownie zalogować po zmianie hasła. (?)" #. line 126 #. line 50 +#. line 126 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:300 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:134 @@ -1277,6 +1423,7 @@ msgstr "Ustawione" #. line 130 #. line 52 +#. line 130 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:309 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:140 @@ -1290,6 +1437,14 @@ msgstr "Wygasa" #. line 17 #. line 54 #. line 133 +#. line 24 +#. line 62 +#. line 150 +#. line 180 +#. line 24 +#. line 62 +#. line 150 +#. line 180 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:74 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:169 @@ -1328,7 +1483,7 @@ msgid "No board to move to; there is only one." msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." #: ../../../../inc/config.php:689 ../../../../inc/config.php:747 -#: ../../../../inc/config.php:753 +#: ../../../../inc/config.php:753 ../../../../inc/config.php:750 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." @@ -1346,6 +1501,10 @@ msgstr "Edytuj board" msgid "New board" msgstr "Nowy board" +#. line 102 +#. line 20 +#. line 102 +#. line 20 #. line 102 #. line 20 #: ../../../../inc/mod/pages.php:586 ../../../../inc/mod/pages.php:612 @@ -1361,6 +1520,7 @@ msgstr "adres IP" #: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 #: ../../../../inc/mod/pages.php:772 ../../../../inc/mod/pages.php:1187 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:398 +#: ../../../../inc/mod/pages.php:1190 msgid "New ban" msgstr "Nowy ban" @@ -1380,6 +1540,7 @@ msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1307 ../../../../inc/mod/pages.php:1356 #: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 #: ../../../../inc/mod/pages.php:1466 ../../../../inc/mod/pages.php:1515 +#: ../../../../inc/mod/pages.php:1477 ../../../../inc/mod/pages.php:1530 msgid "Edit user" msgstr "Edytuj użytkownika" @@ -1388,11 +1549,13 @@ msgstr "Edytuj użytkownika" #: ../../../../inc/mod/pages.php:1431 ../../../../inc/mod/pages.php:1503 #: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 #: ../../../../inc/mod/pages.php:1590 ../../../../inc/mod/pages.php:1662 +#: ../../../../inc/mod/pages.php:1605 ../../../../inc/mod/pages.php:1677 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 #: ../../../../inc/mod/pages.php:1460 ../../../../inc/mod/pages.php:1594 +#: ../../../../inc/mod/pages.php:1609 msgid "Private message" msgstr "Prywatna wiadomość" @@ -1400,33 +1563,39 @@ msgstr "Prywatna wiadomość" #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 #: ../../../../inc/mod/pages.php:1481 ../../../../inc/mod/pages.php:1615 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 +#: ../../../../inc/mod/pages.php:1630 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 #: ../../../../inc/mod/pages.php:1804 ../../../../inc/mod/pages.php:1938 +#: ../../../../inc/mod/pages.php:1953 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 #: ../../../../inc/mod/pages.php:1970 ../../../../inc/mod/pages.php:2104 +#: ../../../../inc/mod/pages.php:2119 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 #: ../../../../inc/mod/pages.php:1892 ../../../../inc/mod/pages.php:2026 +#: ../../../../inc/mod/pages.php:2041 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 #: ../../../../inc/mod/pages.php:1903 ../../../../inc/mod/pages.php:2037 +#: ../../../../inc/mod/pages.php:2052 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 #: ../../../../inc/mod/pages.php:1931 ../../../../inc/mod/pages.php:2065 +#: ../../../../inc/mod/pages.php:2080 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1438,20 +1607,24 @@ msgid "" msgstr "" #: ../../../../inc/config.php:704 ../../../../inc/config.php:710 +#: ../../../../inc/config.php:707 msgid "Thread has reached its maximum reply limit." msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." #: ../../../../inc/config.php:705 ../../../../inc/config.php:711 +#: ../../../../inc/config.php:708 msgid "Thread has reached its maximum image limit." msgstr "Ten temat osiągnął swój maksymalny limit obrazków." #: ../../../../inc/config.php:726 ../../../../inc/config.php:732 +#: ../../../../inc/config.php:729 #, php-format msgid "That file already exists in this thread!" msgstr "Ten plik już istnieje w tym temacie!" #. Moderator errors #: ../../../../inc/config.php:733 ../../../../inc/config.php:739 +#: ../../../../inc/config.php:736 #, php-format msgid "" "You are only allowed to unban %s users at a time. You tried to unban %u " @@ -1460,12 +1633,12 @@ msgstr "" "Możesz odbanować tylko %s użytkowników na raz. Próbowałeś odbanować %u users." #: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 -#: ../../../../inc/mod/pages.php:2128 +#: ../../../../inc/mod/pages.php:2128 ../../../../inc/mod/pages.php:2143 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" #: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 -#: ../../../../inc/mod/pages.php:2152 +#: ../../../../inc/mod/pages.php:2152 ../../../../inc/mod/pages.php:2167 msgid "Debug: SQL" msgstr "Debug: SQL" @@ -1500,9 +1673,9 @@ msgid "" "(Search is case-insensitive and based on keywords. To match exact phrases, " "use \"quotes\". Use an asterisk (*) for wildcard.)" msgstr "" -"(Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " -"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " -"wieloznacznego.)" +"(Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach " +"kluczowych. Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki " +"(*) jako symbolu wieloznacznego.)" #. line 8 #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:32 @@ -1520,14 +1693,14 @@ msgid "" "example, name:Anonymous or subject:\"Some Thread\". " "Wildcards cannot be used in filters." msgstr "" -"Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach kluczowych. " -"Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki (*) jako symbolu " -"wieloznacznego.

Możesz zastosować poniższe " -"filtry do swojego wyszukiwania: id, thread, " -"subject, i name. Aby wykorzystać filtr, " -"po prostu dodaj do swojego zapytania, na przykład: name:Anonymous " -"albo subject:\"Jakiś temat\". Symbole wieloznaczne nie mogą być " -"wykorzystane w filtrach." +"Wyszukiwanie jest niezależne od wielkości znaków i bazowane na słowach " +"kluczowych. Aby dopasować pełne frazy, użyj \"cudzysłowi\". Użyj gwiazdki " +"(*) jako symbolu wieloznacznego.

Możesz zastosować poniższe filtry do swojego wyszukiwania: id, thread, subject, i name. Aby wykorzystać filtr, po prostu dodaj do swojego zapytania, na " +"przykład: name:Anonymous albo subject:\"Jakiś temat\". " +"Symbole wieloznaczne nie mogą być wykorzystane w filtrach." #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:57 msgid "edit" @@ -1552,32 +1725,45 @@ msgid "Change password" msgstr "Zmień hasło" #. line 118 +#. line 130 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:308 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:341 msgid "Debug" msgstr "Debug" #. line 120 +#. line 132 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:312 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:345 msgid "Anti-spam" msgstr "Antyspam" #. line 121 +#. line 133 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:315 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:348 msgid "Recent posts" msgstr "Ostatnie posty" #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:321 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:354 msgid "SQL" msgstr "SQL" #. line 143 +#. line 155 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:359 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:392 msgid "User account" msgstr "Konto użytkownika" #. line 25 #. line 67 #. line 18 +#. line 25 +#. line 67 +#. line 25 +#. line 67 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:77 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:179 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:54 @@ -1586,6 +1772,7 @@ msgstr "Notka" #. line 26 #. line 19 +#. line 26 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:80 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:57 msgid "Date" @@ -1634,6 +1821,7 @@ msgstr "nigdy" #. line 140 #. line 53 +#. line 140 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:331 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:143 msgid "Seen" @@ -1656,6 +1844,7 @@ msgstr "Usuń ban" #. line 181 #. line 135 +#. line 181 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:424 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:352 msgid "Time" @@ -1753,16 +1942,19 @@ msgstr "Wiadomość" #. line 46 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:117 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:122 msgid "public; attached to post" msgstr "publiczny; dołączony do posta" #. line 58 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:133 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:138 msgid "Length" msgstr "Długość" #. line 88 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:192 +#: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:197 msgid "New Ban" msgstr "Nowy ban" @@ -1799,3 +1991,109 @@ msgstr[2] "%d wyników na" #: ../../../../search.php:160 msgid "No results." msgstr "Brak wyników." + +#: ../../../../inc/functions.php:594 +msgid "Banned!" +msgstr "Zbanowany!" + +#: ../../../../banned.php:4 +msgid "Banned?" +msgstr "Zbanowany?" + +#: ../../../../banned.php:5 +msgid "You are not banned." +msgstr "Nie jesteś zbanowany." + +#: ../../../../inc/functions.php:549 ../../../../inc/functions.php:566 +msgid "second" +msgid_plural "seconds" +msgstr[0] "sekunda" +msgstr[1] "sekundy" +msgstr[2] "sekund" + +#: ../../../../inc/functions.php:551 ../../../../inc/functions.php:568 +msgid "minute" +msgid_plural "minutes" +msgstr[0] "minuta" +msgstr[1] "minuty" +msgstr[2] "minut" + +#: ../../../../inc/functions.php:553 ../../../../inc/functions.php:570 +msgid "hour" +msgid_plural "hours" +msgstr[0] "godzina" +msgstr[1] "godziny" +msgstr[2] "godzin" + +#: ../../../../inc/functions.php:555 ../../../../inc/functions.php:572 +msgid "day" +msgid_plural "days" +msgstr[0] "dzień" +msgstr[1] "dni" +msgstr[2] "dni" + +#: ../../../../inc/functions.php:557 ../../../../inc/functions.php:574 +msgid "week" +msgid_plural "weeks" +msgstr[0] "tydzień" +msgstr[1] "tygodnie" +msgstr[2] "tygodni" + +#: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 +msgid "year" +msgid_plural "years" +msgstr[0] "rok" +msgstr[1] "lata" +msgstr[2] "lat" + +#. line 118 +#: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:308 +msgid "Other" +msgstr "Inne" + +#: ../../../../templates/cache/b7/7d/de31d12a1684acbc7c0d7ee71653.php:30 +msgid "Successfully installed and built theme." +msgstr "Pomyślnie zainstalowano i zbudowano dodatek." + +#. line 9 +#: ../../../../templates/cache/b7/7d/de31d12a1684acbc7c0d7ee71653.php:37 +msgid "Go back to themes" +msgstr "Wróć do dodatków" + +#. line 3 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:21 +msgid "New post" +msgstr "Nowy post" + +#. line 32 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:76 +msgid "Post news entry" +msgstr "Zapostuj newsa" + +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:100 +msgid "delete" +msgstr "usuń" + +#. line 55 +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:133 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:94 +msgid "by" +msgstr "przez" + +#: ../../../../templates/cache/c8/8b/242bf87b3b6a29a67cdd09a3afeb.php:136 +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:97 +msgid "at" +msgstr "dnia" + +#: ../../../../templates/cache/f3/ad/68dee281a64ebad9a5c774b53279.php:66 +msgid "(No news to show.)" +msgstr "(Nie ma newsów do wyświetlenia.)" + +#: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:19 +msgid "There are no themes available." +msgstr "Nie ma dostępnych dodatków." + +#. line 25 +#: ../../../../templates/cache/d1/99/467985632043e204070d354b8290.php:91 +msgid "Install theme" +msgstr "Zainstaluj dodatek" From 7e0cec3d9dc0fbf3a1e13909de116ba12594302a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Sat, 22 Dec 2012 20:14:43 +0100 Subject: [PATCH 109/289] Facilitate styling of subboard listings --- inc/display.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/display.php b/inc/display.php index 0992166d..a2d50f74 100644 --- a/inc/display.php +++ b/inc/display.php @@ -25,7 +25,7 @@ function doBoardListPart($list, $root) { $body = ''; foreach ($list as $board) { if (is_array($board)) - $body .= ' [' . doBoardListPart($board, $root) . '] '; + $body .= ' [' . doBoardListPart($board, $root) . '] '; else { if (($key = array_search($board, $list)) && gettype($key) == 'string') { $body .= ' ' . $key . ' /'; From 701cf42eef17963fc57159e5383c020e76c0181f Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 2 Jul 2013 23:10:00 -0400 Subject: [PATCH 110/289] main.js: added preliminary translation functions for javascript --- templates/main.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) 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 = {}; From 61a305a1a27d414072b0de24441c07b1630c3075 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:04:08 -0400 Subject: [PATCH 111/289] 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(-) 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: From 123a72d7de692c8f33f6df39d0a8a7a267fe8b0b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 04:28:26 -0400 Subject: [PATCH 112/289] 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(-) 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 %} From 54714595f7ce2cdbd88de1c536e0ddc97ca71529 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:19:58 -0400 Subject: [PATCH 069/289] js/inline-expanding.js: Allow to work with auto-reload.js, etc. (jQuery is still optional) Conflicts: js/inline-expanding.js --- js/inline-expanding.js | 79 ++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/js/inline-expanding.js b/js/inline-expanding.js index 2e924f05..06d3f76f 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -6,49 +6,62 @@ * Copyright (c) 2012-2013 Michael Save * * Usage: + * // $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/inline-expanding.js'; * */ onready(function(){ - var link = document.getElementsByTagName('a'); + var inline_expand_post = function() { + var link = this.getElementsByTagName('a'); - for (var i = 0; i < link.length; i++) { - if (typeof link[i] == "object" && link[i].childNodes && link[i].childNodes[0].src && link[i].className != 'file') { - link[i].childNodes[0].style.maxWidth = '95%'; - link[i].childNodes[0].style.maxHeight = '95%'; - link[i].onclick = function(e) { - if (this.childNodes[0].className == 'hidden') - return false; - if (e.which == 2) - return true; - if (!this.dataset.src) { - this.dataset.expanded = 'true'; - this.dataset.src= this.childNodes[0].src; - this.dataset.width = this.childNodes[0].style.width; - this.dataset.height = this.childNodes[0].style.height; - this.childNodes[0].src = this.href; - this.childNodes[0].style.width = 'auto'; - this.childNodes[0].style.height = 'auto'; - this.childNodes[0].style.opacity = '0.4'; - this.childNodes[0].style.filter = 'alpha(opacity=40)'; - this.childNodes[0].onload = function() { - this.style.opacity = ''; - delete this.style.filter; + 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') { + link[i].childNodes[0].style.maxWidth = '95%'; + link[i].onclick = function(e) { + if (this.childNodes[0].className == 'hidden') + return false; + if (e.which == 2) + return true; + if (!this.dataset.src) { + this.dataset.expanded = 'true'; + this.dataset.src= this.childNodes[0].src; + this.dataset.width = this.childNodes[0].style.width; + this.dataset.height = this.childNodes[0].style.height; + this.childNodes[0].src = this.href; + this.childNodes[0].style.width = 'auto'; + this.childNodes[0].style.height = 'auto'; + this.childNodes[0].style.opacity = '0.4'; + this.childNodes[0].style.filter = 'alpha(opacity=40)'; + this.childNodes[0].onload = function() { + this.style.opacity = ''; + delete this.style.filter; + } + } else { + this.childNodes[0].src = this.dataset.src; + this.childNodes[0].style.width = this.dataset.width; + this.childNodes[0].style.height = this.dataset.height; + delete this.dataset.expanded; + delete this.dataset.src; + delete this.childNodes[0].style.opacity; + delete this.childNodes[0].style.filter; } - } else { - this.childNodes[0].src = this.dataset.src; - this.childNodes[0].style.width = this.dataset.width; - this.childNodes[0].style.height = this.dataset.height; - delete this.dataset.expanded; - delete this.dataset.src; - delete this.childNodes[0].style.opacity; - delete this.childNodes[0].style.filter; + return false; } - return false; } - } } + + if (window.jQuery) { + $('div[id^="thread_"]').each(inline_expand_post); + + // allow to work with auto-reload.js, etc. + $(document).bind('new_post', function(e, post) { + inline_expand_post.call(post); + }); + } else { + inline_expand_post.call(document); + } + }); From 461084d400620c32ef262aab1f837573f47b0951 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 16:41:10 -0400 Subject: [PATCH 070/289] MySQL's utf8 charset only supports up to 3-byte symbols. Insterting four byte symbols (U+010000 to U+10FFFF) can be done maliciously to break HTML mark-up. The ideal solution was to convert to MySQL's utf8mb4 charset, but then we would lose support for MySQL < 5.5.3. In this fix, incompatible characters are encoded as HTML numeric character references (eg. #65536) and just stripped from body_nommarkup. --- inc/functions.php | 2 +- post.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 2915e1b6..4af7891a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1523,7 +1523,7 @@ function markup(&$body, $track_cites = false) { } function utf8tohtml($utf8) { - return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); + return mb_encode_numericentity(htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'), array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); } function ordutf8($string, &$offset) { diff --git a/post.php b/post.php index ad045b66..e9041ce8 100644 --- a/post.php +++ b/post.php @@ -378,7 +378,7 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); - $post['body_nomarkup'] = $post['body']; + $post['body_nomarkup'] = preg_replace('/[\x{010000}-\x{ffffff}]/u', '', $post['body']); if (!($mod && isset($post['raw']) && $post['raw'])) $post['tracked_cites'] = markup($post['body'], true); From 91bb3182da63e64d45ab8ac26735e090db928f15 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 19:07:28 -0400 Subject: [PATCH 071/289] =?UTF-8?q?=E2=8C=98+click=20should=20open=20image?= =?UTF-8?q?=20in=20new=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/inline-expanding.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/inline-expanding.js b/js/inline-expanding.js index 06d3f76f..20383f04 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -21,7 +21,7 @@ onready(function(){ link[i].onclick = function(e) { if (this.childNodes[0].className == 'hidden') return false; - if (e.which == 2) + if (e.which == 2 || e.metaKey) return true; if (!this.dataset.src) { this.dataset.expanded = 'true'; From 8efab06616bfcdab49fb9e996cdc7ddfe79426bb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 22:08:56 -0400 Subject: [PATCH 072/289] 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(-) 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 From fbc78f76323528cab0d23fa259de984b8b9db457 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 22:13:05 -0400 Subject: [PATCH 073/289] Fix last commit (mysql_version() doesn't work if connection is not yet established) --- install.php | 1 + 1 file changed, 1 insertion(+) diff --git a/install.php b/install.php index c2fe1a55..1f148e92 100644 --- a/install.php +++ b/install.php @@ -249,6 +249,7 @@ if (file_exists($config['has_installed'])) { } } case 'v0.9.6-dev-9': + sql_open(); function __query($sql) { if (mysql_version() >= 50503) return query($sql); From 343397d561183a72ed3a6351175b0d34ebe9ffc3 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 23:30:49 -0400 Subject: [PATCH 074/289] ?/IP/: Don't show posts for board user doesn't have access to --- inc/mod/pages.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index d447fa51..fdf9d8e9 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -744,6 +744,8 @@ function mod_page_ip($ip) { $boards = listBoards(); foreach ($boards as $board) { 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->bindValue(':ip', $ip); From 889945f50cd0c2cd1b8f39d7b380133196a93a74 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 30 Jul 2013 23:36:46 -0400 Subject: [PATCH 075/289] 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(-) 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 %} From bb2868896c2f383a913e8e5929627660cc754b14 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 00:04:57 -0400 Subject: [PATCH 076/289] Ability to hide IP addresses from mod log --- inc/config.php | 2 ++ templates/mod/log.html | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) 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 }} From 42d29657a4fd9cba4ce3db6912dd3696b4a5f83e Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 00:29:49 -0400 Subject: [PATCH 077/289] README update --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 50dcc621..7bd6f461 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,21 @@ license. It is written in PHP and has few dependencies. Requirements ------------ 1. PHP >= 5.2.5 -2. [mbstring](http://www.php.net/manual/en/mbstring.installation.php) - (--enable-mbstring) -3. [PHP-GD](http://php.net/manual/en/book.image.php) -4. [PHP-PDO](http://php.net/manual/en/book.pdo.php) - (only MySQL is supported at the moment) +2. MySQL server +3. [mbstring](http://www.php.net/manual/en/mbstring.installation.php) +4. [PHP GD](http://www.php.net/manual/en/intro.image.php) +5. [PHP PDO](http://www.php.net/manual/en/intro.pdo.php) We try to make sure Tinyboard is compatible with all major web servers and operating systems. Tinyboard does not include an Apache ```.htaccess``` file nor does it need one. +### Recommended +1. PHP >= 5.3 +2. MySQL server >= 5.5.3 +3. ImageMagick or command-line version (```convert``` and ```identify```) +4. [APC (Alternative PHP Cache)](http://php.net/manual/en/book.apc.php), [XCache](http://xcache.lighttpd.net/) or [Memcached](http://www.php.net/manual/en/intro.memcached.php) + Contributing ------------ You can contribute to Tinyboard by: @@ -58,7 +63,7 @@ find support from a variety of sources: * Documentation can be found [here](http://tinyboard.org/docs/). * You can join Tinyboard's IRC channel for support and general queries: [irc.datnode.net #tinyboard](irc://irc.datnode.net/tinyboard). -* You can find enterprise-grade support at [tinyboard.org](http://tinyboard.org/#support). +* You may find help at [tinyboard.org](http://tinyboard.org/#help). License -------- From 3bee1ba4fd16263ac4eefdf0bc8c7a3d11d8cccb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 00:39:00 -0400 Subject: [PATCH 078/289] Issue #61 --- js/expand.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/js/expand.js b/js/expand.js index 16a0efb2..6e5fa659 100644 --- a/js/expand.js +++ b/js/expand.js @@ -1,9 +1,9 @@ /* - *expand.js + * expand.js * https://github.com/savetheinternet/Tinyboard/blob/master/js/expand.js * * Released under the MIT license - * Copyright (c) 2012 Michael Save + * Copyright (c) 2012-2013 Michael Save * * Usage: * $config['additional_javascript'][] = 'js/jquery.min.js'; @@ -35,9 +35,8 @@ $(document).ready(function(){ $(this).addClass('expanded').insertAfter(thread.find('div.post:first')).after('
'); } last_expanded = $(this); - - } - else { + $(document).trigger('new_post', this); + } else { last_expanded = post_in_doc; } }); From 42cba538878cb695ba8b3093f72bc66ccd2fa074 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 02:08:55 -0400 Subject: [PATCH 079/289] Allow Unicode in board URIs. --- inc/config.php | 3 +++ inc/display.php | 6 +++--- inc/functions.php | 8 ++++---- inc/mod/pages.php | 9 ++++----- install.php | 23 ++++++++++++++++++----- install.sql | 22 +++++++++++----------- mod.php | 33 +++++++++++++++++---------------- post.php | 6 +++--- 8 files changed, 63 insertions(+), 47 deletions(-) diff --git a/inc/config.php b/inc/config.php index 28a7a4db..36518028 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1130,6 +1130,9 @@ // 'type' => 'scp' //); + // Regex for board URIs + $config['board_regex'] = '[0-9a-zA-Z$_\x{0080}-\x{FFFF}]{1,58}'; + // 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 a7e4826e..0992166d 100644 --- a/inc/display.php +++ b/inc/display.php @@ -235,7 +235,7 @@ function bidi_cleanup($str){ function secure_link_confirm($text, $title, $confirm_message, $href) { global $config; - return '' . $text . ''; + return '' . $text . ''; } function secure_link($href) { return $href . '/' . make_secure_link_token($href); @@ -299,7 +299,7 @@ class Post { // Fix internal links // Very complicated regex $this->body = preg_replace( - '/ ':?/', // redirect to dashboard @@ -45,7 +45,7 @@ $pages = array( '/news/(\d+)' => 'news', // view news '/news/delete/(\d+)' => 'news_delete', // delete from news - '/edit/(\w+)' => 'edit_board', // edit board details + '/edit/(\%b)' => 'edit_board', // edit board details '/new-board' => 'new_board', // create a new board '/rebuild' => 'rebuild', // rebuild static files @@ -63,15 +63,15 @@ $pages = array( // CSRF-protected moderator actions '/ban' => 'secure_POST ban', // new ban - '/(\w+)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster - '/(\w+)/move/(\d+)' => 'secure_POST move', // move thread - '/(\w+)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post - '/(\w+)/delete/(\d+)' => 'secure delete', // delete post - '/(\w+)/deletefile/(\d+)' => 'secure deletefile', // delete file from post - '/(\w+)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address - '/(\w+)/(un)?lock/(\d+)' => 'secure lock', // lock thread - '/(\w+)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread - '/(\w+)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread + '/(\%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)/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 '/themes' => 'themes_list', // manage themes '/themes/(\w+)' => 'theme_configure', // configure/reconfigure theme @@ -86,10 +86,10 @@ $pages = array( '/debug/sql' => 'secure_POST debug_sql', // This should always be at the end: - '/(\w+)/' => 'view_board', - '/(\w+)/' . preg_quote($config['file_index'], '!') => 'view_board', - '/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', - '/(\w+)/' . preg_quote($config['dir']['res'], '!') . + '/(\%b)/' => 'view_board', + '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board', + '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', + '/(\%b)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread', ); @@ -109,7 +109,8 @@ $new_pages = array(); foreach ($pages as $key => $callback) { if (is_string($callback) && preg_match('/^secure /', $callback)) $key .= '(/(?P[a-f0-9]{8}))?'; - $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!'] = $callback; + $key = str_replace('\%b', $config['board_regex'], $key); + $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback; } $pages = $new_pages; diff --git a/post.php b/post.php index d1749fd1..85dc2d05 100644 --- a/post.php +++ b/post.php @@ -170,7 +170,7 @@ if (isset($_POST['delete'])) { error($config['error']['bot']); // Check the referrer - if (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], $_SERVER['HTTP_REFERER'])) + if (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], urldecode($_SERVER['HTTP_REFERER']))) error($config['error']['referer']); checkDNSBL(); @@ -547,9 +547,9 @@ if (isset($_POST['delete'])) { // Remove board directories before inserting them into the database. if ($post['has_file']) { $post['file_path'] = $post['file']; - $post['file'] = substr_replace($post['file'], '', 0, mb_strlen($board['dir'] . $config['dir']['img'])); + $post['file'] = mb_substr($post['file'], mb_strlen($board['dir'] . $config['dir']['img'])); if ($is_an_image && $post['thumb'] != 'spoiler') - $post['thumb'] = substr_replace($post['thumb'], '', 0, mb_strlen($board['dir'] . $config['dir']['thumb'])); + $post['thumb'] = mb_substr($post['thumb'], mb_strlen($board['dir'] . $config['dir']['thumb'])); } $post = (object)$post; From b22bcdecf9cce8b08c48283290173996b6c8abf2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 02:19:58 -0400 Subject: [PATCH 080/289] Fix last commit: purge() issue --- inc/functions.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/inc/functions.php b/inc/functions.php index 6db21c54..773f8eb6 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -366,6 +366,11 @@ function boardTitle($uri) { function purge($uri) { global $config, $debug; + // Fix for Unicode + $uri = urlencode($uri); + $uri = str_replace("%2F", "/", $uri); + $uri = str_replace("%3A", ":", $uri); + if (preg_match($config['referer_match'], $config['root']) && isset($_SERVER['REQUEST_URI'])) { $uri = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/') . $uri; } else { From 90b82b1a0635d78d536bc92decbdc273d8f7e323 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 02:38:40 -0400 Subject: [PATCH 081/289] Disable autocomplete --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() }} From 37d769646b7754f37928f9ceb8b0a2a9eea58c6b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:12:06 -0400 Subject: [PATCH 082/289] Markup/quote fix for multibyte --- inc/functions.php | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 773f8eb6..2d648df8 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -297,6 +297,10 @@ function sprintf3($str, $vars, $delim = '%') { array_values($replaces), $str); } +function mb_substr_replace($string, $replacement, $start, $length) { + return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length); +} + function setupBoard($array) { global $board, $config; @@ -1451,6 +1455,7 @@ function markup(&$body, $track_cites = false) { } $skip_chars = 0; + $body_tmp = $body; foreach ($cites as $matches) { $cite = $matches[2][0]; @@ -1458,20 +1463,26 @@ function markup(&$body, $track_cites = false) { $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); + // preg_replace is not multibyte-safe + foreach ($matches as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + if ($post = $query->fetch()) { $replacement = '' . '>>' . $cite . ''; - $body = substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); - $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); + if ($track_cites && $config['track_cites']) $tracked_cites[] = array($board['uri'], $post['id']); } } } - + // Cross-board linking if (preg_match_all('/(^|\s)>>>\/(' . $config['board_regex'] . 'f?)\/(\d+)?([\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { @@ -1479,11 +1490,17 @@ function markup(&$body, $track_cites = false) { } $skip_chars = 0; + $body_tmp = $body; foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; + // preg_replace is not multibyte-safe + foreach ($matches as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + // Temporarily store board information because it will be overwritten $tmp_board = $board['uri']; @@ -1499,7 +1516,8 @@ function markup(&$body, $track_cites = false) { $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread']?$post['thread']:$post['id']) . '.html#' . $cite . '">' . '>>>/' . $_board . '/' . $cite . ''; - $body = substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) @@ -1510,7 +1528,7 @@ function markup(&$body, $track_cites = false) { $config['root'] . $board['dir'] . $config['file_index'] . '">' . '>>>/' . $_board . '/' . ''; - $body = substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } From a2d8e4cf3efd97765405e4d51ecdc279b227072b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:13:51 -0400 Subject: [PATCH 083/289] Previous commit comment fix --- inc/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 2d648df8..15037847 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1463,7 +1463,7 @@ function markup(&$body, $track_cites = false) { $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); - // preg_replace is not multibyte-safe + // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } @@ -1496,7 +1496,7 @@ function markup(&$body, $track_cites = false) { $_board = $matches[2][0]; $cite = @$matches[3][0]; - // preg_replace is not multibyte-safe + // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } From f9cdf31ede3bab1aff1ffa5a043bfd9a6eceb6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Sat, 22 Dec 2012 20:16:31 +0100 Subject: [PATCH 084/289] Fix animated .gif conversion when $config['thumb_ext'] == '' --- inc/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/image.php b/inc/image.php index eb98ceda..f0909b8c 100644 --- a/inc/image.php +++ b/inc/image.php @@ -186,7 +186,7 @@ class ImageImagick extends ImageBase { public function resize() { global $config; - if ($this->format == 'gif' && $config['thumb_ext'] == 'gif') { + if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '')) { $this->image = new Imagick(); $this->image->setFormat('gif'); @@ -274,7 +274,7 @@ class ImageConvert extends ImageBase { $quality = $config['thumb_quality'] * 10; - if ($this->format == 'gif' && $config['thumb_ext'] == 'gif' && $config['thumb_keep_animation_frames'] > 1) { + if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if (shell_exec("convert -background transparent -filter Point -sample {$this->width}x{$this->height} +antialias -quality {$quality} " . escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); From b7e725bf3e0394193dee9373c18dec7f727ea6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Mon, 24 Dec 2012 05:34:06 +0100 Subject: [PATCH 085/289] Support for resizing gifs using gifsicle with resizing the rest using ImageMagick --- inc/config.php | 15 ++++++++++----- inc/image.php | 28 ++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/inc/config.php b/inc/config.php index 36518028..863b9043 100644 --- a/inc/config.php +++ b/inc/config.php @@ -413,11 +413,16 @@ $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. + // - '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. + $config['thumb_method'] = 'gd'; // Strip EXIF metadata from JPEG files diff --git a/inc/image.php b/inc/image.php index f0909b8c..e4738953 100644 --- a/inc/image.php +++ b/inc/image.php @@ -16,10 +16,10 @@ class Image { $this->src = $src; $this->format = $format; - + if ($config['thumb_method'] == 'imagick') { $classname = 'ImageImagick'; - } elseif ($config['thumb_method'] == 'convert') { + } elseif ($config['thumb_method'] == 'convert' || $config['thumb_method'] == 'convert+gifsicle') { $classname = 'ImageConvert'; } else { $classname = 'Image' . strtoupper($this->format); @@ -29,6 +29,7 @@ class Image { } $this->image = new $classname($this); + if (!$this->image->valid()) { $this->delete(); error($config['error']['invalidimg']); @@ -44,10 +45,15 @@ class Image { public function resize($extension, $max_width, $max_height) { global $config; + $gifsicle = false; + if ($config['thumb_method'] == 'imagick') { $classname = 'ImageImagick'; } elseif ($config['thumb_method'] == 'convert') { $classname = 'ImageConvert'; + } elseif ($config['thumb_method'] == 'convert+gifsicle') { + $classname = 'ImageConvert'; + $gifsicle = true; } else { $classname = 'Image' . strtoupper($extension); if (!class_exists($classname)) { @@ -75,6 +81,9 @@ class Image { $height = $max_height; } + if ($gifsicle) { + $thumb->gifsicle = 1; + } $thumb->_resize($this->image->image, $width, $height); return $thumb; @@ -219,7 +228,7 @@ class ImageImagick extends ImageBase { class ImageConvert extends ImageBase { - public $width, $height, $temp; + public $width, $height, $temp, $gifsicle; public function init() { global $config; @@ -275,9 +284,16 @@ class ImageConvert extends ImageBase { $quality = $config['thumb_quality'] * 10; if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { - if (shell_exec("convert -background transparent -filter Point -sample {$this->width}x{$this->height} +antialias -quality {$quality} " . - escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) - error('Failed to resize image!'); + if ($this->gifsicle) { + if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} " . + escapeshellarg($this->src . '') . " " . 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} " . + 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} " . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) From 73cb2bdf2c429fc302156b5853a409ff3cdc09b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Mon, 24 Dec 2012 05:42:53 +0100 Subject: [PATCH 086/289] convert+gifsicle: fix previous commit --- inc/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/image.php b/inc/image.php index e4738953..7aea9bfe 100644 --- a/inc/image.php +++ b/inc/image.php @@ -285,8 +285,8 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { - if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} " . - escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) + if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . + escapeshellarg($this->src . '') . " > " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); } else { From 573f86ccaee3b206ebacdb4c695ea2841d68f8f9 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:35:07 -0400 Subject: [PATCH 087/289] Tiny code clean-up --- inc/image.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/inc/image.php b/inc/image.php index 7aea9bfe..99c10252 100644 --- a/inc/image.php +++ b/inc/image.php @@ -81,9 +81,7 @@ class Image { $height = $max_height; } - if ($gifsicle) { - $thumb->gifsicle = 1; - } + $thumb->gifsicle = $gifsicle; $thumb->_resize($this->image->image, $width, $height); return $thumb; @@ -288,8 +286,7 @@ class ImageConvert extends ImageBase { if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " > " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); - } - else { + } else { if (shell_exec("convert -background transparent -filter Point -sample {$this->width}x{$this->height} +antialias -quality {$quality} " . escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); From 44d3b12cefce4e6e2e5c6e367e8443790f38bf57 Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sat, 5 Jan 2013 13:45:21 +0100 Subject: [PATCH 088/289] Embedding: added vocaroo support --- inc/config.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/config.php b/inc/config.php index 863b9043..e2cd79f1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -663,6 +663,10 @@ array( '/^https?:\/\/video\.google\.com\/videoplay\?docid=(\d+)([&#](.+)?)?$/i', '' + ), + array( + '/^https?:\/\/(\w+\.)?vocaroo\.com\/i\/([a-zA-Z0-9]{2,15})$/i', + '' ) ); From 220609999a78fedce1459df5e89c40b2bd1f7d90 Mon Sep 17 00:00:00 2001 From: szalej Date: Wed, 16 Jan 2013 10:50:20 +0100 Subject: [PATCH 089/289] Update inc/functions.php Hide Referrer (nullrefer.com) --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 15037847..bc58b117 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1385,7 +1385,7 @@ function markup_url($matches) { $markup_urls[] = $url; - return '' . $url . '' . $after; + return '' . $url . '' . $after; } function unicodify($body) { From 5bf53cb581e8e9598405cd1d8531c2672417d32e Mon Sep 17 00:00:00 2001 From: szalej Date: Wed, 16 Jan 2013 11:34:31 +0100 Subject: [PATCH 090/289] Update inc/functions.php url ads --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index bc58b117..8bae66d3 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1385,7 +1385,7 @@ function markup_url($matches) { $markup_urls[] = $url; - return '' . $url . '' . $after; + return '' . $url . '' . $after; } function unicodify($body) { From 3ef2c05bb20d5fc7de528676e8a7c02bfd9135fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Wed, 16 Jan 2013 19:49:26 +0100 Subject: [PATCH 091/289] url_ads: fix it not working --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 8bae66d3..5d3a5757 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1378,7 +1378,7 @@ function quote($body, $quote=true) { } function markup_url($matches) { - global $markup_urls; + global $config, $markup_urls; $url = $matches[1]; $after = $matches[2]; From 51efd817c8e82a498dbdd603d1194a0dd43f7192 Mon Sep 17 00:00:00 2001 From: szalej Date: Wed, 16 Jan 2013 11:32:15 +0100 Subject: [PATCH 092/289] Update inc/config.php hide referrer option --- inc/config.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/inc/config.php b/inc/config.php index e2cd79f1..cf55d149 100644 --- a/inc/config.php +++ b/inc/config.php @@ -335,6 +335,11 @@ $config['auto_unicode'] = true; // Whether to turn URLs into functional links $config['markup_urls'] = true; + $config['url_ads'] = ''; + // Use it if you want to add something before URL + //for example hide referrer 'http://www.nullrefer.com/?' 'http://anonym.to/?' + //or add some sort of ads + // Wordfilters are used to automatically replace certain words/phrases with something else. // For a normal string replacement: From 18516ff8289cc4e0c147f185d29824643b1f960d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:43:01 -0400 Subject: [PATCH 093/289] Rename $config['url_ads'] to $config['link_prefix'] --- inc/config.php | 6 ++---- inc/functions.php | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/inc/config.php b/inc/config.php index cf55d149..35b31b86 100644 --- a/inc/config.php +++ b/inc/config.php @@ -335,10 +335,8 @@ $config['auto_unicode'] = true; // Whether to turn URLs into functional links $config['markup_urls'] = true; - $config['url_ads'] = ''; - // Use it if you want to add something before URL - //for example hide referrer 'http://www.nullrefer.com/?' 'http://anonym.to/?' - //or add some sort of ads + // Optional URL prefix for links (eg. "http://anonym.to/?") + $config['link_prefix'] = ''; // Wordfilters are used to automatically replace certain words/phrases with something else. diff --git a/inc/functions.php b/inc/functions.php index 5d3a5757..a261e350 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1385,7 +1385,7 @@ function markup_url($matches) { $markup_urls[] = $url; - return '' . $url . '' . $after; + return '' . $url . '' . $after; } function unicodify($body) { From a9f3f44c5ffc355df7831eed29b08e0dd2b398fc Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sun, 6 Jan 2013 09:41:00 +0100 Subject: [PATCH 094/289] 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 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

+
+ + From 1ffabe2b930a72995be9c4b1699ebd0dab22827d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 03:55:55 -0400 Subject: [PATCH 095/289] fix header.html merge --- templates/header.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 From b7d884ef45c271a0081a61b396cddb9aaf9a55ef Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 16 Jul 2013 13:18:55 -0400 Subject: [PATCH 096/289] recaptcha: fix for https --- templates/post_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 %} +
+ + + From 15d2c3e28a4f1590a0a42387dd198eb433ff8580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Wed, 2 Jan 2013 05:49:04 +0100 Subject: [PATCH 113/289] 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 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; +} From b01417be444bd3217ae09067c039cc14f3a5593b Mon Sep 17 00:00:00 2001 From: asiekierka Date: Sun, 6 Jan 2013 13:40:33 +0100 Subject: [PATCH 114/289] 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 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']); From f98d5bdd180d7452e82d7e35dcd7e3372ccd2aab Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 2 Jul 2013 20:58:16 -0400 Subject: [PATCH 115/289] local-time.js: make it work in localised environments --- js/local-time.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/local-time.js b/js/local-time.js index b92cc5be..bb81c83a 100644 --- a/js/local-time.js +++ b/js/local-time.js @@ -25,13 +25,13 @@ onready(function(){ var times = document.getElementsByTagName('time'); for(var i = 0; i < times.length; i++) { - if(!times[i].innerHTML.match(/^\d+\/\d+\/\d+ \(\w+\) \d+:\d+:\d+$/)) + if(typeof times[i].getAttribute('data-local') == 'undefined') continue; var t = iso8601(times[i].getAttribute('datetime')); - + times[i].setAttribute('data-local', 'true'); times[i].innerHTML = // date zeropad(t.getMonth() + 1, 2) + "/" + zeropad(t.getDate(), 2) + "/" + t.getFullYear().toString().substring(2) + From 46ebcbf51d99cd439906cf63a5bf4cefe5ddce45 Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 2 Jul 2013 21:09:05 -0400 Subject: [PATCH 116/289] local-time.js: make it work with thread expand etc; BEWARE IT NOW NEEDS JQUERY TO BE LOADED BEFORE --- js/local-time.js | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/js/local-time.js b/js/local-time.js index bb81c83a..aee26ed2 100644 --- a/js/local-time.js +++ b/js/local-time.js @@ -6,6 +6,7 @@ * Copyright (c) 2012 Michael Save * * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/local-time.js'; * */ @@ -21,23 +22,32 @@ onready(function(){ var zeropad = function(num, count) { return [Math.pow(10, count - num.toString().length), num].join('').substr(1); }; + + var do_localtime = function(elem) { + var times = elem.getElementsByTagName('time'); - var times = document.getElementsByTagName('time'); - - for(var i = 0; i < times.length; i++) { - if(typeof times[i].getAttribute('data-local') == 'undefined') - continue; + for(var i = 0; i < times.length; i++) { + if(typeof times[i].getAttribute('data-local') == 'undefined') + continue; - var t = iso8601(times[i].getAttribute('datetime')); + var t = iso8601(times[i].getAttribute('datetime')); - times[i].setAttribute('data-local', 'true'); - times[i].innerHTML = - // date - zeropad(t.getMonth() + 1, 2) + "/" + zeropad(t.getDate(), 2) + "/" + t.getFullYear().toString().substring(2) + - " (" + ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][t.getDay()] + ") " + - // time - zeropad(t.getHours(), 2) + ":" + zeropad(t.getMinutes(), 2) + ":" + zeropad(t.getSeconds(), 2); + times[i].setAttribute('data-local', 'true'); + times[i].innerHTML = + // date + zeropad(t.getMonth() + 1, 2) + "/" + zeropad(t.getDate(), 2) + "/" + t.getFullYear().toString().substring(2) + + " (" + ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][t.getDay()] + ") " + + // time + zeropad(t.getHours(), 2) + ":" + zeropad(t.getMinutes(), 2) + ":" + zeropad(t.getSeconds(), 2); + }; }; + + do_localtime(document); + + // allow to work with auto-reload.js, etc. + $(document).bind('new_post', function(e, post) { + do_localtime(post); + }); }); From 0a97cf721584e352806354e2c5c6392175d89d7c Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 04:37:07 -0400 Subject: [PATCH 117/289] js/local-time.js: Make jQuery optional --- js/local-time.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/js/local-time.js b/js/local-time.js index aee26ed2..40869c3a 100644 --- a/js/local-time.js +++ b/js/local-time.js @@ -6,7 +6,7 @@ * Copyright (c) 2012 Michael Save * * Usage: - * $config['additional_javascript'][] = 'js/jquery.min.js'; + * // $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/local-time.js'; * */ @@ -44,10 +44,12 @@ onready(function(){ }; do_localtime(document); - - // allow to work with auto-reload.js, etc. - $(document).bind('new_post', function(e, post) { - do_localtime(post); - }); + + if (window.jQuery) { + // allow to work with auto-reload.js, etc. + $(document).bind('new_post', function(e, post) { + do_localtime(post); + }); + } }); From 4922828e35eca8b28135a681a6f5d0e9a93641fd Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:17:56 -0400 Subject: [PATCH 118/289] js i18n: expand.js --- js/expand.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/expand.js b/js/expand.js index 6e5fa659..d5706643 100644 --- a/js/expand.js +++ b/js/expand.js @@ -17,7 +17,7 @@ $(document).ready(function(){ $('div.post.op span.omitted').each(function() { $(this) - .html($(this).text().replace(/Click reply to view\./, 'Click to expand.')) + .html($(this).text().replace(_("Click reply to view."), ''+_("Click to expand")+'.')) .find('a').click(function() { var thread = $(this).parent().parent().parent(); var id = thread.attr('id').replace(/^thread_/, ''); @@ -40,7 +40,7 @@ $(document).ready(function(){ last_expanded = post_in_doc; } }); - $('Hide expanded replies.') + $('' + _('Hide expanded replies') + '.') .insertAfter(thread.find('span.omitted').css('display', 'none')) .click(function() { thread.find('.expanded').remove(); From 2779db56cb080d1837d216d3c1f9b8c6aa013f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Sat, 29 Dec 2012 16:30:46 +0100 Subject: [PATCH 119/289] smartphone-spoiler.js: add windows phone/tablet user agents --- js/smartphone-spoiler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/smartphone-spoiler.js b/js/smartphone-spoiler.js index ede273e4..54c7a9a1 100644 --- a/js/smartphone-spoiler.js +++ b/js/smartphone-spoiler.js @@ -11,7 +11,7 @@ */ onready(function(){ - if(navigator.userAgent.match(/iPhone|iPod|iPad|Android|Opera Mini|Blackberry|PlayBook/i)) { + if(navigator.userAgent.match(/iPhone|iPod|iPad|Android|Opera Mini|Blackberry|PlayBook|Windows Phone|Tablet PC|Windows CE|IEMobile/i)) { var spoilers = document.getElementsByClassName('spoiler'); for(var i = 0; i < spoilers.length; i++) { spoilers[i].onmousedown = function() { From fee73c2087dcac126c430bae905ed4ff24784c35 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:27:09 -0400 Subject: [PATCH 120/289] js i18n: local-time.js --- js/local-time.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/local-time.js b/js/local-time.js index 40869c3a..d581e304 100644 --- a/js/local-time.js +++ b/js/local-time.js @@ -37,7 +37,7 @@ onready(function(){ times[i].innerHTML = // date zeropad(t.getMonth() + 1, 2) + "/" + zeropad(t.getDate(), 2) + "/" + t.getFullYear().toString().substring(2) + - " (" + ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][t.getDay()] + ") " + + " (" + [_("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")][t.getDay()] + ") " + // time zeropad(t.getHours(), 2) + ":" + zeropad(t.getMinutes(), 2) + ":" + zeropad(t.getSeconds(), 2); }; From bf4eca82b60f8ecd30f529164eb9f65872746608 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:40:23 -0400 Subject: [PATCH 121/289] js i18n: hide-locked-threads.js i18n --- js/toggle-locked-threads.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/toggle-locked-threads.js b/js/toggle-locked-threads.js index 50c44eda..1d517a4d 100644 --- a/js/toggle-locked-threads.js +++ b/js/toggle-locked-threads.js @@ -36,7 +36,7 @@ $(document).ready(function(){ $('hr:first').before(''); $('div#toggle-locked-threads a') - .text((hide_locked_threads ? 'Show' : 'Hide') + ' locked threads') + .text(hide_locked_threads ? _('Show locked threads') : _('Hide locked threads')) .click(function() { hide_locked_threads = !hide_locked_threads; if (hide_locked_threads) { @@ -51,7 +51,7 @@ $(document).ready(function(){ delete localStorage.hidelockedthreads; } - $(this).text((hide_locked_threads ? 'Show' : 'Hide') + ' locked threads') + $(this).text(hide_locked_threads ? _('Show locked threads') : _('Hide locked threads')) }); if (hide_locked_threads) { From 223624892a8cf9cb6f41f6b83927f2d12f00246c Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:48:24 -0400 Subject: [PATCH 122/289] js i18n: forced-anon.js --- js/forced-anon.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/forced-anon.js b/js/forced-anon.js index 3dbf0dfc..6ae43882 100644 --- a/js/forced-anon.js +++ b/js/forced-anon.js @@ -56,17 +56,17 @@ $(document).ready(function() { forced_anon = localStorage['forcedanon'] ? true : false; $('hr:first').before(''); - $('div#forced-anon a').text('Forced anonymity (' + (forced_anon ? 'enabled' : 'disabled') + ')'); + $('div#forced-anon a').text(_('Forced anonymity')+' (' + (forced_anon ? _('enabled') : _('disabled')) + ')'); $('div#forced-anon a').click(function() { forced_anon = !forced_anon; if(forced_anon) { - $('div#forced-anon a').text('Forced anonymity (enabled)'); + $('div#forced-anon a').text(_('Forced anonymity')+' ('+_('enabled')+')'); localStorage.forcedanon = true; enable_fa(); } else { - $('div#forced-anon a').text('Forced anonymity (disabled)'); + $('div#forced-anon a').text(_('Forced anonymity')+' ('+_('disabled')+')'); delete localStorage.forcedanon; disable_fa(); } From a1b739b818eef2aa17846cd171f04e21dc7d34e4 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 01:55:43 -0400 Subject: [PATCH 123/289] js i18n: quick-post-controls.js --- js/quick-post-controls.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/quick-post-controls.js b/js/quick-post-controls.js index 0c164bbb..c28f874f 100644 --- a/js/quick-post-controls.js +++ b/js/quick-post-controls.js @@ -24,17 +24,17 @@ $(document).ready(function(){ '' + - ': ' + + ': ' + '' + - '' + - '' + - ' ' + + '' + + '' + + ' ' + '
' + - ': ' + + ': ' + '' + - ' ' + + ' ' + '
' + ''); post_form From e648121e4ad07aadec7579d62a56190ca19d3fe5 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:12:22 -0400 Subject: [PATCH 124/289] hide-images.js: javascript i18n --- js/hide-images.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/hide-images.js b/js/hide-images.js index 7344cd8f..365ebac6 100644 --- a/js/hide-images.js +++ b/js/hide-images.js @@ -47,13 +47,13 @@ $(document).ready(function(){ var fileinfo = $(this).parent().prev(); var id = $(this).parent().parent().find('>p.intro>a.post_no:eq(1),>div.post.op>p.intro>a.post_no:eq(1)').text(); - var replacement = $('File (hide): '); + var replacement = $(''+_('File')+' ('+_('hide')+'): '); replacement.find('a').click(function() { hidden_data[board][id] = Math.round(Date.now() / 1000); store_data(); - var show_link = $('show').click(function() { + var show_link = $(''+_('show')+'').click(function() { delete hidden_data[board][id]; store_data(); From 2868dd7886082cfb11fcbe8f8bee1108a48c81a3 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 15 Jun 2013 01:39:39 -0400 Subject: [PATCH 125/289] javascripts: fixed interactions (BEWARE, inline-expanding.js now requires jquery! fix your configs) Conflicts: js/expand.js js/inline-expanding.js --- js/expand.js | 4 ++-- js/inline-expanding.js | 5 ++--- js/show-backlinks.js | 4 ++++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/js/expand.js b/js/expand.js index d5706643..f2cfdc5e 100644 --- a/js/expand.js +++ b/js/expand.js @@ -14,7 +14,7 @@ $(document).ready(function(){ if($('div.banner').length != 0) return; // not index - + $('div.post.op span.omitted').each(function() { $(this) .html($(this).text().replace(_("Click reply to view."), ''+_("Click to expand")+'.')) @@ -51,4 +51,4 @@ $(document).ready(function(){ }); }); }); -}); +}); \ No newline at end of file diff --git a/js/inline-expanding.js b/js/inline-expanding.js index 20383f04..e529a395 100644 --- a/js/inline-expanding.js +++ b/js/inline-expanding.js @@ -14,7 +14,7 @@ onready(function(){ var inline_expand_post = function() { var link = this.getElementsByTagName('a'); - + 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') { link[i].childNodes[0].style.maxWidth = '95%'; @@ -54,7 +54,7 @@ onready(function(){ if (window.jQuery) { $('div[id^="thread_"]').each(inline_expand_post); - + // allow to work with auto-reload.js, etc. $(document).bind('new_post', function(e, post) { inline_expand_post.call(post); @@ -64,4 +64,3 @@ onready(function(){ } }); - diff --git a/js/show-backlinks.js b/js/show-backlinks.js index e6e17e4f..4ead494b 100644 --- a/js/show-backlinks.js +++ b/js/show-backlinks.js @@ -46,5 +46,9 @@ onready(function(){ }; $('div.post.reply').each(showBackLinks); + + $(document).bind('new_post', function(e, post) { + showBackLinks.call(post); + }); }); From 45ead9803f01c2cb84b11b3747e432737af27595 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 00:57:12 -0400 Subject: [PATCH 126/289] ukko: fix javascript interoperation Conflicts: js/expand.js js/hide-threads.js templates/themes/ukko/ukko.js --- js/expand.js | 13 +++++++++++-- js/hide-threads.js | 12 +++++++++--- js/show-backlinks.js | 7 ++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/js/expand.js b/js/expand.js index f2cfdc5e..07ce9e43 100644 --- a/js/expand.js +++ b/js/expand.js @@ -14,8 +14,9 @@ $(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() { @@ -50,5 +51,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); + } }); -}); \ No newline at end of file +}); diff --git a/js/hide-threads.js b/js/hide-threads.js index faa1289c..575804b6 100644 --- a/js/hide-threads.js +++ b/js/hide-threads.js @@ -41,11 +41,11 @@ $(document).ready(function(){ hidden_data[board] = {}; // id : timestamp } - $('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(); $('[–] ') - .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(); @@ -68,9 +68,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); + } }); }); From be2e7d9782ebccc6a952468da5fbf94dd9a9d6c0 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:33:21 -0400 Subject: [PATCH 127/289] i18n some strings in inc/config.php --- inc/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/config.php b/inc/config.php index 0ff0600b..8184f236 100644 --- a/inc/config.php +++ b/inc/config.php @@ -329,7 +329,7 @@ $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; - $config['robot_mute_descritpion'] = 'You have been muted for unoriginal content.'; + $config['robot_mute_descritpion'] = _('You have been muted for unoriginal content.'); // Automatically convert things like "..." to Unicode characters ("…") $config['auto_unicode'] = true; @@ -903,7 +903,7 @@ $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). - $config['mod']['default_ban_message'] = 'USER WAS BANNED FOR THIS POST'; + $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']['ban_message'] = '(%s)'; From babeec8bb9f54eece943b74628c95f976f5ee814 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:50:38 -0400 Subject: [PATCH 128/289] localise time values --- inc/functions.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index a261e350..8fdd8927 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -554,35 +554,35 @@ function checkFlood($post) { function until($timestamp) { $difference = $timestamp - time(); if ($difference < 60) { - return $difference . ' second' . ($difference != 1 ? 's' : ''); + return $difference . ' ' . ngettext('second', 'seconds', $difference); } elseif ($difference < 60*60) { - return ($num = round($difference/(60))) . ' minute' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); } elseif ($difference < 60*60*24) { - return ($num = round($difference/(60*60))) . ' hour' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60))) . ' ' . ngettext('hour', 'hours', $num); } elseif ($difference < 60*60*24*7) { - return ($num = round($difference/(60*60*24))) . ' day' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24))) . ' ' . ngettext('day', 'days', $num); } elseif ($difference < 60*60*24*365) { - return ($num = round($difference/(60*60*24*7))) . ' week' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*7))) . ' ' . ngettext('week', 'weeks', $num); } - return ($num = round($difference/(60*60*24*365))) . ' year' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*365))) . ' ' . ngettext('year', 'years', $num); } function ago($timestamp) { $difference = time() - $timestamp; if ($difference < 60) { - return $difference . ' second' . ($difference != 1 ? 's' : ''); + return $difference . ' ' . ngettext('second', 'seconds', $difference); } elseif ($difference < 60*60) { - return ($num = round($difference/(60))) . ' minute' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); } elseif ($difference < 60*60*24) { - return ($num = round($difference/(60*60))) . ' hour' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60))) . ' ' . ngettext('hour', 'hours', $num); } elseif ($difference < 60*60*24*7) { - return ($num = round($difference/(60*60*24))) . ' day' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24))) . ' ' . ngettext('day', 'days', $num); } elseif ($difference < 60*60*24*365) { - return ($num = round($difference/(60*60*24*7))) . ' week' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*7))) . ' ' . ngettext('week', 'weeks', $num); } - return ($num = round($difference/(60*60*24*365))) . ' year' . ($num != 1 ? 's' : ''); + return ($num = round($difference/(60*60*24*365))) . ' ' . ngettext('year', 'years', $num); } function displayBan($ban) { From 3f98522ff2cb6cc90b6f7e1285b27b4ba374eb9c Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:21:30 -0400 Subject: [PATCH 129/289] i18n one more string in inc/functions.php --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 8fdd8927..783663e7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -599,7 +599,7 @@ function displayBan($ban) { // Show banned page and exit die( Element('page.html', array( - 'title' => 'Banned!', + 'title' => _('Banned!'), 'config' => $config, 'body' => Element('banned.html', array( 'config' => $config, From 67db0a878a033d98a7daab578a7be8b70dc85b64 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 00:25:32 -0400 Subject: [PATCH 130/289] js i18n: finish implementation with addition of the compiled locale strings file to additional javascripts --- inc/functions.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/inc/functions.php b/inc/functions.php index 783663e7..d904e1a2 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1277,6 +1277,12 @@ function buildJavascript() { 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)); } + // Check if we have translation for the javascripts; if yes, we add it to additional javascripts + list($pure_locale) = explode(".", $config['locale']); + if (file_exists ($jsloc = "inc/locale/".$pure_locale."/LC_MESSAGES/javascript.js")) { + array_unshift($config['additional_javascript'], $jsloc); + } + $script = Element('main.js', array( 'config' => $config, 'stylesheets' => $stylesheets From 81da2fea040b76c564c063ab88a3ef2a809dfc5f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 05:03:50 -0400 Subject: [PATCH 131/289] Undo 7e0cec for now. Will restore later once I resolve issues --- inc/display.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/display.php b/inc/display.php index a2d50f74..94f8e8cd 100644 --- a/inc/display.php +++ b/inc/display.php @@ -25,7 +25,8 @@ function doBoardListPart($list, $root) { $body = ''; foreach ($list as $board) { if (is_array($board)) - $body .= ' [' . doBoardListPart($board, $root) . '] '; + $body .= ' [' . doBoardListPart($board, $root) . '] '; + // $body .= ' [' . doBoardListPart($board, $root) . '] '; else { if (($key = array_search($board, $list)) && gettype($key) == 'string') { $body .= ' ' . $key . ' /'; From 317f616e822c4519c78ac068bb69d285955bb39e Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 05:06:29 -0400 Subject: [PATCH 132/289] Accidentally included header.html twice --- templates/index.html | 1 - 1 file changed, 1 deletion(-) 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 }} From 439795e63b1468000992275320b6c7e3f43fa9c0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 06:40:57 -0400 Subject: [PATCH 133/289] Disallow board names which are too large for the filesytem to handle --- inc/mod/pages.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index ab4cdaaf..08604039 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -446,6 +446,23 @@ function mod_new_board() { if (!preg_match('/^' . $config['board_regex'] . '$/u', $_POST['uri'])) error(sprintf($config['error']['invalidfield'], 'URI')); + $bytes = 0; + $chars = preg_split('//u', $_POST['uri'], -1, PREG_SPLIT_NO_EMPTY); + foreach ($chars as $char) { + $o = 0; + $ord = ordutf8($char, $o); + if ($ord > 0x0080) + $bytes += 5; // @01ff + else + $bytes ++; + } + $bytes + strlen('posts_.frm'); + + if ($bytes > 255) { + error('Your filesystem cannot handle a board URI of that length (' . $bytes . '/255 bytes)'); + exit; + } + if (openBoard($_POST['uri'])) { error(sprintf($config['error']['boardexists'], $board['url'])); } From 42e16e233a53e73d8d8796814a588d5df1091f7b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 06:54:53 -0400 Subject: [PATCH 134/289] Javascript l10n: Work without $config['additional_javascript_compile'] --- inc/functions.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index d904e1a2..1ffa32df 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1277,16 +1277,17 @@ function buildJavascript() { 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)); } - // Check if we have translation for the javascripts; if yes, we add it to additional javascripts - list($pure_locale) = explode(".", $config['locale']); - if (file_exists ($jsloc = "inc/locale/".$pure_locale."/LC_MESSAGES/javascript.js")) { - array_unshift($config['additional_javascript'], $jsloc); - } - $script = Element('main.js', array( 'config' => $config, 'stylesheets' => $stylesheets )); + + // Check if we have translation for the javascripts; if yes, we add it to additional javascripts + list($pure_locale) = explode(".", $config['locale']); + if (file_exists ($jsloc = "inc/locale/$pure_locale/LC_MESSAGES/javascript.js")) { + $script = file_get_contents($jsloc) . "\n\n" . $script; + } + if ($config['additional_javascript_compile']) { foreach ($config['additional_javascript'] as $file) { $script .= file_get_contents($file); From 659310663e9e7c2163234fbbc9ce922147328aa1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 06:56:57 -0400 Subject: [PATCH 135/289] i18n some more strings in inc/config.php --- inc/config.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/config.php b/inc/config.php index 8184f236..1fd00a3d 100644 --- a/inc/config.php +++ b/inc/config.php @@ -538,8 +538,8 @@ $config['ban_date'] = '%A %e %B, %Y'; // The names on the post buttons. (On most imageboards, these are both "Post") - $config['button_newtopic'] = 'New Topic'; - $config['button_reply'] = 'New Reply'; + $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. $config['poster_ids'] = false; @@ -550,7 +550,7 @@ $config['thread_subject_in_title'] = false; // Page footer - $config['footer'][] = 'All trademarks, copyrights, comments, and images on this page are owned by and are the responsibility of their respective parties.'; + $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) $config['genpassword_chars'] = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+'; From 8e4c493a4c5bbff07483fd4a11c44c687c99e441 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 12:05:19 -0400 Subject: [PATCH 136/289] Issue #126 --- post.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/post.php b/post.php index 85dc2d05..a82b56ad 100644 --- a/post.php +++ b/post.php @@ -378,10 +378,22 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); - if (mysql_version() >= 50503) + 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 + } else { + // MySQL's `utf8` charset only supports up to 3-byte symbols + // Remove anything >= 0x010000 + + $chars = preg_split('//u', $post['body'], -1, PREG_SPLIT_NO_EMPTY); + $post['body_nomarkup'] = ''; + foreach ($chars as $char) { + $o = 0; + $ord = ordutf8($char, $o); + if ($ord >= 0x010000) + continue; + $post['body_nomarkup'] .= $char; + } + } if (!($mod && isset($post['raw']) && $post['raw'])) $post['tracked_cites'] = markup($post['body'], true); From 3d979750b1be802549e4e18662c7e642f466daaa Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 15:01:44 -0400 Subject: [PATCH 137/289] fix merge --- inc/image.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/inc/image.php b/inc/image.php index 8cc9d69b..99c10252 100644 --- a/inc/image.php +++ b/inc/image.php @@ -286,12 +286,7 @@ class ImageConvert extends ImageBase { if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " > " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); -<<<<<<< HEAD - } - else { -======= } else { ->>>>>>> 8e4c493a4c5bbff07483fd4a11c44c687c99e441 if (shell_exec("convert -background transparent -filter Point -sample {$this->width}x{$this->height} +antialias -quality {$quality} " . escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); From dc1d1a3fcd0e6a9e4f1ba791e15765d68b09e6dc Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 16:22:27 -0400 Subject: [PATCH 138/289] Issue #125 --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 19790 -> 19840 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 2a31d64e2b739bc537600e64426544aa1e58a4fe..bc603e6776603e1b1c86a613577a3c9ddc23aad2 100644 GIT binary patch delta 2375 zcmX>%i?Lxgrz`)7Cz_7`ffq{d8 zfnkp^1A`p{1H(~ch(#1Y#(1!*P_ zhh&>DFt9N&Fcg|FFmN+4FjSZ@Fo-iSFtnI3Ft{@?Fw8NjXJ8O!U|@J+0&(FF6Nt;$ zOd$?ZHHFCQn?fx#Wnhp3S!l|@AjrVLkPTH=Ys$c2#lXPO4y6y7GB9{DFfjZzWnj=^ zU|?`JV*q=!$c%wOnt_3#)eI6c3+v4wE?#K{aq&7c1_pix28JzWkf=Cf2Jzu7sQgnX z|FszdgBk+^!#AjYS#yX3m7uh~ImE{{<`55fm_tG$21+MG>G~{lh)W91AwgdWm1r`D zIIPng;;=p_J;fXnLbIUic0w&UV9vn6#K6FC1!~T9DE+`35>hYCAtCVF91>D|7GV48 z89Xf@50w(gn@zKmKDTceQOA9Z4J@qZq2|Tz`(!|Y7GggG;2r{v|2+# za;7!d=M3{f`szVGvxc~63rK*0fngt1!6|Eq4=zLLdr);Rts!y!8EPPd4J3E4*)TA; zFfcH1*+4?X-v$yQt zB+iN)A#q&o2ys}aBSimXM@U*(;Rx~h4o8SN`y3%2ItmrP=*YmJ%fP^J-I0Mohk=2C zwcZKh6C)=E1~Uc*21h3b1`SY2<;1{X%D}*|&>rRjm_}~PIA}(hLU(p#-qFFmb zfV8Xz_VDAd4GfG?`AvxU@QgqLDg+#@1SBN>6 zp!9oJaER42@VG%-BI5?J(AW*)lYBRbhHf`Vkgsrq1m!k2NE{x5(pRD4FWewO{sn5@ zZ#PH~3%N5e7=s+>4$)Wa4sl?cJILO828J$o1_pglP`g8d@*-G*f#Ib)14AeS0|SEx z#Go(_NWs$V0ZG*}Js23|85kILcrY*+FfcIO@PO#&^kiT#WME)W^n^q~uqPx6)1l%G zo{%)N$&-OW43z(mdqP}z&l8dhguEa@sp16*0e3G*+DP$YV8~!#V3_U20LtixNa9=r z0jR9IA##>fwT`)d>{@A_W=bx14En-LmGo70|P^; z4z->;v)1PAGlU2a;_r`apvGKUAH(FT@~KUx-6(d?60-_JyRGR9{H>P`vr1 z;0-w+V{3(ioYJDi99xY%TU$c~dj$gpD}_8&LjyZoBLy`zFw@4?1jN(;2^-iL8YtA% ZfW<*-3^Wz&6$}-u6pS=C?>3k$0{{gO5`h2! delta 2325 zcmZpe&3JAW1_nQ4hI$4e1_p*)V+ICJ1_p)(V+IBe z1_p*MV+IC01_p-7#t@4x88a|2GcYjxGln>T$%KJ{hk=1X(1d}3i-Cbb4oYj9KrApZ zfjGd@gn@yLfq}u^gn@yZfq}uzgn>bvfq@~&gn_}Gfq@~*q@IC6n1O*|lL^Fy$4nqD zyJ7-y&}S2f{9l-brVI>HAPY?y7z7y@7%WX8>by-E7_1l=7($`+1XBhEPX-2t)20jz zS_}*fqGk+Wk2;t!Fi0~nFa(=HLMFf74C3N)Gl+|8%orH>85kIv%pg%Q$qeGd6;S!j zQ2tIc1_m_-28JV0{jbd+A@TuA|22d7n9CgE0Wot(NN7Q6LnvKuVGePLy*VW4-Jucz z<`9R4n?oEH1ErJ9At96jRo4!+pwFCvfr){EVG-1vrBHgEIV7aEn?pk2q&Xy{?m*=0 z8N@9h5(*X!43eP4Vgd2FFH}6)f`LJVfq|jSf`P%Cfq|jh0urRxEf^S*85kItEFp^Jj633p75Ql|3Li8s(Leff^BgE%zjt~#@I6^F*3>Ba6$iSe>z`(H7k%2*nfq~(2 zy(7dY3{DITW(*7r{7wuE8laNOiGjhCfq^043F70WPLL4T=LCtO8&LjxCrF9L=?n>a zMQ2FvuyuwwJOj$FafXMR%qvBr2x5Ld;nJ zrT4mmL#&?RmMg?1uUsJ(GP*&0V(SLc5a|X9@-jC_P`0>1;&1|#UJMoA<^~D!Lv9fB zPP##Y_<!fD|l&9*|U>?!mwy&%nUY=E1;Vz`($;%mbqTx(5S;Ap--$dk;tyD0)Jo(9{zm z?&k?fGYy^$3}T@CKh+cB!Zn_dT=2jX5|p1jAt4~@1xXu5UJMKw3=9mJUJML23=9mH zydbHV-y1@UdqYA<-W!rwwY?!BVgePnhVtFLAyMMz&A?C(Dybs9A#s`orSrWZskp=& zk~piN{7$IGeyBmSpyCUm{N>(|M7j=2pYR69F~cKoNc-RuRGq31DCij&bbJ`n7&I9e z7@U0|L6z$RvAEF(;*)kLJ=q76ZRYzxg8VF0-CL+ZpM4+>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. There is no previous page. #: /var/www/html/Tinyboard/inc/functions.php:958 From d692bce68674934a4af2e9cba79d65e72279b0a9 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 16:34:50 -0400 Subject: [PATCH 139/289] 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(-) 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 %} From 6cdf6038754f18af4509ecf078f51894f63c5853 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 16:38:09 -0400 Subject: [PATCH 140/289] 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(-) 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 %} From c2a287cd142b4ba0940c3026af98d4ff949469de Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 17:02:42 -0400 Subject: [PATCH 141/289] Only run SQL query to count threads if we really need to --- inc/functions.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 1ffa32df..95487529 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -995,7 +995,10 @@ function index($page, $mod=false) { $query->bindValue(':threads_per_page', $config['threads_per_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($query->rowcount() < 1 && $page > 1) + if ($page == 1 && $query->rowCount() <= $config['threads_per_page']) + $board['thread_count'] = $query->rowCount(); + + if ($query->rowCount() < 1 && $page > 1) return false; while ($th = $query->fetch()) { $thread = new Thread( @@ -1108,10 +1111,13 @@ function getPageButtons($pages, $mod=false) { function getPages($mod=false) { global $board, $config; - // Count threads - $query = query(sprintf("SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); - - $count = current($query->fetch()); + if (isset($board['thread_count'])) { + $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()); + $count = $query->fetchColumn(); + } $count = floor(($config['threads_per_page'] + $count - 1) / $config['threads_per_page']); if ($count < 1) $count = 1; From 3a8736cdc0a047e19eaffb4eb82bbf560906ea7f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 17:04:36 -0400 Subject: [PATCH 142/289] Fix last commit --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 95487529..7826d41b 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -995,7 +995,7 @@ function index($page, $mod=false) { $query->bindValue(':threads_per_page', $config['threads_per_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($page == 1 && $query->rowCount() <= $config['threads_per_page']) + if ($page == 1 && $query->rowCount() < $config['threads_per_page']) $board['thread_count'] = $query->rowCount(); if ($query->rowCount() < 1 && $page > 1) From 6317a7015272d770770c000c69271ff73cf55007 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 15 Jun 2013 00:22:13 -0400 Subject: [PATCH 143/289] 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(-) 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 From 4891735c49ee7879d0f299d03ebfbe361f3cc73d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 18:29:09 -0400 Subject: [PATCH 144/289] Fix issue #72 --- inc/config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/config.php b/inc/config.php index 1fd00a3d..6f2371ec 100644 --- a/inc/config.php +++ b/inc/config.php @@ -381,10 +381,10 @@ */ // "Wiki" markup syntax ($config['wiki_markup'] in pervious versions): - $config['markup'][] = array("/'''(.+?)'''/", "\$1"); - $config['markup'][] = array("/''(.+?)''/", "\$1"); - $config['markup'][] = array("/\*\*(.+?)\*\*/", "\$1"); - $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1"); + $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( From 6d52c8b42813722c49890b6e4f776dc0dabf382c Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 18:59:54 -0400 Subject: [PATCH 145/289] Markup modifiers. Fix issue #66 (public ban message lost when rebuilding post body) --- inc/functions.php | 36 +++++++++++++++++++++++++++++++++++- inc/mod/pages.php | 10 ++++++++-- post.php | 3 ++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 7826d41b..e638f016 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1456,13 +1456,43 @@ function markup(&$body, $track_cites = false) { } } + if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + $skip_chars = 0; + $body_tmp = $body; + + foreach ($modifiers as $modifier) { + // preg_match_all is not multibyte-safe + foreach ($modifier as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + + $modifier['type'] = $modifier[1][0]; + $modifier['content'] = $modifier[2][0]; + + if ($modifier['type'] == 'ban message') { + // Public ban message + $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + } elseif (preg_match('/^escape /', $modifier['type'])) { + // Escaped (not a real modifier) + $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; + } else { + // Unknown + $replacement = ''; + } + + $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); + $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); + + } + } + // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); $tracked_cites = array(); // Cites - if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } @@ -1561,6 +1591,10 @@ function markup(&$body, $track_cites = false) { return $tracked_cites; } +function escape_markup_modifiers($string) { + return preg_replace('@(.+)@', '$2', $string); +} + function utf8tohtml($utf8) { return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 08604039..351d3203 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -507,6 +507,7 @@ function mod_noticeboard($page_no = 1) { if (!hasPermission($config['mod']['noticeboard_post'])) error($config['error']['noaccess']); + $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); $query = prepare('INSERT INTO `noticeboard` VALUES (NULL, :mod, :time, :subject, :body)'); @@ -568,6 +569,7 @@ function mod_news($page_no = 1) { if (!hasPermission($config['mod']['news'])) error($config['error']['noaccess']); + $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); $query = prepare('INSERT INTO `news` VALUES (NULL, :name, :time, :subject, :body)'); @@ -737,6 +739,7 @@ function mod_page_ip($ip) { if (!hasPermission($config['mod']['create_notes'])) error($config['error']['noaccess']); + $_POST['note'] = escape_markup_modifiers($_POST['note']); markup($_POST['note']); $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); $query->bindValue(':ip', $ip); @@ -1214,12 +1217,14 @@ function mod_ban_post($board, $delete, $post, $token = false) { if (isset($_POST['public_message'], $_POST['message'])) { // public ban message $length_english = parse_time($_POST['length']) ? 'for ' . until(parse_time($_POST['length'])) : 'permanently'; + $_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` = CONCAT(`body`, :body) 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', sprintf($config['mod']['ban_message'], utf8tohtml($_POST['message']))); + $query->bindValue(':body_nomarkup', sprintf('%s', $_POST['message'])); $query->execute() or error(db_error($query)); + rebuildPost($post); modLog("Attached a public ban message to post #{$post}: " . utf8tohtml($_POST['message'])); buildThread($thread ? $thread : $post); @@ -1713,6 +1718,7 @@ function mod_new_pm($username) { } if (isset($_POST['message'])) { + $_POST['message'] = escape_markup_modifiers($_POST['message']); markup($_POST['message']); $query = prepare("INSERT INTO `pms` VALUES (NULL, :me, :id, :message, :time, 1)"); diff --git a/post.php b/post.php index 8820db2d..adb44b58 100644 --- a/post.php +++ b/post.php @@ -107,7 +107,7 @@ if (isset($_POST['delete'])) { if (count($report) > $config['report_limit']) error($config['error']['toomanyreports']); - $reason = &$_POST['reason']; + $reason = escape_markup_modifiers($_POST['reason']); markup($reason); foreach ($report as &$id) { @@ -377,6 +377,7 @@ if (isset($_POST['delete'])) { error(sprintf($config['error']['toolong'], 'password')); wordfilters($post['body']); + $post['body'] = escape_markup_modifiers($post['body']); if (mysql_version() >= 50503) { $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset From 6bbe407e18681f2812db4345036bb5ae639f5973 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 19:18:55 -0400 Subject: [PATCH 146/289] Markup modifiers: raw HTML --- inc/functions.php | 65 +++++++++++++++++++++++++---------------------- post.php | 7 +++-- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index e638f016..7cde156b 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1421,6 +1421,39 @@ 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)) { + $skip_chars = 0; + $body_tmp = $body; + + foreach ($modifiers as $modifier) { + // preg_match_all is not multibyte-safe + foreach ($modifier as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + + $modifier['type'] = $modifier[1][0]; + $modifier['content'] = $modifier[2][0]; + + if ($modifier['type'] == 'ban message') { + // Public ban message + $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + } elseif ($modifier['type'] == 'raw html') { + $body = html_entity_decode($modifier['content']); + return array(); + } elseif (preg_match('/^escape /', $modifier['type'])) { + // Escaped (not a real modifier) + $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; + } else { + // Unknown + $replacement = ''; + } + + $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); + $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); + + } + } + if (mysql_version() < 50503) $body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); @@ -1456,36 +1489,6 @@ function markup(&$body, $track_cites = false) { } } - if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - $skip_chars = 0; - $body_tmp = $body; - - foreach ($modifiers as $modifier) { - // preg_match_all is not multibyte-safe - foreach ($modifier as &$match) { - $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); - } - - $modifier['type'] = $modifier[1][0]; - $modifier['content'] = $modifier[2][0]; - - if ($modifier['type'] == 'ban message') { - // Public ban message - $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); - } elseif (preg_match('/^escape /', $modifier['type'])) { - // Escaped (not a real modifier) - $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; - } else { - // Unknown - $replacement = ''; - } - - $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); - $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); - - } - } - // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); @@ -1592,7 +1595,7 @@ function markup(&$body, $track_cites = false) { } function escape_markup_modifiers($string) { - return preg_replace('@(.+)@', '$2', $string); + return preg_replace('@(.+)@m', '$2', $string); } function utf8tohtml($utf8) { diff --git a/post.php b/post.php index adb44b58..db077866 100644 --- a/post.php +++ b/post.php @@ -379,6 +379,10 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); $post['body'] = escape_markup_modifiers($post['body']); + if ($mod && isset($post['raw']) && $post['raw']) { + $post['body'] = '' . $post['body'] . ''; + } + if (mysql_version() >= 50503) { $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset } else { @@ -396,8 +400,7 @@ if (isset($_POST['delete'])) { } } - if (!($mod && isset($post['raw']) && $post['raw'])) - $post['tracked_cites'] = markup($post['body'], true); + $post['tracked_cites'] = markup($post['body'], true); // Check for a flood if (!hasPermission($config['mod']['flood'], $board['uri']) && checkFlood($post)) { From fa5922b45efec1c0e334706ab5bccedb1856572b Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 19:50:25 -0400 Subject: [PATCH 147/289] fix post editing for tinyboard markup --- inc/mod/pages.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 351d3203..0eadd6ad 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1276,7 +1276,7 @@ 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 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->bindValue(':id', $postID); @@ -1284,6 +1284,10 @@ function mod_edit_post($board, $edit_raw_html, $postID) { $query->bindValue(':email', $_POST['email']); $query->bindValue(':subject', $_POST['subject']); $query->bindValue(':body', $_POST['body']); + if ($edit_raw_html) { + $body_nomarkup = '' . $_POST['body'] . ''; + $query->bindValue(':body_nomarkup', $body_nomarkup); + } $query->execute() or error(db_error($query)); if ($edit_raw_html) { From e7dd0bbc4a4a17a4f7e5f6750b48ee3c0946c40e Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:11:11 -0400 Subject: [PATCH 148/289] facilitate using markup modifiers multiple times; make raw html not consume the whole post --- inc/functions.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 1f702ba0..5dace908 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1451,7 +1451,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; @@ -1468,8 +1468,7 @@ function markup(&$body, $track_cites = false) { // Public ban message $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); } elseif ($modifier['type'] == 'raw html') { - $body = html_entity_decode($modifier['content']); - return array(); + $replacement = html_entity_decode($modifier['content']); } elseif (preg_match('/^escape /', $modifier['type'])) { // Escaped (not a real modifier) $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; From d7ea47a91f63382f7a4e002086e415550e342a11 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:13:19 -0400 Subject: [PATCH 149/289] markup modifiers: make it even harder to escape --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 5dace908..b52c58fb 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1624,7 +1624,7 @@ function markup(&$body, $track_cites = false) { } function escape_markup_modifiers($string) { - return preg_replace('@(.+)@m', '$2', $string); + return preg_replace('@@m', '', $string); } function utf8tohtml($utf8) { From ce2af291b084f7f6f36a0718fbf4d84a832aef12 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:33:27 -0400 Subject: [PATCH 150/289] markup modifiers: there was a plan for adding markup to ban reasons, but assignment was missing; escape markup there too --- inc/mod/ban.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/mod/ban.php b/inc/mod/ban.php index cfc2636f..99dfd196 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -61,7 +61,8 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); if ($reason !== '') { - markup($reason); + $reason = escape_markup_modifiers($reason); + $reason = markup($reason); $query->bindValue(':reason', $reason); } else $query->bindValue(':reason', null, PDO::PARAM_NULL); From 03d91df1d8af49aa1fd9e87fa8e9643b52fd52d9 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:41:56 -0400 Subject: [PATCH 151/289] fix previous commit; markup is called via reference --- inc/mod/ban.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 99dfd196..3f30db8f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -62,7 +62,7 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':time', time()); if ($reason !== '') { $reason = escape_markup_modifiers($reason); - $reason = markup($reason); + markup($reason); $query->bindValue(':reason', $reason); } else $query->bindValue(':reason', null, PDO::PARAM_NULL); From 328484bee7cab9ce354121413cc8d96c3e227aea Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 20:51:43 -0400 Subject: [PATCH 152/289] 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(-) 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', From 0f9df0ac6608d3398cd480465dcab1b0227ec9c0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 20:54:20 -0400 Subject: [PATCH 153/289] Newline before --- inc/mod/pages.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index f5b1101d..7edc0ee6 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('%s', $_POST['message'])); + $query->bindValue(':body_nomarkup', sprintf("\n%s", $_POST['message'])); $query->execute() or error(db_error($query)); rebuildPost($post); From a5312ebe897036e89db57480abb0ae617a2bcb38 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 21:02:26 -0400 Subject: [PATCH 154/289] Allow public ban messages on raw HTML posts --- inc/functions.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 0b4ac211..b40b40d2 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1423,6 +1423,7 @@ function markup(&$body, $track_cites = false) { 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; foreach ($modifiers as $modifier) { // preg_match_all is not multibyte-safe @@ -1436,9 +1437,13 @@ function markup(&$body, $track_cites = false) { if ($modifier['type'] == 'ban message') { // Public ban message $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + if ($end_markup) { + $body .= $replacement; + } } elseif ($modifier['type'] == 'raw html') { $body = html_entity_decode($modifier['content']); - return array(); + $replacement = ''; + $end_markup = true; } elseif (preg_match('/^escape /', $modifier['type'])) { // Escaped (not a real modifier) $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; @@ -1447,9 +1452,14 @@ function markup(&$body, $track_cites = false) { $replacement = ''; } - $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); - $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); - + if (!$end_markup) { + $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); + $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); + } + } + + if ($end_markup) { + return array(); } } From 055c3a73820dd949ab8bf71012fac66cac9daebd Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 21:22:32 -0400 Subject: [PATCH 155/289] Revert "facilitate using markup modifiers multiple times; make raw html not consume the whole post" This reverts commit e7dd0bbc4a4a17a4f7e5f6750b48ee3c0946c40e. --- inc/functions.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 2cbf3e6b..a6fd35c7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1449,7 +1449,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; @@ -1466,7 +1466,8 @@ function markup(&$body, $track_cites = false) { // Public ban message $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); } elseif ($modifier['type'] == 'raw html') { - $replacement = html_entity_decode($modifier['content']); + $body = html_entity_decode($modifier['content']); + return array(); } elseif (preg_match('/^escape /', $modifier['type'])) { // Escaped (not a real modifier) $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; From e93d5b2f8e033735ca40a9d3a44771be9f3842c8 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 21:22:57 -0400 Subject: [PATCH 156/289] Revert "markup modifiers: make it even harder to escape" This reverts commit d7ea47a91f63382f7a4e002086e415550e342a11. --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index a6fd35c7..e57fd32a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1623,7 +1623,7 @@ function markup(&$body, $track_cites = false) { } function escape_markup_modifiers($string) { - return preg_replace('@@m', '', $string); + return preg_replace('@(.+)@m', '$2', $string); } function utf8tohtml($utf8) { From ea2b8cce077a092e0cbf136f9a45158668cc5ecf Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 21:24:17 -0400 Subject: [PATCH 157/289] 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(-) 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 %} - + From ab364525433a7194d050e4ec13ae08d603fdad43 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 19:50:25 -0400 Subject: [PATCH 158/289] fix post editing for tinyboard markup --- inc/mod/pages.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 2808dc56..3ff6a9b1 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1276,7 +1276,7 @@ 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 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->bindValue(':id', $postID); @@ -1284,6 +1284,10 @@ function mod_edit_post($board, $edit_raw_html, $postID) { $query->bindValue(':email', $_POST['email']); $query->bindValue(':subject', $_POST['subject']); $query->bindValue(':body', $_POST['body']); + if ($edit_raw_html) { + $body_nomarkup = '' . $_POST['body'] . ''; + $query->bindValue(':body_nomarkup', $body_nomarkup); + } $query->execute() or error(db_error($query)); if ($edit_raw_html) { From 232f4ff8680e81dbee3902c01af6c702555fbc0f Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:13:19 -0400 Subject: [PATCH 159/289] markup modifiers: make it even harder to escape --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 9e1ce1fa..403f6112 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1604,7 +1604,7 @@ function markup(&$body, $track_cites = false) { } function escape_markup_modifiers($string) { - return preg_replace('@(.+)@m', '$2', $string); + return preg_replace('@@m', '', $string); } function utf8tohtml($utf8) { From a052a791b553c770ef407f91b697bef7a62df5b1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 22:14:26 -0400 Subject: [PATCH 160/289] 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(-) 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); } From 5bf0e7f7e76cd3610e0aa692e0c433aca594ee51 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 00:27:54 -0400 Subject: [PATCH 161/289] 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(-) 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 From 94468c430cf4c3edc93b265eeb900a0afa8f75a2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 00:52:49 -0400 Subject: [PATCH 162/289] Small install fix --- install.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.php b/install.php index 2f51b22f..6bb161dc 100644 --- a/install.php +++ b/install.php @@ -501,8 +501,8 @@ if ($step == 0) { - - + + From 38cc2d77f8cb68973ca52a1ce7d619ded64e83c5 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 01:16:12 -0400 Subject: [PATCH 163/289] toggle-images.js: javascript i18n --- js/toggle-images.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/toggle-images.js b/js/toggle-images.js index 74f2fab4..de1d47b3 100644 --- a/js/toggle-images.js +++ b/js/toggle-images.js @@ -38,7 +38,7 @@ $(document).ready(function(){ if ($(this).next().hasClass('show-image-link')) { $(this).next().hide(); } - $(this).hide().after('hidden'); + $(this).hide().after(''+_('hidden')+''); }); } else { $('span.toggle-images-placeholder').remove(); @@ -54,7 +54,7 @@ $(document).ready(function(){ $('hr:first').before('
    '); $('div#toggle-images a') - .text((hide_images ? 'Show' : 'Hide') + ' images') + .text(hide_images ? _('Show images') : _('Hide images')) .click(function() { hide_images = !hide_images; if (hide_images) { @@ -67,7 +67,7 @@ $(document).ready(function(){ show_hide_hide_images_buttons(); - $(this).text((hide_images ? 'Show' : 'Hide') + ' images') + $(this).text(hide_images ? _('Show images') : _('Hide images')) }); if (hide_images) { From 235ee484fd1b2f665da2b1402d7393033056a3f7 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:04:09 -0400 Subject: [PATCH 164/289] removed a relict from older post hider --- inc/config.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/inc/config.php b/inc/config.php index ec5d71d4..cb3f528b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -636,9 +636,6 @@ // $config['additional_javascript'][] = 'js/jquery.min.js'; // $config['additional_javascript'][] = 'js/auto-reload.js'; - // Enable hiding posts. Remember to put this AFTER jQuery. - // $config['additional_javascript'][] = 'js/post-hider.js'; - // Where these script files are located on the web (defaults to $config['root']). // $config['additional_javascript_url'] = '/js/'; From 05fb4cbca4f93ea55d55da3b2e3a7f2f5a174b21 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:33:27 -0400 Subject: [PATCH 165/289] markup modifiers: there was a plan for adding markup to ban reasons, but assignment was missing; escape markup there too --- inc/mod/ban.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 9166223f..45973ae6 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -61,7 +61,8 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); if ($reason !== '') { - markup($reason); + $reason = escape_markup_modifiers($reason); + $reason = markup($reason); $query->bindValue(':reason', $reason); } else $query->bindValue(':reason', null, PDO::PARAM_NULL); From bc76d934fe30c9a6fcea27678dc155e903eb88c3 Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 31 Jul 2013 20:41:56 -0400 Subject: [PATCH 166/289] fix previous commit; markup is called via reference --- inc/mod/ban.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 45973ae6..71173326 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -62,7 +62,7 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':time', time()); if ($reason !== '') { $reason = escape_markup_modifiers($reason); - $reason = markup($reason); + markup($reason); $query->bindValue(':reason', $reason); } else $query->bindValue(':reason', null, PDO::PARAM_NULL); From 9343651d90113f68b83f214c20a32975d18217e7 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:16:20 -0400 Subject: [PATCH 167/289] 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(-) 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)); From 47647648852af9ab5d7541589e2ad08a57e13059 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:43:33 -0400 Subject: [PATCH 168/289] the prefix work: fix it to be dependent on a board_regex config value --- inc/database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/database.php b/inc/database.php index 7be001ea..95dfc775 100644 --- a/inc/database.php +++ b/inc/database.php @@ -87,7 +87,7 @@ 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); + $query = preg_replace('/``('.$config['board_regex'].')``/u', '`' . $config['db']['prefix'] . '$1`', $query); sql_open(); @@ -100,7 +100,7 @@ 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); + $query = preg_replace('/``('.$config['board_regex'].')``/u', '`' . $config['db']['prefix'] . '$1`', $query); sql_open(); From a1e105a470d3f049b666abaf5cf3ccaef48d6bc8 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:47:15 -0400 Subject: [PATCH 169/289] i18n strings in inc/display.php --- inc/display.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/display.php b/inc/display.php index 3ce8eced..1dcb60fb 100644 --- a/inc/display.php +++ b/inc/display.php @@ -72,14 +72,14 @@ function error($message, $priority = true) { die(Element('page.html', array( 'config'=>$config, - 'title'=>'Error', - 'subtitle'=>'An error has occured.', + 'title'=>_('Error'), + 'subtitle'=>_('An error has occured.'), 'body'=>'
    ' . '

    ' . _($message) . '

    ' . (isset($board) ? "

    Go back.

    " : '') . + $board['dir'] . $config['file_index'] . "\">"._("Go back").".

    " : '') . '
    ' ))); } From e109d8179fa0e4e34d0191b287b31cbb40414e02 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:43:33 -0400 Subject: [PATCH 170/289] the prefix work: fix it to be dependent on a board_regex config value --- inc/database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/database.php b/inc/database.php index 7be001ea..95dfc775 100644 --- a/inc/database.php +++ b/inc/database.php @@ -87,7 +87,7 @@ 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); + $query = preg_replace('/``('.$config['board_regex'].')``/u', '`' . $config['db']['prefix'] . '$1`', $query); sql_open(); @@ -100,7 +100,7 @@ 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); + $query = preg_replace('/``('.$config['board_regex'].')``/u', '`' . $config['db']['prefix'] . '$1`', $query); sql_open(); From b9769d0cea205e4ddf831f374901ec8d220ecc7a Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:47:15 -0400 Subject: [PATCH 171/289] i18n strings in inc/display.php --- inc/display.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/display.php b/inc/display.php index 94f8e8cd..c68af9d6 100644 --- a/inc/display.php +++ b/inc/display.php @@ -72,14 +72,14 @@ function error($message, $priority = true) { die(Element('page.html', array( 'config'=>$config, - 'title'=>'Error', - 'subtitle'=>'An error has occured.', + 'title'=>_('Error'), + 'subtitle'=>_('An error has occured.'), 'body'=>'
    ' . '

    ' . _($message) . '

    ' . (isset($board) ? "

    Go back.

    " : '') . + $board['dir'] . $config['file_index'] . "\">"._("Go back").".

    " : '') . '
    ' ))); } From 3b03e18d68de3d56930956ac0d61d934d82d4f49 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:56:04 -0400 Subject: [PATCH 172/289] i18n even more strings in inc/display.php --- inc/display.php | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/inc/display.php b/inc/display.php index 1dcb60fb..fd21e83c 100644 --- a/inc/display.php +++ b/inc/display.php @@ -208,7 +208,7 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { $body = preg_replace('/&[^;]*$/', '', $body); } - $body .= 'Post too long. Click here to view the full text.'; + $body .= ''.sprintf(_('Post too long. Click here to view the full text.'), $url).''; } return $body; @@ -331,19 +331,19 @@ class Post { // 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['uri'] . '/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['uri'] . '/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['uri'] . '/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['uri'] . '/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['uri'] . '/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 . ''; From bea5509d63426824993b0d15d6c5b06d1cae7c66 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 02:06:34 -0400 Subject: [PATCH 173/289] Update Polish locale --- inc/locale/pl_PL/LC_MESSAGES/javascript.po | 3 +- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 19840 -> 20956 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 269 ++++++++++++++------- 3 files changed, 181 insertions(+), 91 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po index 482ec45f..ae1bb5c9 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.po +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-27 01:54-0400\n" +"POT-Creation-Date: 2013-08-01 01:58-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -42,6 +42,7 @@ msgid "Click to expand" msgstr "Kliknij aby rozwinąć" #: ../../../../js/expand.js:41 ../../../../js/expand.js:45 +#: ../../../../js/expand.js:43 msgid "Hide expanded replies" msgstr "Schowaj rozwinięte odpowiedzi" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index bc603e6776603e1b1c86a613577a3c9ddc23aad2..73f434f793e0925bd7bd1f91516ca303002df41a 100644 GIT binary patch delta 6994 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 delta 6209 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 YCi_{HY-X{}WZQhuv6*disz*5|01Oa&UH||9 diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 20802b7d..8a46fda9 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-27 01:54-0400\n" +"POT-Creation-Date: 2013-08-01 01:58-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,6 +24,7 @@ msgstr "" #: ../../../../inc/functions.php:1041 ../../../../inc/functions.php:1055 #: ../../../../inc/functions.php:1039 ../../../../inc/functions.php:1053 #: ../../../../inc/functions.php:1068 ../../../../inc/functions.php:1082 +#: ../../../../inc/functions.php:1079 ../../../../inc/functions.php:1093 msgid "Previous" msgstr "Wstecz" @@ -33,6 +34,7 @@ msgstr "Wstecz" #: ../../../../inc/functions.php:1060 ../../../../inc/functions.php:1069 #: ../../../../inc/functions.php:1058 ../../../../inc/functions.php:1067 #: ../../../../inc/functions.php:1087 ../../../../inc/functions.php:1096 +#: ../../../../inc/functions.php:1098 ../../../../inc/functions.php:1107 msgid "Next" msgstr "Dalej" @@ -57,6 +59,7 @@ msgid "all boards" msgstr "wszystkie boardy" #: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 +#: ../../../../inc/config.php:334 msgid "You have been muted for unoriginal content." msgstr "Zostałeś zagłuszony za nieoryginalną treść." @@ -64,11 +67,12 @@ msgstr "Zostałeś zagłuszony za nieoryginalną treść." msgid "Anonymous" msgstr "Anonimowy" -#: /var/www/html/Tinyboard/inc/config.php:481 +#. The names on the post buttons. (On most imageboards, these are both "Post") +#: /var/www/html/Tinyboard/inc/config.php:481 ../../../../inc/config.php:552 msgid "New Topic" msgstr "Nowy wątek" -#: /var/www/html/Tinyboard/inc/config.php:482 +#: /var/www/html/Tinyboard/inc/config.php:482 ../../../../inc/config.php:553 msgid "New Reply" msgstr "Odpowiedz" @@ -84,19 +88,19 @@ msgstr "Szybka odpowiedź" #. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 #: ../../../../inc/config.php:692 ../../../../inc/config.php:698 -#: ../../../../inc/config.php:695 +#: ../../../../inc/config.php:695 ../../../../inc/config.php:701 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 #: ../../../../inc/config.php:693 ../../../../inc/config.php:699 -#: ../../../../inc/config.php:696 +#: ../../../../inc/config.php:696 ../../../../inc/config.php:702 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 #: ../../../../inc/config.php:694 ../../../../inc/config.php:700 -#: ../../../../inc/config.php:697 +#: ../../../../inc/config.php:697 ../../../../inc/config.php:703 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " @@ -104,161 +108,161 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 #: ../../../../inc/config.php:695 ../../../../inc/config.php:701 -#: ../../../../inc/config.php:698 +#: ../../../../inc/config.php:698 ../../../../inc/config.php:704 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 #: ../../../../inc/config.php:696 ../../../../inc/config.php:702 -#: ../../../../inc/config.php:699 +#: ../../../../inc/config.php:699 ../../../../inc/config.php:705 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 #: ../../../../inc/config.php:697 ../../../../inc/config.php:703 -#: ../../../../inc/config.php:700 +#: ../../../../inc/config.php:700 ../../../../inc/config.php:706 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 #: ../../../../inc/config.php:698 ../../../../inc/config.php:704 -#: ../../../../inc/config.php:701 +#: ../../../../inc/config.php:701 ../../../../inc/config.php:707 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 #: ../../../../inc/config.php:699 ../../../../inc/config.php:705 -#: ../../../../inc/config.php:702 +#: ../../../../inc/config.php:702 ../../../../inc/config.php:708 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 #: ../../../../inc/config.php:700 ../../../../inc/config.php:706 -#: ../../../../inc/config.php:703 +#: ../../../../inc/config.php:703 ../../../../inc/config.php:709 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 #: ../../../../inc/config.php:701 ../../../../inc/config.php:707 -#: ../../../../inc/config.php:704 +#: ../../../../inc/config.php:704 ../../../../inc/config.php:710 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 #: ../../../../inc/config.php:702 ../../../../inc/config.php:708 -#: ../../../../inc/config.php:705 +#: ../../../../inc/config.php:705 ../../../../inc/config.php:711 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 #: ../../../../inc/config.php:703 ../../../../inc/config.php:709 -#: ../../../../inc/config.php:706 +#: ../../../../inc/config.php:706 ../../../../inc/config.php:712 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 #: ../../../../inc/config.php:706 ../../../../inc/config.php:712 -#: ../../../../inc/config.php:709 +#: ../../../../inc/config.php:709 ../../../../inc/config.php:715 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 #: ../../../../inc/config.php:707 ../../../../inc/config.php:713 -#: ../../../../inc/config.php:710 +#: ../../../../inc/config.php:710 ../../../../inc/config.php:716 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 #: ../../../../inc/config.php:708 ../../../../inc/config.php:714 -#: ../../../../inc/config.php:711 +#: ../../../../inc/config.php:711 ../../../../inc/config.php:717 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 #: ../../../../inc/config.php:709 ../../../../inc/config.php:715 -#: ../../../../inc/config.php:712 +#: ../../../../inc/config.php:712 ../../../../inc/config.php:718 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 #: ../../../../inc/config.php:710 ../../../../inc/config.php:716 -#: ../../../../inc/config.php:713 +#: ../../../../inc/config.php:713 ../../../../inc/config.php:719 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 -#: ../../../../inc/config.php:714 +#: ../../../../inc/config.php:714 ../../../../inc/config.php:720 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 -#: ../../../../inc/config.php:715 +#: ../../../../inc/config.php:715 ../../../../inc/config.php:721 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 -#: ../../../../inc/config.php:716 +#: ../../../../inc/config.php:716 ../../../../inc/config.php:722 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 -#: ../../../../inc/config.php:717 +#: ../../../../inc/config.php:717 ../../../../inc/config.php:723 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 #: ../../../../inc/config.php:715 ../../../../inc/config.php:721 -#: ../../../../inc/config.php:718 +#: ../../../../inc/config.php:718 ../../../../inc/config.php:724 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 #: ../../../../inc/config.php:716 ../../../../inc/config.php:722 -#: ../../../../inc/config.php:719 +#: ../../../../inc/config.php:719 ../../../../inc/config.php:725 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 #: ../../../../inc/config.php:717 ../../../../inc/config.php:723 -#: ../../../../inc/config.php:720 +#: ../../../../inc/config.php:720 ../../../../inc/config.php:726 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 #: ../../../../inc/config.php:718 ../../../../inc/config.php:724 -#: ../../../../inc/config.php:721 +#: ../../../../inc/config.php:721 ../../../../inc/config.php:727 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 #: ../../../../inc/config.php:719 ../../../../inc/config.php:725 -#: ../../../../inc/config.php:722 +#: ../../../../inc/config.php:722 ../../../../inc/config.php:728 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 #: ../../../../inc/config.php:720 ../../../../inc/config.php:726 -#: ../../../../inc/config.php:723 +#: ../../../../inc/config.php:723 ../../../../inc/config.php:729 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 #: ../../../../inc/config.php:721 ../../../../inc/config.php:727 -#: ../../../../inc/config.php:724 +#: ../../../../inc/config.php:724 ../../../../inc/config.php:730 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 #: ../../../../inc/config.php:722 ../../../../inc/config.php:728 -#: ../../../../inc/config.php:725 +#: ../../../../inc/config.php:725 ../../../../inc/config.php:731 msgid "Maximum file size: %maxsz% bytes
    Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
    Rozmiar twojego pliku: %filesz% " @@ -266,33 +270,33 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 #: ../../../../inc/config.php:723 ../../../../inc/config.php:729 -#: ../../../../inc/config.php:726 +#: ../../../../inc/config.php:726 ../../../../inc/config.php:732 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 #: ../../../../inc/config.php:724 ../../../../inc/config.php:730 -#: ../../../../inc/config.php:727 +#: ../../../../inc/config.php:727 ../../../../inc/config.php:733 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 #: ../../../../inc/config.php:725 ../../../../inc/config.php:731 -#: ../../../../inc/config.php:728 +#: ../../../../inc/config.php:728 ../../../../inc/config.php:734 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 #: ../../../../inc/config.php:727 ../../../../inc/config.php:733 -#: ../../../../inc/config.php:730 +#: ../../../../inc/config.php:730 ../../../../inc/config.php:736 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 #: ../../../../inc/config.php:728 ../../../../inc/config.php:734 -#: ../../../../inc/config.php:731 +#: ../../../../inc/config.php:731 ../../../../inc/config.php:737 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " @@ -300,31 +304,31 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 #: ../../../../inc/config.php:729 ../../../../inc/config.php:735 -#: ../../../../inc/config.php:732 +#: ../../../../inc/config.php:732 ../../../../inc/config.php:738 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 #: ../../../../inc/config.php:730 ../../../../inc/config.php:736 -#: ../../../../inc/config.php:733 +#: ../../../../inc/config.php:733 ../../../../inc/config.php:739 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 #: ../../../../inc/config.php:734 ../../../../inc/config.php:740 -#: ../../../../inc/config.php:737 +#: ../../../../inc/config.php:737 ../../../../inc/config.php:743 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 #: ../../../../inc/config.php:735 ../../../../inc/config.php:741 -#: ../../../../inc/config.php:738 +#: ../../../../inc/config.php:738 ../../../../inc/config.php:744 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 #: ../../../../inc/config.php:736 ../../../../inc/config.php:742 -#: ../../../../inc/config.php:739 +#: ../../../../inc/config.php:739 ../../../../inc/config.php:745 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -333,65 +337,65 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 #: ../../../../inc/config.php:737 ../../../../inc/config.php:743 -#: ../../../../inc/config.php:740 +#: ../../../../inc/config.php:740 ../../../../inc/config.php:746 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 #: ../../../../inc/config.php:738 ../../../../inc/config.php:744 -#: ../../../../inc/config.php:741 +#: ../../../../inc/config.php:741 ../../../../inc/config.php:747 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 #: ../../../../inc/config.php:739 ../../../../inc/config.php:745 -#: ../../../../inc/config.php:742 +#: ../../../../inc/config.php:742 ../../../../inc/config.php:748 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 #: ../../../../inc/config.php:740 ../../../../inc/config.php:746 -#: ../../../../inc/config.php:743 +#: ../../../../inc/config.php:743 ../../../../inc/config.php:749 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 #: ../../../../inc/config.php:741 ../../../../inc/config.php:747 -#: ../../../../inc/config.php:744 +#: ../../../../inc/config.php:744 ../../../../inc/config.php:750 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 #: ../../../../inc/config.php:742 ../../../../inc/config.php:748 -#: ../../../../inc/config.php:745 +#: ../../../../inc/config.php:745 ../../../../inc/config.php:751 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 #: ../../../../inc/config.php:743 ../../../../inc/config.php:749 -#: ../../../../inc/config.php:746 +#: ../../../../inc/config.php:746 ../../../../inc/config.php:752 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 #: ../../../../inc/config.php:744 ../../../../inc/config.php:750 -#: ../../../../inc/config.php:747 +#: ../../../../inc/config.php:747 ../../../../inc/config.php:753 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 #: ../../../../inc/config.php:745 ../../../../inc/config.php:751 -#: ../../../../inc/config.php:748 +#: ../../../../inc/config.php:748 ../../../../inc/config.php:754 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 #: ../../../../inc/config.php:746 ../../../../inc/config.php:752 -#: ../../../../inc/config.php:749 +#: ../../../../inc/config.php:749 ../../../../inc/config.php:755 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -430,6 +434,7 @@ msgstr "[Przenieś]" #. Default public ban message. #. In public ban messages, %length% is replaced with "for x days" or "permanently" (with %LENGTH% being the uppercase equivalent). #: /var/www/html/Tinyboard/inc/config.php:801 ../../../../inc/config.php:911 +#: ../../../../inc/config.php:917 msgid "USER WAS BANNED FOR THIS POST" msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" @@ -438,20 +443,21 @@ msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" msgid "Moved to %s." msgstr "Przeniesiono do %s." -#: /var/www/html/Tinyboard/inc/display.php:80 +#: /var/www/html/Tinyboard/inc/display.php:80 ../../../../inc/display.php:75 msgid "Error" msgstr "Błąd" -#: /var/www/html/Tinyboard/inc/display.php:81 +#: /var/www/html/Tinyboard/inc/display.php:81 ../../../../inc/display.php:76 msgid "An error has occured." msgstr "Wystąpił błąd." -#: /var/www/html/Tinyboard/inc/display.php:87 +#: /var/www/html/Tinyboard/inc/display.php:87 ../../../../inc/display.php:82 msgid "Go back" msgstr "Wróć" #: /var/www/html/Tinyboard/inc/display.php:97 ../../../../inc/display.php:91 #: ../../../../inc/mod/pages.php:59 ../../../../inc/mod/pages.php:62 +#: ../../../../inc/display.php:92 msgid "Login" msgstr "Logowanie" @@ -469,31 +475,34 @@ msgstr "" #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:27 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:27 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:27 +#: ../../../../inc/display.php:423 msgid "Delete" msgstr "Usuń" #: /var/www/html/Tinyboard/inc/display.php:272 -#: /var/www/html/Tinyboard/inc/display.php:365 +#: /var/www/html/Tinyboard/inc/display.php:365 ../../../../inc/display.php:423 msgid "Are you sure you want to delete this?" msgstr "Czy jesteś pewien, że chcesz to usunąć?" #: /var/www/html/Tinyboard/inc/display.php:276 -#: /var/www/html/Tinyboard/inc/display.php:369 +#: /var/www/html/Tinyboard/inc/display.php:369 ../../../../inc/display.php:427 msgid "Delete all posts by IP" msgstr "Usuń wszystkie posty z tego adresu IP" #: /var/www/html/Tinyboard/inc/display.php:276 -#: /var/www/html/Tinyboard/inc/display.php:369 +#: /var/www/html/Tinyboard/inc/display.php:369 ../../../../inc/display.php:427 msgid "Are you sure you want to delete all posts by this IP address?" msgstr "Czy na pewno chcesz usunąć wszystkie posty z tego adresu IP?" #: /var/www/html/Tinyboard/inc/display.php:280 -#: /var/www/html/Tinyboard/inc/display.php:373 +#: /var/www/html/Tinyboard/inc/display.php:373 ../../../../inc/display.php:334 +#: ../../../../inc/display.php:435 msgid "Ban" msgstr "Ban" #: /var/www/html/Tinyboard/inc/display.php:284 -#: /var/www/html/Tinyboard/inc/display.php:377 +#: /var/www/html/Tinyboard/inc/display.php:377 ../../../../inc/display.php:338 +#: ../../../../inc/display.php:439 msgid "Ban & Delete" msgstr "Usuń i zbanuj" @@ -506,34 +515,36 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:408 #: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 #: ../../../../inc/mod/pages.php:1239 ../../../../inc/mod/pages.php:1242 +#: ../../../../inc/display.php:346 ../../../../inc/display.php:470 +#: ../../../../inc/mod/pages.php:1314 msgid "Edit post" msgstr "Edytuj post" -#: /var/www/html/Tinyboard/inc/display.php:386 +#: /var/www/html/Tinyboard/inc/display.php:386 ../../../../inc/display.php:448 msgid "Make thread not sticky" msgstr "Odklej wątek" -#: /var/www/html/Tinyboard/inc/display.php:388 +#: /var/www/html/Tinyboard/inc/display.php:388 ../../../../inc/display.php:450 msgid "Make thread sticky" msgstr "Przyklej wątek" -#: /var/www/html/Tinyboard/inc/display.php:392 +#: /var/www/html/Tinyboard/inc/display.php:392 ../../../../inc/display.php:454 msgid "Allow thread to be bumped" msgstr "Zezwól wątkowi na bumpowanie" -#: /var/www/html/Tinyboard/inc/display.php:394 +#: /var/www/html/Tinyboard/inc/display.php:394 ../../../../inc/display.php:456 msgid "Prevent thread from being bumped" msgstr "Zabroń wątkowi na bumpowanie" -#: /var/www/html/Tinyboard/inc/display.php:399 +#: /var/www/html/Tinyboard/inc/display.php:399 ../../../../inc/display.php:461 msgid "Unlock thread" msgstr "Odblokuj wątek" -#: /var/www/html/Tinyboard/inc/display.php:401 +#: /var/www/html/Tinyboard/inc/display.php:401 ../../../../inc/display.php:463 msgid "Lock thread" msgstr "Zablokuj wątek" -#: /var/www/html/Tinyboard/inc/display.php:404 +#: /var/www/html/Tinyboard/inc/display.php:404 ../../../../inc/display.php:466 msgid "Move thread to another board" msgstr "Przenieś wątek na inny board" @@ -703,6 +714,8 @@ msgstr "Weryfikacja" #. line 72 #. line 3 #. line 72 +#. line 3 +#. line 72 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 @@ -787,6 +800,8 @@ msgstr "Flagi" #. line 99 #. line 98 #. line 99 +#. line 98 +#. line 99 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 @@ -854,6 +869,8 @@ msgstr "Przyklejony" #. line 103 #. line 102 #. line 103 +#. line 102 +#. line 103 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 @@ -921,6 +938,8 @@ msgstr "Zablokowany" #. line 107 #. line 106 #. line 107 +#. line 106 +#. line 107 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 @@ -1058,6 +1077,7 @@ msgstr "Tryb postowania: Odpowiedź" #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:172 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:127 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:173 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:174 msgid "Return" msgstr "Powrót" @@ -1079,6 +1099,7 @@ msgstr "Usuń post" #. line 106 #. line 8 #. line 32 +#. line 8 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 @@ -1116,6 +1137,7 @@ msgstr "Wiadomości prywatne" #: ../../../../inc/mod/pages.php:376 ../../../../inc/mod/pages.php:393 #: ../../../../inc/mod/pages.php:406 ../../../../inc/mod/pages.php:540 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:166 +#: ../../../../inc/mod/pages.php:604 msgid "News" msgstr "Aktualności" @@ -1123,7 +1145,7 @@ msgstr "Aktualności" #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 #: ../../../../inc/mod/pages.php:1682 ../../../../inc/mod/pages.php:1816 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 -#: ../../../../inc/mod/pages.php:1831 +#: ../../../../inc/mod/pages.php:1831 ../../../../inc/mod/pages.php:1904 msgid "Report queue" msgstr "Kolejka zgłoszeń" @@ -1131,6 +1153,7 @@ msgstr "Kolejka zgłoszeń" #: ../../../../inc/mod/pages.php:664 ../../../../inc/mod/pages.php:705 #: ../../../../inc/mod/pages.php:721 ../../../../inc/mod/pages.php:855 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:224 +#: ../../../../inc/mod/pages.php:918 msgid "Ban list" msgstr "Lista banów" @@ -1138,7 +1161,7 @@ msgstr "Lista banów" #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 #: ../../../../inc/mod/pages.php:1394 ../../../../inc/mod/pages.php:1528 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 -#: ../../../../inc/mod/pages.php:1543 +#: ../../../../inc/mod/pages.php:1543 ../../../../inc/mod/pages.php:1615 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -1153,6 +1176,7 @@ msgstr "Zmień swoje hasło" #: ../../../../inc/mod/pages.php:580 ../../../../inc/mod/pages.php:607 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:65 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:255 +#: ../../../../inc/mod/pages.php:644 ../../../../inc/mod/pages.php:671 msgid "Moderation log" msgstr "Log moderacji" @@ -1172,7 +1196,7 @@ msgstr "Pokaż konfigurację" #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 #: ../../../../inc/mod/pages.php:1830 ../../../../inc/mod/pages.php:1964 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 -#: ../../../../inc/mod/pages.php:1979 +#: ../../../../inc/mod/pages.php:1979 ../../../../inc/mod/pages.php:2052 msgid "Manage themes" msgstr "Zarządzaj dodatkami" @@ -1196,7 +1220,7 @@ msgstr "Wyrażenie:" #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:19 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:286 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:19 -#: ../../../../search.php:165 +#: ../../../../search.php:165 ../../../../search.php:168 msgid "Search" msgstr "Szukaj" @@ -1276,12 +1300,14 @@ msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 #: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 #: ../../../../inc/mod/pages.php:1948 ../../../../inc/mod/pages.php:1963 +#: ../../../../inc/mod/pages.php:2036 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 #: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 #: ../../../../inc/mod/pages.php:1950 ../../../../inc/mod/pages.php:1965 +#: ../../../../inc/mod/pages.php:2038 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -1334,6 +1360,7 @@ msgstr "Instaluj" #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 #: ../../../../inc/mod/pages.php:1741 ../../../../inc/mod/pages.php:1745 #: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:98 +#: ../../../../inc/mod/pages.php:1814 ../../../../inc/mod/pages.php:1818 msgid "Rebuild" msgstr "Przebuduj" @@ -1361,6 +1388,7 @@ msgstr "Postuj na tablicy ogłoszeń" #: ../../../../inc/mod/pages.php:333 ../../../../inc/mod/pages.php:346 #: ../../../../inc/mod/pages.php:480 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:96 +#: ../../../../inc/mod/pages.php:543 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -1468,13 +1496,13 @@ msgstr "Konfiguracja" #: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 #: ../../../../inc/mod/pages.php:272 ../../../../inc/mod/pages.php:285 -#: ../../../../inc/mod/pages.php:419 +#: ../../../../inc/mod/pages.php:419 ../../../../inc/mod/pages.php:481 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." #: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 #: ../../../../inc/mod/pages.php:800 ../../../../inc/mod/pages.php:823 -#: ../../../../inc/mod/pages.php:957 +#: ../../../../inc/mod/pages.php:957 ../../../../inc/mod/pages.php:1020 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." @@ -1484,6 +1512,7 @@ msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." #: ../../../../inc/config.php:689 ../../../../inc/config.php:747 #: ../../../../inc/config.php:753 ../../../../inc/config.php:750 +#: ../../../../inc/config.php:756 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." @@ -1493,11 +1522,13 @@ msgstr "Potwierdź akcję" #: ../../../../inc/mod/pages.php:222 ../../../../inc/mod/pages.php:239 #: ../../../../inc/mod/pages.php:252 ../../../../inc/mod/pages.php:386 +#: ../../../../inc/mod/pages.php:431 msgid "Edit board" msgstr "Edytuj board" #: ../../../../inc/mod/pages.php:270 ../../../../inc/mod/pages.php:287 #: ../../../../inc/mod/pages.php:300 ../../../../inc/mod/pages.php:434 +#: ../../../../inc/mod/pages.php:496 msgid "New board" msgstr "Nowy board" @@ -1511,6 +1542,7 @@ msgstr "Nowy board" #: ../../../../inc/mod/pages.php:628 ../../../../inc/mod/pages.php:762 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:247 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:65 +#: ../../../../inc/mod/pages.php:825 msgid "IP" msgstr "adres IP" @@ -1520,12 +1552,14 @@ msgstr "adres IP" #: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 #: ../../../../inc/mod/pages.php:772 ../../../../inc/mod/pages.php:1187 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:398 -#: ../../../../inc/mod/pages.php:1190 +#: ../../../../inc/mod/pages.php:1190 ../../../../inc/mod/pages.php:835 +#: ../../../../inc/mod/pages.php:1255 msgid "New ban" msgstr "Nowy ban" #: ../../../../inc/mod/pages.php:919 ../../../../inc/mod/pages.php:962 #: ../../../../inc/mod/pages.php:987 ../../../../inc/mod/pages.php:1121 +#: ../../../../inc/mod/pages.php:1184 msgid "Impossible to move thread; there is only one board." msgstr "Nie można przenieść wątku; istnieje tylko jeden board." @@ -1533,6 +1567,7 @@ msgstr "Nie można przenieść wątku; istnieje tylko jeden board." #: ../../../../inc/mod/pages.php:923 ../../../../inc/mod/pages.php:966 #: ../../../../inc/mod/pages.php:991 ../../../../inc/mod/pages.php:1125 #: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:106 +#: ../../../../inc/mod/pages.php:1188 msgid "Move thread" msgstr "Przenieś wątek" @@ -1541,6 +1576,7 @@ msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 #: ../../../../inc/mod/pages.php:1466 ../../../../inc/mod/pages.php:1515 #: ../../../../inc/mod/pages.php:1477 ../../../../inc/mod/pages.php:1530 +#: ../../../../inc/mod/pages.php:1549 ../../../../inc/mod/pages.php:1602 msgid "Edit user" msgstr "Edytuj użytkownika" @@ -1550,12 +1586,13 @@ msgstr "Edytuj użytkownika" #: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 #: ../../../../inc/mod/pages.php:1590 ../../../../inc/mod/pages.php:1662 #: ../../../../inc/mod/pages.php:1605 ../../../../inc/mod/pages.php:1677 +#: ../../../../inc/mod/pages.php:1750 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 #: ../../../../inc/mod/pages.php:1460 ../../../../inc/mod/pages.php:1594 -#: ../../../../inc/mod/pages.php:1609 +#: ../../../../inc/mod/pages.php:1609 ../../../../inc/mod/pages.php:1681 msgid "Private message" msgstr "Prywatna wiadomość" @@ -1563,39 +1600,39 @@ msgstr "Prywatna wiadomość" #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 #: ../../../../inc/mod/pages.php:1481 ../../../../inc/mod/pages.php:1615 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 -#: ../../../../inc/mod/pages.php:1630 +#: ../../../../inc/mod/pages.php:1630 ../../../../inc/mod/pages.php:1702 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 #: ../../../../inc/mod/pages.php:1804 ../../../../inc/mod/pages.php:1938 -#: ../../../../inc/mod/pages.php:1953 +#: ../../../../inc/mod/pages.php:1953 ../../../../inc/mod/pages.php:2026 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 #: ../../../../inc/mod/pages.php:1970 ../../../../inc/mod/pages.php:2104 -#: ../../../../inc/mod/pages.php:2119 +#: ../../../../inc/mod/pages.php:2119 ../../../../inc/mod/pages.php:2192 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 #: ../../../../inc/mod/pages.php:1892 ../../../../inc/mod/pages.php:2026 -#: ../../../../inc/mod/pages.php:2041 +#: ../../../../inc/mod/pages.php:2041 ../../../../inc/mod/pages.php:2114 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 #: ../../../../inc/mod/pages.php:1903 ../../../../inc/mod/pages.php:2037 -#: ../../../../inc/mod/pages.php:2052 +#: ../../../../inc/mod/pages.php:2052 ../../../../inc/mod/pages.php:2125 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 #: ../../../../inc/mod/pages.php:1931 ../../../../inc/mod/pages.php:2065 -#: ../../../../inc/mod/pages.php:2080 +#: ../../../../inc/mod/pages.php:2080 ../../../../inc/mod/pages.php:2153 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1607,24 +1644,24 @@ msgid "" msgstr "" #: ../../../../inc/config.php:704 ../../../../inc/config.php:710 -#: ../../../../inc/config.php:707 +#: ../../../../inc/config.php:707 ../../../../inc/config.php:713 msgid "Thread has reached its maximum reply limit." msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." #: ../../../../inc/config.php:705 ../../../../inc/config.php:711 -#: ../../../../inc/config.php:708 +#: ../../../../inc/config.php:708 ../../../../inc/config.php:714 msgid "Thread has reached its maximum image limit." msgstr "Ten temat osiągnął swój maksymalny limit obrazków." #: ../../../../inc/config.php:726 ../../../../inc/config.php:732 -#: ../../../../inc/config.php:729 +#: ../../../../inc/config.php:729 ../../../../inc/config.php:735 #, php-format msgid "That file already exists in this thread!" msgstr "Ten plik już istnieje w tym temacie!" #. Moderator errors #: ../../../../inc/config.php:733 ../../../../inc/config.php:739 -#: ../../../../inc/config.php:736 +#: ../../../../inc/config.php:736 ../../../../inc/config.php:742 #, php-format msgid "" "You are only allowed to unban %s users at a time. You tried to unban %u " @@ -1634,11 +1671,13 @@ msgstr "" #: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 #: ../../../../inc/mod/pages.php:2128 ../../../../inc/mod/pages.php:2143 +#: ../../../../inc/mod/pages.php:2216 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" #: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 #: ../../../../inc/mod/pages.php:2152 ../../../../inc/mod/pages.php:2167 +#: ../../../../inc/mod/pages.php:2240 msgid "Debug: SQL" msgstr "Debug: SQL" @@ -1651,7 +1690,7 @@ msgstr[1] "%count% odpowiedzi" msgstr[2] "%count% odpowiedzi" #. $results now contains the search results -#: ../../../../inc/mod/pages.php:290 +#: ../../../../inc/mod/pages.php:290 ../../../../inc/mod/pages.php:335 msgid "Search results" msgstr "Wyniki wyszukiwania" @@ -1976,11 +2015,11 @@ msgstr "Wyszukiwanie postów jest wyłączone" msgid "Wait a while before searching again, please." msgstr "Proszę poczekać chwilę przed ponownym szukaniem." -#: ../../../../search.php:128 +#: ../../../../search.php:128 ../../../../search.php:131 msgid "Query too broad." msgstr "Zapytanie zbyt szerokie." -#: ../../../../search.php:149 +#: ../../../../search.php:149 ../../../../search.php:152 #, php-format msgid "%d result in" msgid_plural "%d results in" @@ -1988,11 +2027,11 @@ msgstr[0] "%d wynik na" msgstr[1] "%d wyniki na" msgstr[2] "%d wyników na" -#: ../../../../search.php:160 +#: ../../../../search.php:160 ../../../../search.php:163 msgid "No results." msgstr "Brak wyników." -#: ../../../../inc/functions.php:594 +#: ../../../../inc/functions.php:594 ../../../../inc/functions.php:603 msgid "Banned!" msgstr "Zbanowany!" @@ -2005,6 +2044,7 @@ msgid "You are not banned." msgstr "Nie jesteś zbanowany." #: ../../../../inc/functions.php:549 ../../../../inc/functions.php:566 +#: ../../../../inc/functions.php:558 ../../../../inc/functions.php:575 msgid "second" msgid_plural "seconds" msgstr[0] "sekunda" @@ -2012,6 +2052,7 @@ msgstr[1] "sekundy" msgstr[2] "sekund" #: ../../../../inc/functions.php:551 ../../../../inc/functions.php:568 +#: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 msgid "minute" msgid_plural "minutes" msgstr[0] "minuta" @@ -2019,6 +2060,7 @@ msgstr[1] "minuty" msgstr[2] "minut" #: ../../../../inc/functions.php:553 ../../../../inc/functions.php:570 +#: ../../../../inc/functions.php:562 ../../../../inc/functions.php:579 msgid "hour" msgid_plural "hours" msgstr[0] "godzina" @@ -2026,6 +2068,7 @@ msgstr[1] "godziny" msgstr[2] "godzin" #: ../../../../inc/functions.php:555 ../../../../inc/functions.php:572 +#: ../../../../inc/functions.php:564 ../../../../inc/functions.php:581 msgid "day" msgid_plural "days" msgstr[0] "dzień" @@ -2033,6 +2076,7 @@ msgstr[1] "dni" msgstr[2] "dni" #: ../../../../inc/functions.php:557 ../../../../inc/functions.php:574 +#: ../../../../inc/functions.php:566 ../../../../inc/functions.php:583 msgid "week" msgid_plural "weeks" msgstr[0] "tydzień" @@ -2040,6 +2084,7 @@ msgstr[1] "tygodnie" msgstr[2] "tygodni" #: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 +#: ../../../../inc/functions.php:569 ../../../../inc/functions.php:586 msgid "year" msgid_plural "years" msgstr[0] "rok" @@ -2097,3 +2142,47 @@ msgstr "Nie ma dostępnych dodatków." #: ../../../../templates/cache/d1/99/467985632043e204070d354b8290.php:91 msgid "Install theme" msgstr "Zainstaluj dodatek" + +#: ../../../../inc/display.php:211 +#, php-format +msgid "Post too long. Click here to view the full text." +msgstr "Post za długi. Kliknij tutaj, aby zobaczyć jego pełną treść." + +#: ../../../../inc/display.php:342 ../../../../inc/display.php:443 +msgid "Delete file" +msgstr "Usuń plik" + +#: ../../../../inc/display.php:342 ../../../../inc/display.php:443 +msgid "Are you sure you want to delete this file?" +msgstr "Czy jesteś pewien, że chcesz usunąć ten plik?" + +#: ../../../../inc/display.php:431 +msgid "Delete all posts by IP across all boards" +msgstr "Usuń wszystkie posty z tego IP ze wszystkich boardów" + +#: ../../../../inc/display.php:431 +msgid "" +"Are you sure you want to delete all posts by this IP address, across all " +"boards?" +msgstr "" +"Czy jesteś pewien, że chcesz usunąć wszystkie posty z tego adresu IP, ze " +"wszystkich boardów?" + +#. Page footer +#: ../../../../inc/config.php:564 +msgid "" +"All trademarks, copyrights, comments, and images on this page are owned by " +"and are the responsibility of their respective parties." +msgstr "" +"Wszystkie znaki towarowe, prawa autorskie, komentarze oraz obrazki na tej " +"stronie są własnością i odpowiedzialność za nie spoczywa na ich odpowiednich " +"właścicielach." + +#: ../../../../inc/mod/pages.php:267 +msgid "There are no boards to search!" +msgstr "Nie ma boardów do przeszukania!" + +#. Print error +#: ../../../../inc/database.php:72 +msgid "Database error: " +msgstr "Błąd bazy danych: " From 9769e1f964eee89c2dcf1f585d665bd5e8d77357 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 01:56:04 -0400 Subject: [PATCH 174/289] i18n even more strings in inc/display.php --- inc/display.php | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/inc/display.php b/inc/display.php index c68af9d6..5da2f302 100644 --- a/inc/display.php +++ b/inc/display.php @@ -208,7 +208,7 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { $body = preg_replace('/&[^;]*$/', '', $body); } - $body .= 'Post too long. Click here to view the full text.'; + $body .= ''.sprintf(_('Post too long. Click here to view the full text.'), $url).''; } return $body; @@ -331,19 +331,19 @@ class Post { // 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['uri'] . '/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['uri'] . '/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['uri'] . '/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['uri'] . '/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['uri'] . '/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 . ''; From 6c2887ba9f3d20f23015e1a34e5170d219d5e648 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 02:06:34 -0400 Subject: [PATCH 175/289] Update Polish locale --- inc/locale/pl_PL/LC_MESSAGES/javascript.po | 3 +- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 19840 -> 20956 bytes inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 269 ++++++++++++++------- 3 files changed, 181 insertions(+), 91 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/javascript.po b/inc/locale/pl_PL/LC_MESSAGES/javascript.po index 482ec45f..ae1bb5c9 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/javascript.po +++ b/inc/locale/pl_PL/LC_MESSAGES/javascript.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-27 01:54-0400\n" +"POT-Creation-Date: 2013-08-01 01:58-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -42,6 +42,7 @@ msgid "Click to expand" msgstr "Kliknij aby rozwinąć" #: ../../../../js/expand.js:41 ../../../../js/expand.js:45 +#: ../../../../js/expand.js:43 msgid "Hide expanded replies" msgstr "Schowaj rozwinięte odpowiedzi" diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index bc603e6776603e1b1c86a613577a3c9ddc23aad2..73f434f793e0925bd7bd1f91516ca303002df41a 100644 GIT binary patch delta 6994 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 delta 6209 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 YCi_{HY-X{}WZQhuv6*disz*5|01Oa&UH||9 diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 20802b7d..8a46fda9 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-07-27 01:54-0400\n" +"POT-Creation-Date: 2013-08-01 01:58-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,6 +24,7 @@ msgstr "" #: ../../../../inc/functions.php:1041 ../../../../inc/functions.php:1055 #: ../../../../inc/functions.php:1039 ../../../../inc/functions.php:1053 #: ../../../../inc/functions.php:1068 ../../../../inc/functions.php:1082 +#: ../../../../inc/functions.php:1079 ../../../../inc/functions.php:1093 msgid "Previous" msgstr "Wstecz" @@ -33,6 +34,7 @@ msgstr "Wstecz" #: ../../../../inc/functions.php:1060 ../../../../inc/functions.php:1069 #: ../../../../inc/functions.php:1058 ../../../../inc/functions.php:1067 #: ../../../../inc/functions.php:1087 ../../../../inc/functions.php:1096 +#: ../../../../inc/functions.php:1098 ../../../../inc/functions.php:1107 msgid "Next" msgstr "Dalej" @@ -57,6 +59,7 @@ msgid "all boards" msgstr "wszystkie boardy" #: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 +#: ../../../../inc/config.php:334 msgid "You have been muted for unoriginal content." msgstr "Zostałeś zagłuszony za nieoryginalną treść." @@ -64,11 +67,12 @@ msgstr "Zostałeś zagłuszony za nieoryginalną treść." msgid "Anonymous" msgstr "Anonimowy" -#: /var/www/html/Tinyboard/inc/config.php:481 +#. The names on the post buttons. (On most imageboards, these are both "Post") +#: /var/www/html/Tinyboard/inc/config.php:481 ../../../../inc/config.php:552 msgid "New Topic" msgstr "Nowy wątek" -#: /var/www/html/Tinyboard/inc/config.php:482 +#: /var/www/html/Tinyboard/inc/config.php:482 ../../../../inc/config.php:553 msgid "New Reply" msgstr "Odpowiedz" @@ -84,19 +88,19 @@ msgstr "Szybka odpowiedź" #. Error messages #: /var/www/html/Tinyboard/inc/config.php:600 ../../../../inc/config.php:638 #: ../../../../inc/config.php:692 ../../../../inc/config.php:698 -#: ../../../../inc/config.php:695 +#: ../../../../inc/config.php:695 ../../../../inc/config.php:701 msgid "Lurk some more before posting." msgstr "Nie postuj pierwszego dnia." #: /var/www/html/Tinyboard/inc/config.php:601 ../../../../inc/config.php:639 #: ../../../../inc/config.php:693 ../../../../inc/config.php:699 -#: ../../../../inc/config.php:696 +#: ../../../../inc/config.php:696 ../../../../inc/config.php:702 msgid "You look like a bot." msgstr "Wyglądasz jak bot." #: /var/www/html/Tinyboard/inc/config.php:602 ../../../../inc/config.php:640 #: ../../../../inc/config.php:694 ../../../../inc/config.php:700 -#: ../../../../inc/config.php:697 +#: ../../../../inc/config.php:697 ../../../../inc/config.php:703 msgid "Your browser sent an invalid or no HTTP referer." msgstr "" "Twoja przeglądarka przesłała niepoprawny, bądź nie przesłała informacji o " @@ -104,161 +108,161 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:603 ../../../../inc/config.php:641 #: ../../../../inc/config.php:695 ../../../../inc/config.php:701 -#: ../../../../inc/config.php:698 +#: ../../../../inc/config.php:698 ../../../../inc/config.php:704 #, php-format msgid "The %s field was too long." msgstr "Pole %s jest za długie" #: /var/www/html/Tinyboard/inc/config.php:604 ../../../../inc/config.php:642 #: ../../../../inc/config.php:696 ../../../../inc/config.php:702 -#: ../../../../inc/config.php:699 +#: ../../../../inc/config.php:699 ../../../../inc/config.php:705 msgid "The body was too long." msgstr "Zawartość jest za długa." #: /var/www/html/Tinyboard/inc/config.php:605 ../../../../inc/config.php:643 #: ../../../../inc/config.php:697 ../../../../inc/config.php:703 -#: ../../../../inc/config.php:700 +#: ../../../../inc/config.php:700 ../../../../inc/config.php:706 msgid "The body was too short or empty." msgstr "Zawartość jest za krótka, bądź pusta." #: /var/www/html/Tinyboard/inc/config.php:606 ../../../../inc/config.php:644 #: ../../../../inc/config.php:698 ../../../../inc/config.php:704 -#: ../../../../inc/config.php:701 +#: ../../../../inc/config.php:701 ../../../../inc/config.php:707 msgid "You must upload an image." msgstr "Musisz wysłać obrazek." #: /var/www/html/Tinyboard/inc/config.php:607 ../../../../inc/config.php:645 #: ../../../../inc/config.php:699 ../../../../inc/config.php:705 -#: ../../../../inc/config.php:702 +#: ../../../../inc/config.php:702 ../../../../inc/config.php:708 msgid "The server failed to handle your upload." msgstr "Nie udało się obsłużyć twojego pliku." #: /var/www/html/Tinyboard/inc/config.php:608 ../../../../inc/config.php:646 #: ../../../../inc/config.php:700 ../../../../inc/config.php:706 -#: ../../../../inc/config.php:703 +#: ../../../../inc/config.php:703 ../../../../inc/config.php:709 msgid "Unsupported image format." msgstr "Niewspierany format obrazka." #: /var/www/html/Tinyboard/inc/config.php:609 ../../../../inc/config.php:647 #: ../../../../inc/config.php:701 ../../../../inc/config.php:707 -#: ../../../../inc/config.php:704 +#: ../../../../inc/config.php:704 ../../../../inc/config.php:710 msgid "Invalid board!" msgstr "Niepoprawny board!" #: /var/www/html/Tinyboard/inc/config.php:610 ../../../../inc/config.php:648 #: ../../../../inc/config.php:702 ../../../../inc/config.php:708 -#: ../../../../inc/config.php:705 +#: ../../../../inc/config.php:705 ../../../../inc/config.php:711 msgid "Thread specified does not exist." msgstr "Wybrany wątek nie istnieje." #: /var/www/html/Tinyboard/inc/config.php:611 ../../../../inc/config.php:649 #: ../../../../inc/config.php:703 ../../../../inc/config.php:709 -#: ../../../../inc/config.php:706 +#: ../../../../inc/config.php:706 ../../../../inc/config.php:712 msgid "Thread locked. You may not reply at this time." msgstr "Wątek jest zablokowany. Nie możesz w nim teraz postować." #: /var/www/html/Tinyboard/inc/config.php:612 ../../../../inc/config.php:650 #: ../../../../inc/config.php:706 ../../../../inc/config.php:712 -#: ../../../../inc/config.php:709 +#: ../../../../inc/config.php:709 ../../../../inc/config.php:715 msgid "You didn't make a post." msgstr "Nie zrobiłeś posta." #: /var/www/html/Tinyboard/inc/config.php:613 ../../../../inc/config.php:651 #: ../../../../inc/config.php:707 ../../../../inc/config.php:713 -#: ../../../../inc/config.php:710 +#: ../../../../inc/config.php:710 ../../../../inc/config.php:716 msgid "Flood detected; Post discarded." msgstr "Wykryto flood; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:614 ../../../../inc/config.php:652 #: ../../../../inc/config.php:708 ../../../../inc/config.php:714 -#: ../../../../inc/config.php:711 +#: ../../../../inc/config.php:711 ../../../../inc/config.php:717 msgid "Your request looks automated; Post discarded." msgstr "Twoje żądanie wygląda na zautomatyzowane; Post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:615 ../../../../inc/config.php:653 #: ../../../../inc/config.php:709 ../../../../inc/config.php:715 -#: ../../../../inc/config.php:712 +#: ../../../../inc/config.php:712 ../../../../inc/config.php:718 msgid "Unoriginal content!" msgstr "Nieoryginalna treść!" #: /var/www/html/Tinyboard/inc/config.php:616 ../../../../inc/config.php:654 #: ../../../../inc/config.php:710 ../../../../inc/config.php:716 -#: ../../../../inc/config.php:713 +#: ../../../../inc/config.php:713 ../../../../inc/config.php:719 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 -#: ../../../../inc/config.php:714 +#: ../../../../inc/config.php:714 ../../../../inc/config.php:720 #, php-format msgid "You are muted! Expires in %d seconds." msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 -#: ../../../../inc/config.php:715 +#: ../../../../inc/config.php:715 ../../../../inc/config.php:721 #, php-format msgid "Your IP address is listed in %s." msgstr "Twój adres IP jest na liście %s." #: /var/www/html/Tinyboard/inc/config.php:619 ../../../../inc/config.php:657 #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 -#: ../../../../inc/config.php:716 +#: ../../../../inc/config.php:716 ../../../../inc/config.php:722 msgid "Too many links; flood detected." msgstr "Zbyt dużo linków; wykryto flood." #: /var/www/html/Tinyboard/inc/config.php:620 ../../../../inc/config.php:658 #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 -#: ../../../../inc/config.php:717 +#: ../../../../inc/config.php:717 ../../../../inc/config.php:723 msgid "Too many cites; post discarded." msgstr "Zbyt dużo cytatów; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:621 ../../../../inc/config.php:659 #: ../../../../inc/config.php:715 ../../../../inc/config.php:721 -#: ../../../../inc/config.php:718 +#: ../../../../inc/config.php:718 ../../../../inc/config.php:724 msgid "Too many cross-board links; post discarded." msgstr "Zbyt dużo linków między boardami; post odrzucony." #: /var/www/html/Tinyboard/inc/config.php:622 ../../../../inc/config.php:660 #: ../../../../inc/config.php:716 ../../../../inc/config.php:722 -#: ../../../../inc/config.php:719 +#: ../../../../inc/config.php:719 ../../../../inc/config.php:725 msgid "You didn't select anything to delete." msgstr "Nie wybrano nic do usunięcia." #: /var/www/html/Tinyboard/inc/config.php:623 ../../../../inc/config.php:661 #: ../../../../inc/config.php:717 ../../../../inc/config.php:723 -#: ../../../../inc/config.php:720 +#: ../../../../inc/config.php:720 ../../../../inc/config.php:726 msgid "You didn't select anything to report." msgstr "Nie wybrano nic do zgłoszenia." #: /var/www/html/Tinyboard/inc/config.php:624 ../../../../inc/config.php:662 #: ../../../../inc/config.php:718 ../../../../inc/config.php:724 -#: ../../../../inc/config.php:721 +#: ../../../../inc/config.php:721 ../../../../inc/config.php:727 msgid "You can't report that many posts at once." msgstr "Nie możesz raportować tyle postów na raz." #: /var/www/html/Tinyboard/inc/config.php:625 ../../../../inc/config.php:663 #: ../../../../inc/config.php:719 ../../../../inc/config.php:725 -#: ../../../../inc/config.php:722 +#: ../../../../inc/config.php:722 ../../../../inc/config.php:728 msgid "Wrong password…" msgstr "Niepoprawne hasło" #: /var/www/html/Tinyboard/inc/config.php:626 ../../../../inc/config.php:664 #: ../../../../inc/config.php:720 ../../../../inc/config.php:726 -#: ../../../../inc/config.php:723 +#: ../../../../inc/config.php:723 ../../../../inc/config.php:729 msgid "Invalid image." msgstr "Niepoprawny obrazek." #: /var/www/html/Tinyboard/inc/config.php:627 ../../../../inc/config.php:665 #: ../../../../inc/config.php:721 ../../../../inc/config.php:727 -#: ../../../../inc/config.php:724 +#: ../../../../inc/config.php:724 ../../../../inc/config.php:730 msgid "Unknown file extension." msgstr "Nieznane rozszerzenie pliku." #: /var/www/html/Tinyboard/inc/config.php:628 ../../../../inc/config.php:666 #: ../../../../inc/config.php:722 ../../../../inc/config.php:728 -#: ../../../../inc/config.php:725 +#: ../../../../inc/config.php:725 ../../../../inc/config.php:731 msgid "Maximum file size: %maxsz% bytes
    Your file's size: %filesz% bytes" msgstr "" "Maksymalny rozmiar pliku: %maxsz% bajtów
    Rozmiar twojego pliku: %filesz% " @@ -266,33 +270,33 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:629 ../../../../inc/config.php:667 #: ../../../../inc/config.php:723 ../../../../inc/config.php:729 -#: ../../../../inc/config.php:726 +#: ../../../../inc/config.php:726 ../../../../inc/config.php:732 msgid "The file was too big." msgstr "Plik jest za duży." #: /var/www/html/Tinyboard/inc/config.php:630 ../../../../inc/config.php:668 #: ../../../../inc/config.php:724 ../../../../inc/config.php:730 -#: ../../../../inc/config.php:727 +#: ../../../../inc/config.php:727 ../../../../inc/config.php:733 msgid "Invalid archive!" msgstr "Niepoprawne archiwum!" #: /var/www/html/Tinyboard/inc/config.php:631 ../../../../inc/config.php:669 #: ../../../../inc/config.php:725 ../../../../inc/config.php:731 -#: ../../../../inc/config.php:728 +#: ../../../../inc/config.php:728 ../../../../inc/config.php:734 #, php-format msgid "That file already exists!" msgstr "Ten plik już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:632 ../../../../inc/config.php:670 #: ../../../../inc/config.php:727 ../../../../inc/config.php:733 -#: ../../../../inc/config.php:730 +#: ../../../../inc/config.php:730 ../../../../inc/config.php:736 #, php-format msgid "You'll have to wait another %s before deleting that." msgstr "Musisz poczekać kolejne %s przed usunięciem tego." #: /var/www/html/Tinyboard/inc/config.php:633 ../../../../inc/config.php:671 #: ../../../../inc/config.php:728 ../../../../inc/config.php:734 -#: ../../../../inc/config.php:731 +#: ../../../../inc/config.php:731 ../../../../inc/config.php:737 msgid "MIME type detection XSS exploit (IE) detected; post discarded." msgstr "" "Wykryto próbę wykorzystania luki wykrywania typu MIME (XSS w IE); post " @@ -300,31 +304,31 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:634 ../../../../inc/config.php:672 #: ../../../../inc/config.php:729 ../../../../inc/config.php:735 -#: ../../../../inc/config.php:732 +#: ../../../../inc/config.php:732 ../../../../inc/config.php:738 msgid "Couldn't make sense of the URL of the video you tried to embed." msgstr "Nie można było zrozumieć URL-a wideo, którego próbowano zapostować." #: /var/www/html/Tinyboard/inc/config.php:635 ../../../../inc/config.php:673 #: ../../../../inc/config.php:730 ../../../../inc/config.php:736 -#: ../../../../inc/config.php:733 +#: ../../../../inc/config.php:733 ../../../../inc/config.php:739 msgid "You seem to have mistyped the verification." msgstr "Wygląda na to, że przepisano źle weryfikację." #: /var/www/html/Tinyboard/inc/config.php:638 ../../../../inc/config.php:676 #: ../../../../inc/config.php:734 ../../../../inc/config.php:740 -#: ../../../../inc/config.php:737 +#: ../../../../inc/config.php:737 ../../../../inc/config.php:743 msgid "Invalid username and/or password." msgstr "Błędna nazwa użytkownika, bądź hasło" #: /var/www/html/Tinyboard/inc/config.php:639 ../../../../inc/config.php:677 #: ../../../../inc/config.php:735 ../../../../inc/config.php:741 -#: ../../../../inc/config.php:738 +#: ../../../../inc/config.php:738 ../../../../inc/config.php:744 msgid "You are not a mod…" msgstr "Nie jesteś moderatorem" #: /var/www/html/Tinyboard/inc/config.php:640 ../../../../inc/config.php:678 #: ../../../../inc/config.php:736 ../../../../inc/config.php:742 -#: ../../../../inc/config.php:739 +#: ../../../../inc/config.php:739 ../../../../inc/config.php:745 msgid "" "Invalid username and/or password. Your user may have been deleted or changed." msgstr "" @@ -333,65 +337,65 @@ msgstr "" #: /var/www/html/Tinyboard/inc/config.php:641 ../../../../inc/config.php:679 #: ../../../../inc/config.php:737 ../../../../inc/config.php:743 -#: ../../../../inc/config.php:740 +#: ../../../../inc/config.php:740 ../../../../inc/config.php:746 msgid "Invalid/malformed cookies." msgstr "Niepoprawne/zmodyfikowane pliki cookie." #: /var/www/html/Tinyboard/inc/config.php:642 ../../../../inc/config.php:680 #: ../../../../inc/config.php:738 ../../../../inc/config.php:744 -#: ../../../../inc/config.php:741 +#: ../../../../inc/config.php:741 ../../../../inc/config.php:747 msgid "Your browser didn't submit an input when it should have." msgstr "Twoja przeglądarka nie wysłała pola, kiedy powinna." #: /var/www/html/Tinyboard/inc/config.php:643 ../../../../inc/config.php:681 #: ../../../../inc/config.php:739 ../../../../inc/config.php:745 -#: ../../../../inc/config.php:742 +#: ../../../../inc/config.php:742 ../../../../inc/config.php:748 #, php-format msgid "The %s field is required." msgstr "Pole %s jest wymagane." #: /var/www/html/Tinyboard/inc/config.php:644 ../../../../inc/config.php:682 #: ../../../../inc/config.php:740 ../../../../inc/config.php:746 -#: ../../../../inc/config.php:743 +#: ../../../../inc/config.php:743 ../../../../inc/config.php:749 #, php-format msgid "The %s field was invalid." msgstr "Pole %s jest niepoprawne." #: /var/www/html/Tinyboard/inc/config.php:645 ../../../../inc/config.php:683 #: ../../../../inc/config.php:741 ../../../../inc/config.php:747 -#: ../../../../inc/config.php:744 +#: ../../../../inc/config.php:744 ../../../../inc/config.php:750 #, php-format msgid "There is already a %s board." msgstr "Już istnieje board %s" #: /var/www/html/Tinyboard/inc/config.php:646 ../../../../inc/config.php:684 #: ../../../../inc/config.php:742 ../../../../inc/config.php:748 -#: ../../../../inc/config.php:745 +#: ../../../../inc/config.php:745 ../../../../inc/config.php:751 msgid "You don't have permission to do that." msgstr "Nie masz uprawnień do wykonania tej czynności." #: /var/www/html/Tinyboard/inc/config.php:647 ../../../../inc/config.php:685 #: ../../../../inc/config.php:743 ../../../../inc/config.php:749 -#: ../../../../inc/config.php:746 +#: ../../../../inc/config.php:746 ../../../../inc/config.php:752 msgid "That post doesn't exist…" msgstr "Ten post nie istnieje..." #: /var/www/html/Tinyboard/inc/config.php:648 ../../../../inc/config.php:686 #: ../../../../inc/config.php:744 ../../../../inc/config.php:750 -#: ../../../../inc/config.php:747 +#: ../../../../inc/config.php:747 ../../../../inc/config.php:753 msgid "Page not found." msgstr "Strona nie znaleziona." #: /var/www/html/Tinyboard/inc/config.php:649 ../../../../inc/config.php:687 #: ../../../../inc/config.php:745 ../../../../inc/config.php:751 -#: ../../../../inc/config.php:748 +#: ../../../../inc/config.php:748 ../../../../inc/config.php:754 #, php-format msgid "That mod already exists!" msgstr "Ten moderator już istnieje!" #: /var/www/html/Tinyboard/inc/config.php:650 ../../../../inc/config.php:688 #: ../../../../inc/config.php:746 ../../../../inc/config.php:752 -#: ../../../../inc/config.php:749 +#: ../../../../inc/config.php:749 ../../../../inc/config.php:755 msgid "That theme doesn't exist!" msgstr "Ten dodatek nie istnieje!" @@ -430,6 +434,7 @@ msgstr "[Przenieś]" #. Default public ban message. #. In public ban messages, %length% is replaced with "for x days" or "permanently" (with %LENGTH% being the uppercase equivalent). #: /var/www/html/Tinyboard/inc/config.php:801 ../../../../inc/config.php:911 +#: ../../../../inc/config.php:917 msgid "USER WAS BANNED FOR THIS POST" msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" @@ -438,20 +443,21 @@ msgstr "UŻYTKOWNIK ZOSTAŁ ZBANOWANY ZA TEGO POSTA" msgid "Moved to %s." msgstr "Przeniesiono do %s." -#: /var/www/html/Tinyboard/inc/display.php:80 +#: /var/www/html/Tinyboard/inc/display.php:80 ../../../../inc/display.php:75 msgid "Error" msgstr "Błąd" -#: /var/www/html/Tinyboard/inc/display.php:81 +#: /var/www/html/Tinyboard/inc/display.php:81 ../../../../inc/display.php:76 msgid "An error has occured." msgstr "Wystąpił błąd." -#: /var/www/html/Tinyboard/inc/display.php:87 +#: /var/www/html/Tinyboard/inc/display.php:87 ../../../../inc/display.php:82 msgid "Go back" msgstr "Wróć" #: /var/www/html/Tinyboard/inc/display.php:97 ../../../../inc/display.php:91 #: ../../../../inc/mod/pages.php:59 ../../../../inc/mod/pages.php:62 +#: ../../../../inc/display.php:92 msgid "Login" msgstr "Logowanie" @@ -469,31 +475,34 @@ msgstr "" #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:27 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:27 #: ../../../../templates/cache/82/40/4c4a4b82f787181e6500ce83494d.php:27 +#: ../../../../inc/display.php:423 msgid "Delete" msgstr "Usuń" #: /var/www/html/Tinyboard/inc/display.php:272 -#: /var/www/html/Tinyboard/inc/display.php:365 +#: /var/www/html/Tinyboard/inc/display.php:365 ../../../../inc/display.php:423 msgid "Are you sure you want to delete this?" msgstr "Czy jesteś pewien, że chcesz to usunąć?" #: /var/www/html/Tinyboard/inc/display.php:276 -#: /var/www/html/Tinyboard/inc/display.php:369 +#: /var/www/html/Tinyboard/inc/display.php:369 ../../../../inc/display.php:427 msgid "Delete all posts by IP" msgstr "Usuń wszystkie posty z tego adresu IP" #: /var/www/html/Tinyboard/inc/display.php:276 -#: /var/www/html/Tinyboard/inc/display.php:369 +#: /var/www/html/Tinyboard/inc/display.php:369 ../../../../inc/display.php:427 msgid "Are you sure you want to delete all posts by this IP address?" msgstr "Czy na pewno chcesz usunąć wszystkie posty z tego adresu IP?" #: /var/www/html/Tinyboard/inc/display.php:280 -#: /var/www/html/Tinyboard/inc/display.php:373 +#: /var/www/html/Tinyboard/inc/display.php:373 ../../../../inc/display.php:334 +#: ../../../../inc/display.php:435 msgid "Ban" msgstr "Ban" #: /var/www/html/Tinyboard/inc/display.php:284 -#: /var/www/html/Tinyboard/inc/display.php:377 +#: /var/www/html/Tinyboard/inc/display.php:377 ../../../../inc/display.php:338 +#: ../../../../inc/display.php:439 msgid "Ban & Delete" msgstr "Usuń i zbanuj" @@ -506,34 +515,36 @@ msgstr "Usuń plik" #: /var/www/html/Tinyboard/inc/display.php:408 #: ../../../../inc/mod/pages.php:1080 ../../../../inc/mod/pages.php:1105 #: ../../../../inc/mod/pages.php:1239 ../../../../inc/mod/pages.php:1242 +#: ../../../../inc/display.php:346 ../../../../inc/display.php:470 +#: ../../../../inc/mod/pages.php:1314 msgid "Edit post" msgstr "Edytuj post" -#: /var/www/html/Tinyboard/inc/display.php:386 +#: /var/www/html/Tinyboard/inc/display.php:386 ../../../../inc/display.php:448 msgid "Make thread not sticky" msgstr "Odklej wątek" -#: /var/www/html/Tinyboard/inc/display.php:388 +#: /var/www/html/Tinyboard/inc/display.php:388 ../../../../inc/display.php:450 msgid "Make thread sticky" msgstr "Przyklej wątek" -#: /var/www/html/Tinyboard/inc/display.php:392 +#: /var/www/html/Tinyboard/inc/display.php:392 ../../../../inc/display.php:454 msgid "Allow thread to be bumped" msgstr "Zezwól wątkowi na bumpowanie" -#: /var/www/html/Tinyboard/inc/display.php:394 +#: /var/www/html/Tinyboard/inc/display.php:394 ../../../../inc/display.php:456 msgid "Prevent thread from being bumped" msgstr "Zabroń wątkowi na bumpowanie" -#: /var/www/html/Tinyboard/inc/display.php:399 +#: /var/www/html/Tinyboard/inc/display.php:399 ../../../../inc/display.php:461 msgid "Unlock thread" msgstr "Odblokuj wątek" -#: /var/www/html/Tinyboard/inc/display.php:401 +#: /var/www/html/Tinyboard/inc/display.php:401 ../../../../inc/display.php:463 msgid "Lock thread" msgstr "Zablokuj wątek" -#: /var/www/html/Tinyboard/inc/display.php:404 +#: /var/www/html/Tinyboard/inc/display.php:404 ../../../../inc/display.php:466 msgid "Move thread to another board" msgstr "Przenieś wątek na inny board" @@ -703,6 +714,8 @@ msgstr "Weryfikacja" #. line 72 #. line 3 #. line 72 +#. line 3 +#. line 72 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:149 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:22 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:165 @@ -787,6 +800,8 @@ msgstr "Flagi" #. line 99 #. line 98 #. line 99 +#. line 98 +#. line 99 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:188 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:191 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:215 @@ -854,6 +869,8 @@ msgstr "Przyklejony" #. line 103 #. line 102 #. line 103 +#. line 102 +#. line 103 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:200 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:203 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:227 @@ -921,6 +938,8 @@ msgstr "Zablokowany" #. line 107 #. line 106 #. line 107 +#. line 106 +#. line 107 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:212 #: /var/www/html/Tinyboard/templates/cache/1d/5e/91ec2bc929b77377b8b877d82db4.php:215 #: ../../../../templates/cache/d1/2d/eda9403e966240c642b13ca43eb6.php:239 @@ -1058,6 +1077,7 @@ msgstr "Tryb postowania: Odpowiedź" #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:172 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:127 #: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:173 +#: ../../../../templates/cache/aa/f6/f10fd83961bcd8c947af6ddf919d.php:174 msgid "Return" msgstr "Powrót" @@ -1079,6 +1099,7 @@ msgstr "Usuń post" #. line 106 #. line 8 #. line 32 +#. line 8 #: /var/www/html/Tinyboard/templates/cache/dd/1a/77e08f0c1b4ecf707c5a3e5a70be.php:32 #: /var/www/html/Tinyboard/mod.php:1801 #: ../../../../templates/cache/a8/a6/1022091d3402e085395b12e6279a.php:32 @@ -1116,6 +1137,7 @@ msgstr "Wiadomości prywatne" #: ../../../../inc/mod/pages.php:376 ../../../../inc/mod/pages.php:393 #: ../../../../inc/mod/pages.php:406 ../../../../inc/mod/pages.php:540 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:166 +#: ../../../../inc/mod/pages.php:604 msgid "News" msgstr "Aktualności" @@ -1123,7 +1145,7 @@ msgstr "Aktualności" #: ../../../../inc/mod/pages.php:1557 ../../../../inc/mod/pages.php:1657 #: ../../../../inc/mod/pages.php:1682 ../../../../inc/mod/pages.php:1816 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:207 -#: ../../../../inc/mod/pages.php:1831 +#: ../../../../inc/mod/pages.php:1831 ../../../../inc/mod/pages.php:1904 msgid "Report queue" msgstr "Kolejka zgłoszeń" @@ -1131,6 +1153,7 @@ msgstr "Kolejka zgłoszeń" #: ../../../../inc/mod/pages.php:664 ../../../../inc/mod/pages.php:705 #: ../../../../inc/mod/pages.php:721 ../../../../inc/mod/pages.php:855 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:224 +#: ../../../../inc/mod/pages.php:918 msgid "Ban list" msgstr "Lista banów" @@ -1138,7 +1161,7 @@ msgstr "Lista banów" #: ../../../../inc/mod/pages.php:1271 ../../../../inc/mod/pages.php:1369 #: ../../../../inc/mod/pages.php:1394 ../../../../inc/mod/pages.php:1528 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:232 -#: ../../../../inc/mod/pages.php:1543 +#: ../../../../inc/mod/pages.php:1543 ../../../../inc/mod/pages.php:1615 msgid "Manage users" msgstr "Zarządzaj użytkownikami" @@ -1153,6 +1176,7 @@ msgstr "Zmień swoje hasło" #: ../../../../inc/mod/pages.php:580 ../../../../inc/mod/pages.php:607 #: ../../../../templates/cache/55/dd/8ffe738533bd12359200e5745905.php:65 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:255 +#: ../../../../inc/mod/pages.php:644 ../../../../inc/mod/pages.php:671 msgid "Moderation log" msgstr "Log moderacji" @@ -1172,7 +1196,7 @@ msgstr "Pokaż konfigurację" #: ../../../../inc/mod/pages.php:1739 ../../../../inc/mod/pages.php:1805 #: ../../../../inc/mod/pages.php:1830 ../../../../inc/mod/pages.php:1964 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:247 -#: ../../../../inc/mod/pages.php:1979 +#: ../../../../inc/mod/pages.php:1979 ../../../../inc/mod/pages.php:2052 msgid "Manage themes" msgstr "Zarządzaj dodatkami" @@ -1196,7 +1220,7 @@ msgstr "Wyrażenie:" #: ../../../../templates/cache/c3/de/6ff26042c5b94cc80055e6f209d2.php:19 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:286 #: ../../../../templates/cache/4c/fb/a3bf13b0badfc09442bd42da1cce.php:19 -#: ../../../../search.php:165 +#: ../../../../search.php:165 ../../../../search.php:168 msgid "Search" msgstr "Szukaj" @@ -1276,12 +1300,14 @@ msgstr "Akcja" #: /var/www/html/Tinyboard/mod.php:528 ../../../../inc/mod/pages.php:1723 #: ../../../../inc/mod/pages.php:1789 ../../../../inc/mod/pages.php:1814 #: ../../../../inc/mod/pages.php:1948 ../../../../inc/mod/pages.php:1963 +#: ../../../../inc/mod/pages.php:2036 msgid "Themes directory doesn't exist!" msgstr "Katalog dodatków (themes) nie istnieje!" #: /var/www/html/Tinyboard/mod.php:530 ../../../../inc/mod/pages.php:1725 #: ../../../../inc/mod/pages.php:1791 ../../../../inc/mod/pages.php:1816 #: ../../../../inc/mod/pages.php:1950 ../../../../inc/mod/pages.php:1965 +#: ../../../../inc/mod/pages.php:2038 msgid "Cannot open themes directory; check permissions." msgstr "Nie można otworzyć katalogu dodatków (themes); sprawdź uprawnienia." @@ -1334,6 +1360,7 @@ msgstr "Instaluj" #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:263 #: ../../../../inc/mod/pages.php:1741 ../../../../inc/mod/pages.php:1745 #: ../../../../templates/cache/86/31/3f70fa8521e56d617b21133af4d8.php:98 +#: ../../../../inc/mod/pages.php:1814 ../../../../inc/mod/pages.php:1818 msgid "Rebuild" msgstr "Przebuduj" @@ -1361,6 +1388,7 @@ msgstr "Postuj na tablicy ogłoszeń" #: ../../../../inc/mod/pages.php:333 ../../../../inc/mod/pages.php:346 #: ../../../../inc/mod/pages.php:480 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:96 +#: ../../../../inc/mod/pages.php:543 msgid "Noticeboard" msgstr "Tablica ogłoszeń" @@ -1468,13 +1496,13 @@ msgstr "Konfiguracja" #: /var/www/html/Tinyboard/mod.php:2174 ../../../../inc/mod/pages.php:255 #: ../../../../inc/mod/pages.php:272 ../../../../inc/mod/pages.php:285 -#: ../../../../inc/mod/pages.php:419 +#: ../../../../inc/mod/pages.php:419 ../../../../inc/mod/pages.php:481 msgid "Couldn't open board after creation." msgstr "Nie można otworzyć boardu po utworzeniu." #: /var/www/html/Tinyboard/mod.php:2678 ../../../../inc/mod/pages.php:759 #: ../../../../inc/mod/pages.php:800 ../../../../inc/mod/pages.php:823 -#: ../../../../inc/mod/pages.php:957 +#: ../../../../inc/mod/pages.php:957 ../../../../inc/mod/pages.php:1020 msgid "Target and source board are the same." msgstr "Docelowy i źródłowy board są takie same." @@ -1484,6 +1512,7 @@ msgstr "Nie ma boardu na który można to przenieść; istnieje tylko jeden." #: ../../../../inc/config.php:689 ../../../../inc/config.php:747 #: ../../../../inc/config.php:753 ../../../../inc/config.php:750 +#: ../../../../inc/config.php:756 msgid "Invalid security token! Please go back and try again." msgstr "Niepoprawny token bezpieczeństwa! Proszę cofnąć i spróbować ponownie." @@ -1493,11 +1522,13 @@ msgstr "Potwierdź akcję" #: ../../../../inc/mod/pages.php:222 ../../../../inc/mod/pages.php:239 #: ../../../../inc/mod/pages.php:252 ../../../../inc/mod/pages.php:386 +#: ../../../../inc/mod/pages.php:431 msgid "Edit board" msgstr "Edytuj board" #: ../../../../inc/mod/pages.php:270 ../../../../inc/mod/pages.php:287 #: ../../../../inc/mod/pages.php:300 ../../../../inc/mod/pages.php:434 +#: ../../../../inc/mod/pages.php:496 msgid "New board" msgstr "Nowy board" @@ -1511,6 +1542,7 @@ msgstr "Nowy board" #: ../../../../inc/mod/pages.php:628 ../../../../inc/mod/pages.php:762 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:247 #: ../../../../templates/cache/18/9c/c365d711719f494c684aab98a4ae.php:65 +#: ../../../../inc/mod/pages.php:825 msgid "IP" msgstr "adres IP" @@ -1520,12 +1552,14 @@ msgstr "adres IP" #: ../../../../inc/mod/pages.php:638 ../../../../inc/mod/pages.php:1053 #: ../../../../inc/mod/pages.php:772 ../../../../inc/mod/pages.php:1187 #: ../../../../templates/cache/24/a0/f1ddafed7a8f9625e747a5ca33f5.php:398 -#: ../../../../inc/mod/pages.php:1190 +#: ../../../../inc/mod/pages.php:1190 ../../../../inc/mod/pages.php:835 +#: ../../../../inc/mod/pages.php:1255 msgid "New ban" msgstr "Nowy ban" #: ../../../../inc/mod/pages.php:919 ../../../../inc/mod/pages.php:962 #: ../../../../inc/mod/pages.php:987 ../../../../inc/mod/pages.php:1121 +#: ../../../../inc/mod/pages.php:1184 msgid "Impossible to move thread; there is only one board." msgstr "Nie można przenieść wątku; istnieje tylko jeden board." @@ -1533,6 +1567,7 @@ msgstr "Nie można przenieść wątku; istnieje tylko jeden board." #: ../../../../inc/mod/pages.php:923 ../../../../inc/mod/pages.php:966 #: ../../../../inc/mod/pages.php:991 ../../../../inc/mod/pages.php:1125 #: ../../../../templates/cache/dd/1a/7d548894242b9d7bff167de40716.php:106 +#: ../../../../inc/mod/pages.php:1188 msgid "Move thread" msgstr "Przenieś wątek" @@ -1541,6 +1576,7 @@ msgstr "Przenieś wątek" #: ../../../../inc/mod/pages.php:1332 ../../../../inc/mod/pages.php:1381 #: ../../../../inc/mod/pages.php:1466 ../../../../inc/mod/pages.php:1515 #: ../../../../inc/mod/pages.php:1477 ../../../../inc/mod/pages.php:1530 +#: ../../../../inc/mod/pages.php:1549 ../../../../inc/mod/pages.php:1602 msgid "Edit user" msgstr "Edytuj użytkownika" @@ -1550,12 +1586,13 @@ msgstr "Edytuj użytkownika" #: ../../../../inc/mod/pages.php:1456 ../../../../inc/mod/pages.php:1528 #: ../../../../inc/mod/pages.php:1590 ../../../../inc/mod/pages.php:1662 #: ../../../../inc/mod/pages.php:1605 ../../../../inc/mod/pages.php:1677 +#: ../../../../inc/mod/pages.php:1750 msgid "New PM for" msgstr "Nowe PW dla" #: ../../../../inc/mod/pages.php:1337 ../../../../inc/mod/pages.php:1435 #: ../../../../inc/mod/pages.php:1460 ../../../../inc/mod/pages.php:1594 -#: ../../../../inc/mod/pages.php:1609 +#: ../../../../inc/mod/pages.php:1609 ../../../../inc/mod/pages.php:1681 msgid "Private message" msgstr "Prywatna wiadomość" @@ -1563,39 +1600,39 @@ msgstr "Prywatna wiadomość" #: ../../../../inc/mod/pages.php:1358 ../../../../inc/mod/pages.php:1456 #: ../../../../inc/mod/pages.php:1481 ../../../../inc/mod/pages.php:1615 #: ../../../../templates/cache/3a/df/ab38a77244cb9c729b4c6f99759a.php:171 -#: ../../../../inc/mod/pages.php:1630 +#: ../../../../inc/mod/pages.php:1630 ../../../../inc/mod/pages.php:1702 msgid "PM inbox" msgstr "Odebrane PW" #: ../../../../inc/mod/pages.php:1679 ../../../../inc/mod/pages.php:1779 #: ../../../../inc/mod/pages.php:1804 ../../../../inc/mod/pages.php:1938 -#: ../../../../inc/mod/pages.php:1953 +#: ../../../../inc/mod/pages.php:1953 ../../../../inc/mod/pages.php:2026 msgid "Config editor" msgstr "Edytor konfiguracji" #: ../../../../inc/mod/pages.php:1713 ../../../../inc/mod/pages.php:1945 #: ../../../../inc/mod/pages.php:1970 ../../../../inc/mod/pages.php:2104 -#: ../../../../inc/mod/pages.php:2119 +#: ../../../../inc/mod/pages.php:2119 ../../../../inc/mod/pages.php:2192 msgid "Debug: Anti-spam" msgstr "Debug: Antyspam" #: ../../../../inc/mod/pages.php:1801 ../../../../inc/mod/pages.php:1867 #: ../../../../inc/mod/pages.php:1892 ../../../../inc/mod/pages.php:2026 -#: ../../../../inc/mod/pages.php:2041 +#: ../../../../inc/mod/pages.php:2041 ../../../../inc/mod/pages.php:2114 #, php-format msgid "Installed theme: %s" msgstr "Zainstalowano dodatek: %s" #: ../../../../inc/mod/pages.php:1811 ../../../../inc/mod/pages.php:1878 #: ../../../../inc/mod/pages.php:1903 ../../../../inc/mod/pages.php:2037 -#: ../../../../inc/mod/pages.php:2052 +#: ../../../../inc/mod/pages.php:2052 ../../../../inc/mod/pages.php:2125 #, php-format msgid "Configuring theme: %s" msgstr "Konfigurowanie dodatku: %s" #: ../../../../inc/mod/pages.php:1839 ../../../../inc/mod/pages.php:1906 #: ../../../../inc/mod/pages.php:1931 ../../../../inc/mod/pages.php:2065 -#: ../../../../inc/mod/pages.php:2080 +#: ../../../../inc/mod/pages.php:2080 ../../../../inc/mod/pages.php:2153 #, php-format msgid "Rebuilt theme: %s" msgstr "Przebudowano dodatek: %s" @@ -1607,24 +1644,24 @@ msgid "" msgstr "" #: ../../../../inc/config.php:704 ../../../../inc/config.php:710 -#: ../../../../inc/config.php:707 +#: ../../../../inc/config.php:707 ../../../../inc/config.php:713 msgid "Thread has reached its maximum reply limit." msgstr "Ten temat osiągnął swój maksymalny limit odpowiedzi." #: ../../../../inc/config.php:705 ../../../../inc/config.php:711 -#: ../../../../inc/config.php:708 +#: ../../../../inc/config.php:708 ../../../../inc/config.php:714 msgid "Thread has reached its maximum image limit." msgstr "Ten temat osiągnął swój maksymalny limit obrazków." #: ../../../../inc/config.php:726 ../../../../inc/config.php:732 -#: ../../../../inc/config.php:729 +#: ../../../../inc/config.php:729 ../../../../inc/config.php:735 #, php-format msgid "That file already exists in this thread!" msgstr "Ten plik już istnieje w tym temacie!" #. Moderator errors #: ../../../../inc/config.php:733 ../../../../inc/config.php:739 -#: ../../../../inc/config.php:736 +#: ../../../../inc/config.php:736 ../../../../inc/config.php:742 #, php-format msgid "" "You are only allowed to unban %s users at a time. You tried to unban %u " @@ -1634,11 +1671,13 @@ msgstr "" #: ../../../../inc/mod/pages.php:1969 ../../../../inc/mod/pages.php:1994 #: ../../../../inc/mod/pages.php:2128 ../../../../inc/mod/pages.php:2143 +#: ../../../../inc/mod/pages.php:2216 msgid "Debug: Recent posts" msgstr "Debug: Ostatnie posty" #: ../../../../inc/mod/pages.php:1993 ../../../../inc/mod/pages.php:2018 #: ../../../../inc/mod/pages.php:2152 ../../../../inc/mod/pages.php:2167 +#: ../../../../inc/mod/pages.php:2240 msgid "Debug: SQL" msgstr "Debug: SQL" @@ -1651,7 +1690,7 @@ msgstr[1] "%count% odpowiedzi" msgstr[2] "%count% odpowiedzi" #. $results now contains the search results -#: ../../../../inc/mod/pages.php:290 +#: ../../../../inc/mod/pages.php:290 ../../../../inc/mod/pages.php:335 msgid "Search results" msgstr "Wyniki wyszukiwania" @@ -1976,11 +2015,11 @@ msgstr "Wyszukiwanie postów jest wyłączone" msgid "Wait a while before searching again, please." msgstr "Proszę poczekać chwilę przed ponownym szukaniem." -#: ../../../../search.php:128 +#: ../../../../search.php:128 ../../../../search.php:131 msgid "Query too broad." msgstr "Zapytanie zbyt szerokie." -#: ../../../../search.php:149 +#: ../../../../search.php:149 ../../../../search.php:152 #, php-format msgid "%d result in" msgid_plural "%d results in" @@ -1988,11 +2027,11 @@ msgstr[0] "%d wynik na" msgstr[1] "%d wyniki na" msgstr[2] "%d wyników na" -#: ../../../../search.php:160 +#: ../../../../search.php:160 ../../../../search.php:163 msgid "No results." msgstr "Brak wyników." -#: ../../../../inc/functions.php:594 +#: ../../../../inc/functions.php:594 ../../../../inc/functions.php:603 msgid "Banned!" msgstr "Zbanowany!" @@ -2005,6 +2044,7 @@ msgid "You are not banned." msgstr "Nie jesteś zbanowany." #: ../../../../inc/functions.php:549 ../../../../inc/functions.php:566 +#: ../../../../inc/functions.php:558 ../../../../inc/functions.php:575 msgid "second" msgid_plural "seconds" msgstr[0] "sekunda" @@ -2012,6 +2052,7 @@ msgstr[1] "sekundy" msgstr[2] "sekund" #: ../../../../inc/functions.php:551 ../../../../inc/functions.php:568 +#: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 msgid "minute" msgid_plural "minutes" msgstr[0] "minuta" @@ -2019,6 +2060,7 @@ msgstr[1] "minuty" msgstr[2] "minut" #: ../../../../inc/functions.php:553 ../../../../inc/functions.php:570 +#: ../../../../inc/functions.php:562 ../../../../inc/functions.php:579 msgid "hour" msgid_plural "hours" msgstr[0] "godzina" @@ -2026,6 +2068,7 @@ msgstr[1] "godziny" msgstr[2] "godzin" #: ../../../../inc/functions.php:555 ../../../../inc/functions.php:572 +#: ../../../../inc/functions.php:564 ../../../../inc/functions.php:581 msgid "day" msgid_plural "days" msgstr[0] "dzień" @@ -2033,6 +2076,7 @@ msgstr[1] "dni" msgstr[2] "dni" #: ../../../../inc/functions.php:557 ../../../../inc/functions.php:574 +#: ../../../../inc/functions.php:566 ../../../../inc/functions.php:583 msgid "week" msgid_plural "weeks" msgstr[0] "tydzień" @@ -2040,6 +2084,7 @@ msgstr[1] "tygodnie" msgstr[2] "tygodni" #: ../../../../inc/functions.php:560 ../../../../inc/functions.php:577 +#: ../../../../inc/functions.php:569 ../../../../inc/functions.php:586 msgid "year" msgid_plural "years" msgstr[0] "rok" @@ -2097,3 +2142,47 @@ msgstr "Nie ma dostępnych dodatków." #: ../../../../templates/cache/d1/99/467985632043e204070d354b8290.php:91 msgid "Install theme" msgstr "Zainstaluj dodatek" + +#: ../../../../inc/display.php:211 +#, php-format +msgid "Post too long. Click here to view the full text." +msgstr "Post za długi. Kliknij tutaj, aby zobaczyć jego pełną treść." + +#: ../../../../inc/display.php:342 ../../../../inc/display.php:443 +msgid "Delete file" +msgstr "Usuń plik" + +#: ../../../../inc/display.php:342 ../../../../inc/display.php:443 +msgid "Are you sure you want to delete this file?" +msgstr "Czy jesteś pewien, że chcesz usunąć ten plik?" + +#: ../../../../inc/display.php:431 +msgid "Delete all posts by IP across all boards" +msgstr "Usuń wszystkie posty z tego IP ze wszystkich boardów" + +#: ../../../../inc/display.php:431 +msgid "" +"Are you sure you want to delete all posts by this IP address, across all " +"boards?" +msgstr "" +"Czy jesteś pewien, że chcesz usunąć wszystkie posty z tego adresu IP, ze " +"wszystkich boardów?" + +#. Page footer +#: ../../../../inc/config.php:564 +msgid "" +"All trademarks, copyrights, comments, and images on this page are owned by " +"and are the responsibility of their respective parties." +msgstr "" +"Wszystkie znaki towarowe, prawa autorskie, komentarze oraz obrazki na tej " +"stronie są własnością i odpowiedzialność za nie spoczywa na ich odpowiednich " +"właścicielach." + +#: ../../../../inc/mod/pages.php:267 +msgid "There are no boards to search!" +msgstr "Nie ma boardów do przeszukania!" + +#. Print error +#: ../../../../inc/database.php:72 +msgid "Database error: " +msgstr "Błąd bazy danych: " From 0aac198c42dde176b22bba43b8b33460e6c9fda8 Mon Sep 17 00:00:00 2001 From: Jakub Skrzypnik Date: Thu, 1 Aug 2013 08:46:24 +0200 Subject: [PATCH 176/289] Correcting polish locale a bit --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 8a46fda9..e8caf477 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -61,7 +61,7 @@ msgstr "wszystkie boardy" #: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 #: ../../../../inc/config.php:334 msgid "You have been muted for unoriginal content." -msgstr "Zostałeś zagłuszony za nieoryginalną treść." +msgstr "Zostałeś wyciszony za nieoryginalną treść." #: /var/www/html/Tinyboard/inc/config.php:447 msgid "Anonymous" @@ -197,7 +197,7 @@ msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 #, php-format msgid "You are muted! Expires in %d seconds." -msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." +msgstr "Jesteś wyciszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 From 731905ed05eb7b2d516253594bc328a9a8475a69 Mon Sep 17 00:00:00 2001 From: Jakub Skrzypnik Date: Thu, 1 Aug 2013 08:49:14 +0200 Subject: [PATCH 177/289] Correcting polish locale a bit --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index e8caf477..a5a58616 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -190,7 +190,7 @@ msgstr "Nieoryginalna treść!" #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." -msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." +msgstr "Nieoryginalna treść! Zostałeś wyciszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 From 7dd57432a22e95397b509cba3c319cca1d5e364f Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 02:52:35 -0400 Subject: [PATCH 178/289] Compile Polish locale --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 20956 -> 20950 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 73f434f793e0925bd7bd1f91516ca303002df41a..d2807a3794a0d8d95da8d8effc6553a03cfc3c5d 100644 GIT binary patch delta 646 zcmcb!nDN?T#tmQi>n#}=82Y^!7^E2(7*2XIFvu`4Fg*2QVBlq7U|{lQVBlt8U=Z+T zU=U(pV32{*`cQEvZw3Z71_lN{Zw3Z21_p*uZw3Y(1_p*4Zw3Zq1_p+iQ1xfM85o!u z7#JQv)jjcMV9;e?VEFCLP|qOFz`&sC12MqShk+rKfq@~y2V&4V9|i_d1_p-PJ`4#Z3W82Y^!7^E2(7*2aJFvu`4Fg*8SVBlq7U|{iPVBlt8U=Z?V zU=U(pV332-hEQ=AZw3Z71_p)zZw3Z21_p+3Zw3Y(1_p*aZw3Zq1_p-NQ1$1%85o!u z7#JQw)jjiOV9;k^VEF6JP|qOFz`&sE12MqWhk+rKfq@~$2V&4B9|i_d1_p-vJ`4I%F7#J8#d>O#{Q+*j23>g?0YJC|Pgc%qZ*84IrNH8!k9EOVD z@nv8TVPIh3^Mlx<><4k6m0vvrgCNMoehdss3=9knevlAY?8m@h#=yXEz>k3;gMoqJ zyB`CC4Fdy1fe$+!5fBhL4SQ!`?m;x9W_!t-%I07Ji@c@WM*#L;a8c=b4DBm=I zfkBdifx!k!hXpV&@G~$l6a+9Z7=b(lRkt|+;`3br3=EnK3=9_oAR!g`8)_hbAjBu4 zP+BpNfk77(HGz;Ij}C-5s5%g0P-7s(p)&#@4p<%tNizon85npN7#PlP_7uvnV5>?@ YKiX8fd8?NnBaF@NQwwKz`1-K`0El8*mH+?% From 0a026c8f3fd62de31e3e7a0c091f0aed4fa5164c Mon Sep 17 00:00:00 2001 From: Jakub Skrzypnik Date: Thu, 1 Aug 2013 08:46:24 +0200 Subject: [PATCH 179/289] Correcting polish locale a bit --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index 8a46fda9..e8caf477 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -61,7 +61,7 @@ msgstr "wszystkie boardy" #: /var/www/html/Tinyboard/inc/config.php:305 ../../../../inc/config.php:330 #: ../../../../inc/config.php:334 msgid "You have been muted for unoriginal content." -msgstr "Zostałeś zagłuszony za nieoryginalną treść." +msgstr "Zostałeś wyciszony za nieoryginalną treść." #: /var/www/html/Tinyboard/inc/config.php:447 msgid "Anonymous" @@ -197,7 +197,7 @@ msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." #: ../../../../inc/config.php:714 ../../../../inc/config.php:720 #, php-format msgid "You are muted! Expires in %d seconds." -msgstr "Jesteś zagłuszony! Wygasa w ciągu %d sekund." +msgstr "Jesteś wyciszony! Wygasa w ciągu %d sekund." #: /var/www/html/Tinyboard/inc/config.php:618 ../../../../inc/config.php:656 #: ../../../../inc/config.php:712 ../../../../inc/config.php:718 From 00600f241ff0357f57abdcd3a9f4c88cbfc1f5bd Mon Sep 17 00:00:00 2001 From: Jakub Skrzypnik Date: Thu, 1 Aug 2013 08:49:14 +0200 Subject: [PATCH 180/289] Correcting polish locale a bit --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po index e8caf477..a5a58616 100644 --- a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po +++ b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.po @@ -190,7 +190,7 @@ msgstr "Nieoryginalna treść!" #: ../../../../inc/config.php:713 ../../../../inc/config.php:719 #, php-format msgid "Unoriginal content! You have been muted for %d seconds." -msgstr "Nieoryginalna treść! Zostałeś zagłuszony na %d sekund." +msgstr "Nieoryginalna treść! Zostałeś wyciszony na %d sekund." #: /var/www/html/Tinyboard/inc/config.php:617 ../../../../inc/config.php:655 #: ../../../../inc/config.php:711 ../../../../inc/config.php:717 From 9487eb4ac74afabe08b4c6a582bf385bda224aa3 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 02:52:35 -0400 Subject: [PATCH 181/289] Compile Polish locale --- inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo | Bin 20956 -> 20950 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo b/inc/locale/pl_PL/LC_MESSAGES/tinyboard.mo index 73f434f793e0925bd7bd1f91516ca303002df41a..d2807a3794a0d8d95da8d8effc6553a03cfc3c5d 100644 GIT binary patch delta 646 zcmcb!nDN?T#tmQi>n#}=82Y^!7^E2(7*2XIFvu`4Fg*2QVBlq7U|{lQVBlt8U=Z+T zU=U(pV32{*`cQEvZw3Z71_lN{Zw3Z21_p*uZw3Y(1_p*4Zw3Zq1_p+iQ1xfM85o!u z7#JQv)jjcMV9;e?VEFCLP|qOFz`&sC12MqShk+rKfq@~y2V&4V9|i_d1_p-PJ`4#Z3W82Y^!7^E2(7*2aJFvu`4Fg*8SVBlq7U|{iPVBlt8U=Z?V zU=U(pV332-hEQ=AZw3Z71_p)zZw3Z21_p+3Zw3Y(1_p*aZw3Zq1_p-NQ1$1%85o!u z7#JQw)jjiOV9;k^VEF6JP|qOFz`&sE12MqWhk+rKfq@~$2V&4B9|i_d1_p-vJ`4I%F7#J8#d>O#{Q+*j23>g?0YJC|Pgc%qZ*84IrNH8!k9EOVD z@nv8TVPIh3^Mlx<><4k6m0vvrgCNMoehdss3=9knevlAY?8m@h#=yXEz>k3;gMoqJ zyB`CC4Fdy1fe$+!5fBhL4SQ!`?m;x9W_!t-%I07Ji@c@WM*#L;a8c=b4DBm=I zfkBdifx!k!hXpV&@G~$l6a+9Z7=b(lRkt|+;`3br3=EnK3=9_oAR!g`8)_hbAjBu4 zP+BpNfk77(HGz;Ij}C-5s5%g0P-7s(p)&#@4p<%tNizon85npN7#PlP_7uvnV5>?@ YKiX8fd8?NnBaF@NQwwKz`1-K`0El8*mH+?% From c1912b2a90c15eb46196abe60cd4ed0c324ec634 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 03:30:45 -0400 Subject: [PATCH 182/289] Move stylesheets from Tinyboard-Tools here --- stylesheets/dark.css | 150 ++++++++ stylesheets/futaba+vichan.css | 88 +++++ stylesheets/img/fade-miku.png | Bin 0 -> 234 bytes stylesheets/img/fade-yellow.png | Bin 0 -> 47975 bytes stylesheets/img/testorange_bg.gif | Bin 0 -> 2618 bytes stylesheets/img/testorange_f_bg.gif | Bin 0 -> 143 bytes stylesheets/img/testorange_testo.png | Bin 0 -> 20588 bytes stylesheets/img/testorange_textarea_bg.gif | Bin 0 -> 292 bytes stylesheets/img/testorange_top_bg.gif | Bin 0 -> 6551 bytes stylesheets/miku.css | 87 +++++ stylesheets/testorange.css | 208 +++++++++++ stylesheets/wasabi.css | 391 +++++++++++++++++++++ 12 files changed, 924 insertions(+) create mode 100644 stylesheets/dark.css create mode 100644 stylesheets/futaba+vichan.css create mode 100644 stylesheets/img/fade-miku.png create mode 100644 stylesheets/img/fade-yellow.png create mode 100644 stylesheets/img/testorange_bg.gif create mode 100644 stylesheets/img/testorange_f_bg.gif create mode 100644 stylesheets/img/testorange_testo.png create mode 100644 stylesheets/img/testorange_textarea_bg.gif create mode 100644 stylesheets/img/testorange_top_bg.gif create mode 100644 stylesheets/miku.css create mode 100644 stylesheets/testorange.css create mode 100644 stylesheets/wasabi.css diff --git a/stylesheets/dark.css b/stylesheets/dark.css new file mode 100644 index 00000000..2248c9d3 --- /dev/null +++ b/stylesheets/dark.css @@ -0,0 +1,150 @@ +/** + * dark.css + * For AwsumChan by Circlepuller + */ +body { + background: #1E1E1E; + color: #999999; + font-family: sans-serif; + font-size: 12px; +} +h1 { + font-size: 20pt; + text-align: center; + letter-spacing: 0px; +} +div.title, h1 { + color: lime; + font-family: Arial, Helvetica, sans-serif; +} +div.title p { + font-size: 10px; +} +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; +} +a.post_no { + color: #AAAAAA; + text-decoration: none; +} +a.post_no:hover { + color: maroon; + text-decoration: underline overline; +} +div.post.reply { + background: #333333; + border: #555555 1px solid; +} +div.post.reply.highlighted { + background: transparent; + border: transparent 1px solid; +} +div.post.reply div.body a:link, div.post.reply div.body a:visited { + color: #CCCCCC; +} +div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { + color: #FF0000; +} +p.intro span.subject { + font-size: 12px; + font-family: sans-serif; + color: #446655; + font-weight: 800; +} +p.intro span.name { + color: #00CC00; + font-weight: 800; +} +p.intro a.capcode, p.intro a.nametag { + color: magenta; + margin-left: 0; +} +p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { + color: #00CCCC; +} +input[type="text"], textarea, select { + background: #333333; + color: #CCCCCC; + border: #666666 1px solid; + padding-left: 5px; + padding-right: -5px; + font-family: sans-serif; + font-size: 10pt; +} +input[type="password"] { + background: #333333; + color: #CCCCCC; + border: #666666 1px solid; +} +form table tr th { + background: #333333; + color: #AAAAAA; + font-weight: 800; + text-align: left; + padding: 0; +} +div.banner { + background: #00AA00; + color: #FFFFFF; + text-align: center; + width: 250px; + padding: 4px; + padding-left: 12px; + padding-right: 12px; + margin-left: auto; + margin-right: auto; + font-size: 12px; +} +input[type="submit"] { + background: #333333; + border: #888888 1px solid; + color: #CCCCCC; +} +input[type="submit"]:hover { + background: #555555; + border: #888888 1px solid; + color: #FF0000; +} +p.fileinfo a:hover { + text-decoration: underline; +} +span.trip { + color: #AAAAAA; +} +div.pages { + color: #AAAAAA; + background: #333333; + border: #666666 1px solid; + font-family: sans-serif; + font-size: 10pt; +} +div.pages a.selected { + color: #CCCCCC; +} +hr { + height: 1px; + border: #333333 1px solid; +} +div.boardlist { + color: #999999; +} +div.ban { + background-color: transparent; + border: transparent 0px solid; +} +div.ban h2 { + background: transparent; + color: lime; + font-size: 12px; +} +table.modlog tr th { + background: #333333; + color: #AAAAAA; +} diff --git a/stylesheets/futaba+vichan.css b/stylesheets/futaba+vichan.css new file mode 100644 index 00000000..be0ab672 --- /dev/null +++ b/stylesheets/futaba+vichan.css @@ -0,0 +1,88 @@ +/* +piwnichan style, based on futaba.css of Tinyboard */ + +body { + background: #ffe; + color: #800000; + font-family: sans-serif; + font-size: 13px; +} +div.title h1 { + font-size: 24px; +} +div.title p { + font-size: 10px; +} +div.pages { + font-size: 13px !important; +} +a:link, a:visited, p.intro a.email span.name { + color: #0000ff; + font-size: inherit; + text-decoration: inherit; +} +a:link:hover { + color: #d00; + text-decoration: inherit; +} +span.omitted { + color: gray; +} +a.post_no { + color: #800000; +} +div.post.reply { + border: 0px; + background: #f0e0d6; +} +div.post.reply.highlighted { + background: #f0c0b0; + border-color: #d9bfb7; +} +div.post.reply div.body a { + color: navy; +} +p.intro span.subject { + color: #d00; +} +form table tr th { + background: #EA8; +} +div.ban h2 { + background: #FCA; + color: inherit; +} +div.ban { + border-color: #800; +} +div.ban p { + color: black; +} +div.pages { + padding: 7px 5px; + color: maroon; + font-size: 12pt; + + background: none; + border-width: 1px; + border-style: inset; + +} +div.pages a.selected { + color: #800; +} +hr { + border-width: 1px; + border-style: inset; +} +div.boardlist { + color: #B86; +} +div.boardlist a { + color: #800; +} +unimportant, .unimportant * { + font-size: 13px; +} +table.modlog tr th { + background: #EA8; +} diff --git a/stylesheets/img/fade-miku.png b/stylesheets/img/fade-miku.png new file mode 100644 index 0000000000000000000000000000000000000000..a231913f1e4f1e4959ba1143d571682735e77dba GIT binary patch literal 234 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Ú!r!^et3^F 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 TpS{HP`|-g*pFCzk1_o;Ytxr1D literal 0 HcmV?d00001 diff --git a/stylesheets/img/testorange_f_bg.gif b/stylesheets/img/testorange_f_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..1887e7fafb6e97ac3bd99eade27900523dadf463 GIT binary patch literal 143 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 I@5o>c03A8bt^fc4 literal 0 HcmV?d00001 diff --git a/stylesheets/img/testorange_top_bg.gif b/stylesheets/img/testorange_top_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..c1d1828294769df41824d63387a4e3c94cbae35f GIT binary patch literal 6551 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 Date: Wed, 2 Jan 2013 07:53:00 +0100 Subject: [PATCH 183/289] Add szalet.css style by Kurwancka from http://lepszy.vichan.net/ --- stylesheets/img/szalet_bg.png | Bin 0 -> 54946 bytes stylesheets/img/szalet_hr.png | Bin 0 -> 1023 bytes stylesheets/szalet.css | 210 ++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 stylesheets/img/szalet_bg.png create mode 100644 stylesheets/img/szalet_hr.png create mode 100644 stylesheets/szalet.css diff --git a/stylesheets/img/szalet_bg.png b/stylesheets/img/szalet_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..12e4dccae338953cf0cf433ffc8d8667cbad7a15 GIT binary patch literal 54946 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 literal 0 HcmV?d00001 diff --git a/stylesheets/img/szalet_hr.png b/stylesheets/img/szalet_hr.png new file mode 100644 index 0000000000000000000000000000000000000000..97414ce5ac2d2b7f32af05ba131e4412c8959c2c GIT binary patch literal 1023 zcmeAS@N?(olHy`uVBq!ia0y~yV1B{Cz`)GG#=yY9a6;9Bfq_A?#5JNMI6tkVJh3R1 z!7(L2DOJHUH!(dmC^a#qvhZZ84Fd!7LQfaRkcwMxB6It$81VG&=2li*7;C{Whsp1t z{JKMqJGkmCSm!YDG3<7V%1kutuQBVJT(az~kE#78p-tKL`)}mk@-tuz`1taQ(Q6b$=dzN&J4vb8G#FPrq0-|GxN|nEs{Sv3}ai zmc5r9ulwHpps`4sY2KW(uQ{xGccu22Y47m8=)h&QJ+e;lwB;K8=ht)os&`dhDeAaU zl6$Run?`Ne(!0-g`u{AF%%1cuV*1%ejn&Rmzb?(bz5D@xDbFVLh1(?DC$d|8Ns{? zpAs`6M?T7^Nnh#Pyq*x(eJ}T&u0E61wrcJ4yWK}j?WzOaCF6^3&eGmm+}EU?6g7Kxk@~&>o%5Y$A<;q z(_j19=dyA1<1>#Js%{G1{AFv!P1^wXznQV@T*k6Hw`E;exw2$g(b0{qKi=PJ$yZvJ zD4%i7%0k4PrzA!8?Y67emvxqL%kzFc8}@jq;&C45(%vtT=W0d$I%H<_rtk->?~J{@Yc z{TKbOru`rF%{Tn*(yD(|o2Xr|u`gt@)e-HSnfJe0*E}z|;=0COz(A%ydCud#Qahb( zk1aWVYfZ|GO?DTV|379)e!DR*a{m_VO4)r8V#iZsHgDK`>vPwXcPUFe4*SRJ+Wo;hRM&? z^b~}(Svo7vStxk!21k01dVS6BS5Jw-Y52B+NU4Mk9&OJKXXE3 z{>pt~*4NAQ&ZwT$H7Kr)zJ2Z3ny2@rc9-5!{rWz{@cE{-U*}2{dw!ZTLv>qlLjTq0 zKd!ueyLR`!ojWy`S=2VI`^8c#Q}Ttg>d-gNs`(36+c~}${*v%s_zRfvORBc%p8AX0 lrgPcvKtl00j{o%!FmQdp Date: Wed, 2 Jan 2013 07:53:50 +0100 Subject: [PATCH 184/289] Add luna.css style by klaczy, ported by asiekierka --- stylesheets/img/luna_bg1.png | Bin 0 -> 27337 bytes stylesheets/img/luna_bg2.png | Bin 0 -> 803 bytes stylesheets/luna.css | 447 +++++++++++++++++++++++++++++++++++ 3 files changed, 447 insertions(+) create mode 100644 stylesheets/img/luna_bg1.png create mode 100644 stylesheets/img/luna_bg2.png create mode 100644 stylesheets/luna.css diff --git a/stylesheets/img/luna_bg1.png b/stylesheets/img/luna_bg1.png new file mode 100644 index 0000000000000000000000000000000000000000..fe72c24e84b73b6b83f578bd5d973a663774d656 GIT binary patch literal 27337 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�Q&p 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 literal 0 HcmV?d00001 diff --git a/stylesheets/img/luna_bg2.png b/stylesheets/img/luna_bg2.png new file mode 100644 index 0000000000000000000000000000000000000000..ea4688ad7b656482c7e297d0c70d7b0a2f88f043 GIT binary patch literal 803 zcmeAS@N?(olHy`uVBq!ia0y~yU|?ZjV5s9@VqjqC(NgbYU|?V@4sv&5Sa(k5B}g{i z(btiIVPik{pF~y$1_sUokH}&M2EM}}%y>M1MG6B0(+*D;#}Etuy%V2@-7yewOOJi3 zwtn@tKxb|N4-Q!;UnZ7_ivP<`nk#QE@cY+Z{I_ylO7C&*i}k-=2lCf*ELvC6A@hoH z-<^33AFKEtTgW|pWw}r1=LCiYPLm$9^+_A~aRjbgeMEF;-jj-n%_YijT-J&2%bT#^A?dlndcKJbzrG3{E=qYiV`bmU2d`L~n2Lg~EO#xwmG8GQ z<6Hn|`h?G$EZsw+G;hhL9uDa2+PR^~khv&y+w`S7T^vKJLnW7)To0M~I;$XAxF~w_ zosj0}RqWe$C^9}#U!kJ7|5YNp>EZjv3gu^C@I~^!Uvnp#Biyg5=dF{*d1-&{^vyrnvpkJSA=qfL_=TcoX7hrCP_c=QNQF6r)2$&w~XWF!OX%*<~P{hKfaOosUboA zK&IrX$^G*a*tb4DVLZ2lcb9RQjpXv#Po1~ll(hCUf05I%U4JX@oBW%#{dbn7<#iqT z-r?i&W_|MB-*O!`YNy}-7m6;m{=a2f_(Deegz8N6w@}0|Nttr>mdK II;Vst06JA!jQ{`u literal 0 HcmV?d00001 diff --git a/stylesheets/luna.css b/stylesheets/luna.css new file mode 100644 index 00000000..2256f8c2 --- /dev/null +++ b/stylesheets/luna.css @@ -0,0 +1,447 @@ +body { + background-color: #171C4E; + background-image: url('img/luna_bg1.png'), url('img/luna_bg2.png'); + background-repeat: no-repeat, repeat-x; + background-attachment: fixed, scroll; + background-position: right bottom, 0% 0%; + font-family: sans-serif; + font-size: 12px; + color:#ffffff; + margin: 0 8px; + padding-left: 5px; + padding-right: 5px; +} +table * { + margin: 0; +} +a, a:visited { + text-decoration: none; + color: #0091ff;; +} +a, a:selected { + text-decoration: bold; + color: #ffffff; +} +a:hover, p.intro a.post_no:hover { + color: #ffffff; +} +a.post_no { + text-decoration: none; + margin: 0; + padding: 0; +} +p.intro a.post_no { + color: inherit; +} +p.intro a.post_no, p.intro a.email { + margin: 0; +} +p.intro a.email span.name { + color: #0091ff; +} +p.intro a.email:hover span.name { + color: #ffffff; +} +p.intro label { + display: inline; +} +h2 { + color: #0091ff; + font-size: 11pt; + margin: 0; + padding: 0; +} +header { + margin: 1em 0; +} +h1 { + color: #0091ff; + letter-spacing: -2px; + font-size: 20pt; + margin: 0; +} +header div.subtitle, h1 { + color: #FFFFFF; + text-align: center; +} +header div.subtitle { + font-size: 8pt; +} +form { + margin-bottom: 4em; +} +form table { + margin: auto; +} +form table input { + height: auto; +} +input[type="text"], input[type="password"], textarea { + border: 1px solid #a9a9a9; + text-indent: 0; + text-shadow: none; + text-transform: none; + word-spacing: normal; + box-shadow: 3px 3px 3px #111; + border-radius: 10px; +} +form table tr td { + text-align: left; + margin: 0; + padding: 0; +} +form table.mod tr td { + padding: 2px; +} +form table tr th { + text-align: left; + padding: 4px; +} +form table tr th { + background: #000000; +} +form table tr td div { + text-align: center; + float: left; + padding-left: 3px; +} +form table tr td div input { + display: block; + margin: 2px auto 0 auto; + border-radius: 10px; +} +form table tr td div label { + font-size: 10px; +} +.unimportant, .unimportant * { + font-size: 10px; +} +p.fileinfo { + display: block; + margin: 0; + padding-right: 7em; + border-radius: 10px; +} +div.banner { + background-color: #000000; + font-size: 12pt; + font-weight: bold; + text-align: center; + margin: 1em 0; +} +div.banner, div.banner a { + color: #aaa; +} +div.banner a:hover { + color: #000000; + text-decoration: none; +} +img.banner { + float: none; + border: 1px solid #a9a9a9; + margin: 12px auto 0 auto; +} +img { + display: block; + float: left; + margin: 10px 20px; + border: none; +} +div.post img { + padding: 5px; + margin: 5px 20px 0 0; +} +div.post img.icon { + display: inline; + float: none; + margin: 0 5px; + padding: 0; +} +div.post.op { + margin-right: 20px; + margin-bottom: 5px; + border-radius: 10px; +} +div.post.op hr { + border-color: #040934; +} +p.intro { + margin: 0.5em 0; + padding: 0; + padding-bottom: 0.2em; +} +input.delete { + float: left; + margin: 1px 6px 0 0; +} +p.intro span.subject { + color: #CCCCEE; + font-weight: bold; +} +p.intro span.name { + color: #BBBBDD; + font-weight: bold; +} +p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { + color: #CCCCEE; + margin-left: 0; +} +p.intro a { + margin-left: 8px; +} +div.delete { + float: right; +} +div.post.reply p { + margin: 0.3em 0 0 0; +} +div.post.reply div.body { + margin-left: 1.8em; + margin-top: 0.8em; + padding-right: 3em; + padding-bottom: 0.3em; +} +div.post.reply.highlighted { + background: #000000; +} +div.post.reply div.body a { + color: #0091FF; +} +div.post { + max-width: 97%; +} +div.post div.body { + word-wrap: break-word; + white-space: pre-wrap; +} +div.post.reply { + margin-right: 20px; + margin-bottom: 5px; + padding: 5px; + border: 1px #353868 solid; + background: rgba(53, 56, 104, 0.6) !important; + box-shadow: 2px 2px 2px #353868; + display: inline-block; + border-radius: 10px; +} +span.trip { + color: #DDDDDD; +} +span.quote { + color: #FFFF55; +} +span.omitted { + display: block; + margin-top: 1em; +} +br.clear { + clear: left; + display: block; +} +span.controls { + float: right; + margin: 0; + padding: 0; + font-size: 80%; +} +span.controls.op { + float: none; + margin-left: 10px; +} +span.controls a { + margin: 0; +} +div#wrap { + width: 900px; + margin:0 auto; +} +div.ban { + background: #070C3E; + border: 1px solid #00; + max-width: 700px; + margin: 30px auto; +} +div.ban p, div.ban h2 { + padding: 3px 7px; +} +div.ban h2 { + background: #000; + color: #FFF; + font-size: 12pt; +} +div.ban p { + font-size: 12px; + margin-bottom: 12px; +} +div.ban p.reason { + font-weight: bold; +} +span.heading { + color: #000; + font-size: 11pt; + font-weight: bold; +} +span.spoiler { + background: black; + color: black; + padding: 0px 1px; +} +div.post.reply div.body span.spoiler a { + color: black; +} +span.spoiler:hover, div.post.reply div.body span.spoiler:hover a { + color: white; +} +div.styles { + color: #B7C5D9; + background: #353868; + display: inline; + padding: 8px; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + float: right; +} +div.styles a { + text-decoration: none; +} +div.styles a.selected { + color: #FFF; + font-weight: bolder; +} +div.styles form { + margin: 0; + padding: 0; + display: inline; +} +table.test { + width: 100%; +} +table.test td, table.test th { + text-align: left; + padding: 5px; +} +table.test tr.h th { + background: #000; +} +table.test td img { + margin: 0; +} +fieldset label { + display: block; +} +fieldset legend { + background: black; + color: white; + border: 1px solid #000 +} +div.pages { + color: #B7C5D9; + background: #353868; + display: inline; + padding: 8px; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; +} +div.pages a.selected { + color: #FFF; + font-weight: bolder; +} +div.pages a { + text-decoration: none; +} +div.pages form { + margin: 0; + padding: 0; + display: inline; +} +div.pages form input { + margin: 0 5px; + display: inline; +} +hr { + border: none; + border-top: 1px solid #000000; + height: 0; + clear: left; +} +div.boardlist { + color: #B7C5D9; + background: #353868; + display: inline; + padding: 8px; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; +} +div.boardlist.bottom { + margin-top: 20px; +} +div.boardlist a { + text-decoration: none; +} +div.boardlist a.selected { + color: #FFF; + font-weight: bolder; +} +div.report { + color: #333; +} +table.modlog { + margin: auto; + width: 100%; +} +table.modlog tr td { + text-align: left; + margin: 0; + padding: 4px 15px 0 0; +} +table.modlog tr th { + text-align: left; + padding: 4px 15px 5px 5px; + white-space: nowrap; +} +table.modlog tr th { + background: #000; +} +td.minimal, th.minimal { + width: 1%; + white-space: nowrap; +} +div.top_notice { + text-align: center; + margin: 5px auto; +} +span.public_ban { + display: block; + color: red; + font-weight: bold; + margin-top: 15px; +} +span.toolong { + display: block; + margin-top: 15px; +} +div.blotter { + color: red; + font-weight: bold; + text-align: center; +} +table.mod.config-editor { + font-size: 9pt; + width: 100%; +} +table.mod.config-editor td { + text-align: left; + padding: 5px; + border-bottom: 1px solid #000; +} +table.mod.config-editor input[type="text"] { + width: 98%; +} + +.desktop-style div.boardlist:nth-child(1):hover { + background-color: inherit; +} + +.desktop-style .sub { + background: none; +} From 5174bf23ebb3d2f7b20d1bbdca8197a1273ee9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Wed, 2 Jan 2013 07:54:44 +0100 Subject: [PATCH 185/289] Add Terminal-2 style by spider --- stylesheets/terminal2.css | 170 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 stylesheets/terminal2.css diff --git a/stylesheets/terminal2.css b/stylesheets/terminal2.css new file mode 100644 index 00000000..f08d0b3a --- /dev/null +++ b/stylesheets/terminal2.css @@ -0,0 +1,170 @@ +body { + background: #000000; + color: #00FF00; + font-family: sans-serif; + font-size: 12px; +} +h1 { + font-size: 20pt; + text-align: center; + letter-spacing: 0px; +} +div.title, h1 { + color: lime; + font-family: sans-serif; +} +div.title p { + font-size: 10px; +} +a:link, a:visited, p.intro a.email span.name { + color: #00FF00; + text-decoration: underline; + font-family: sans-serif; +} +a:link:hover, a:visited:hover { + color: #00FF00; + font-family: sans-serif; + text-decoration: underline overline; +} +a.post_no { + color: #00FF00; + text-decoration: none; +} +a.post_no:hover { + color: #00FF00; + text-decoration: underline overline; +} +div.post.reply { + background: #000000; + border: 1px dashed; + border-color:#00FF00; +} +div.post.reply.highlighted { + background: transparent; + border: transparent 1px dashed; + border-color:#00FF00; +} +div.post.reply div.body a:link, div.post.reply div.body a:visited { + color: #00FF00; +} +div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { + color: #00FF00; +} +p.intro span.subject { + font-size: 12px; + font-family: sans-serif; + color: #446655; + font-weight: 800; +} +p.intro span.name { + color: #00FF00; + font-weight: 800; +} +p.intro a.capcode, p.intro a.nametag { + color: #00FF00; + margin-left: 0; +} +p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { + color: #00FF00; +} +input[type="text"], textarea, select { + background: #000000; + color: #00FF00; + border: 1px dashed; + border-color:#00FF00; + padding-left: 5px; + padding-right: -5px; + font-family: sans-serif; + font-size: 10pt; +} +input[type="password"] { + background: #000000; + color: #00FF00; + border: 1px dashed; + border-color:#00FF00; +} + +form table tr th { + background: #000000; + color: #00FF00; + font-weight: 800; + text-align: left; + padding: 0; + border: #00FF00 1px dashed; + border-color:#00FF00; +} +div.banner { + background: #00AA00; + color: #FFFFFF; + text-align: center; + width: 250px; + padding: 4px; + padding-left: 12px; + padding-right: 12px; + margin-left: auto; + margin-right: auto; + font-size: 12px; +} +input[type="submit"] { + background: #000000; + border: 1px dashed; + border-color:#00FF00; + color: #00FF00; +} +input[type="submit"]:hover { + background: #000000; + border: 1px dashed; + border-color:#00FF00; + color: #00FF00; +} +p.fileinfo a:hover { + text-decoration: underline; +} +span.trip { + color: #00FF00; +} +div.pages { + color: #00FF00; + background: #000000; + border: 1px dashed; + border-color:#00FF00; + font-family: sans-serif; + font-size: 10pt; +} +div.pages a.selected { + color: #00FF00; +} +hr { + height: 1px; + border: 1px dashed; + border-color:#00FF00; +} +div.boardlist { + color: #00FF00; +} +div.ban { + border: transparent 0px dashed; + border-color:#00FF00; +} +div.ban h2 { + background: transparent; + color: lime; + font-size: 12px; +} +table.modlog tr th { + background: #000000; + color: #00FF00; +} + +.desktop-style div.boardlist:nth-child(1) { + background-color: black; + border-bottom: #00FF00 1px dashed; +} +.desktop-style div.boardlist:nth-child(1):hover { + background-color: black; +} + +.desktop-style .sub { + background: none; +} + From fc455f8d8f63b011c002647810ba0093707ee372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Wed, 2 Jan 2013 07:55:13 +0100 Subject: [PATCH 186/289] Add futaba-light.css by Kurwancka --- stylesheets/futaba-light.css | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 stylesheets/futaba-light.css diff --git a/stylesheets/futaba-light.css b/stylesheets/futaba-light.css new file mode 100644 index 00000000..76a82f58 --- /dev/null +++ b/stylesheets/futaba-light.css @@ -0,0 +1,98 @@ +/* +piwnichan style, based on futaba.css of Tinyboard */ + +body { + background: #FFF0DF; + color: #800000; + font-family: sans-serif; + font-size: 13px; +} +div.title h1 { + font-size: 24px; +} +div.title p { + font-size: 10px; +} +div.pages { + font-size: 13px !important; +} +a:link, a:visited, p.intro a.email span.name { + color: #A32615; + font-size: inherit; + text-decoration: inherit; +} +a:link:hover { + color: #d00; + text-decoration: inherit; +} +span.omitted { + color: gray; +} +a.post_no { + color: #800000; +} +div.post.reply { + border: 0px; + background: #FAE8D4; + border: 1px solid #E2C5B1; +} +div.post.reply.highlighted { + background: #f0c0b0; + border-color: #d9bfb7; +} +div.post.reply div.body a { + color: rgb(190, 79, 43); +} +p.intro span.subject { + color: #AA4848; +} +form table tr th { + background: #EED1C2; +} +div.ban h2 { + background: #FCA; + color: inherit; +} +div.ban { + border-color: #800; +} +div.ban p { + color: black; +} +div.pages { + padding: 7px 5px; + color: maroon; + font-size: 12pt; + + background: none; + border-width: 1px; + border-style: inset; + +} +div.pages a.selected { + color: #800; +} +hr { + border-width: 1px; + border-style: inset; +} +div.boardlist { + color: #B86; +} +div.boardlist a { + color: #800; +} +unimportant, .unimportant * { + font-size: 13px; +} +table.modlog tr th { + background: #EA8; +} + +.desktop-style div.boardlist:nth-child(1) { + text-shadow: #fff 1px 1px 1px, #fff -1px -1px 1px; +} + + +.desktop-style div.boardlist:nth-child(1):hover { + background-color: rgba(90%, 90%, 90%, 0.55); +} From 32dd6cc34f49fedc3b7bc61d15f5dea28d713cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81abanowski?= Date: Wed, 2 Jan 2013 08:08:14 +0100 Subject: [PATCH 187/289] Add stripes.css by klaczy --- stylesheets/img/stripes_bg.png | Bin 0 -> 19901 bytes stylesheets/img/stripes_submit.png | Bin 0 -> 163 bytes stylesheets/img/stripes_textarea.png | Bin 0 -> 2816 bytes stylesheets/stripes.css | 67 +++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 stylesheets/img/stripes_bg.png create mode 100644 stylesheets/img/stripes_submit.png create mode 100644 stylesheets/img/stripes_textarea.png create mode 100644 stylesheets/stripes.css diff --git a/stylesheets/img/stripes_bg.png b/stylesheets/img/stripes_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..17a4d6b42defcc8ebbad993bc91a2030f6c690ed GIT binary patch literal 19901 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 PFfe$!`njxgN@xNAkrylb literal 0 HcmV?d00001 diff --git a/stylesheets/img/stripes_textarea.png b/stylesheets/img/stripes_textarea.png new file mode 100644 index 0000000000000000000000000000000000000000..b6401acd17e632f9429ade10229e962ad3b67331 GIT binary patch literal 2816 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 Ad;kCd literal 0 HcmV?d00001 diff --git a/stylesheets/stripes.css b/stylesheets/stripes.css new file mode 100644 index 00000000..da3f2aab --- /dev/null +++ b/stylesheets/stripes.css @@ -0,0 +1,67 @@ +/** + * stripes.css + * for vichan by klaczy + */ +body { + background: url('img/stripes_bg.png'); + color: #BBB; + font-family: 'Hevletica', sans-serif; + font-size: 12px; +} +div.boardlist:nth-child(1):hover { + background: #222 !important; +} +div.reply, div.pages { + background: -moz-linear-gradient(bottom, #323232 40%, #2E2E2E 75%) !important; + border: 1px solid #2D2D2D !important; + box-shadow: 0px 0px 10px #2C2C2C; + color: #BBB !important; +} +.reply { + margin-top: 0.5em !important; +} +.body a, a:hover { + color: #FF6666; +} +table th { background: none !important } +a, a:visited { + color: #BBB; +} +hr { + border: 0 !important; + height: 1px !important; + background-color: #AAA !important; + margin: 1.5em 0 1.5em !important; +} +.name, .body a { + color: #FF6666 !important; +} +.subject, h1, .subtitle, .selected { + color: #FF6699 !important; +} +.capcode { + color: #FF66CC !important; +} +input, textarea { + background: url('img/stripes_textarea.png'); + border: 1px #CCC; + border-radius: 3px; + padding: 3px; +} +input[type="text"] { width: 200px } +textarea { + background-size: 100% 100%; + background-color: #FCFCFC; + background-repeat: repeat-x; + width: 100%; + height: 200px; +} +input[type="submit"] { + border: 1px solid rgb(204, 204, 204); + background: url('img/stripes_submit.png'); + height: 23px; + margin-left: 0.5em; +} +.delete { + margin-top: 0.5em; +} From cd82c167a2c8d1205296c653a3e7f01b79a62116 Mon Sep 17 00:00:00 2001 From: szalej Date: Sat, 19 Jan 2013 02:38:01 +0100 Subject: [PATCH 188/289] Update stylesheets/szalet.css --- stylesheets/szalet.css | 75 +++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/stylesheets/szalet.css b/stylesheets/szalet.css index 1bdc212a..e4deb8ee 100644 --- a/stylesheets/szalet.css +++ b/stylesheets/szalet.css @@ -1,14 +1,27 @@ -/* nowy styl */ +/* szalet 1.2 */ body { font-family: sans-serif; font-size: 12px; - color: #C4C4C4; + color: #99938D; background-color: #1e1e1e; background-image: url('img/szalet_bg.png'); background-repeat: repeat; - +} + +.desktop-style .bl-menu{ +background-image: url('img/szalet_bg.png'); +background-repeat: repeat; +/*background-color: #200000;*/ +} + +.boardlist .board a { +background-color: #200000; +} + +p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +color: #26899C; } div.pages a.selected { @@ -16,15 +29,15 @@ color: #FFFCFC !important;} a:link, a:visited, div.post.reply p.body a { - color: #86472F; + color: #7A422C!important; text-decoration: none; } a:link:hover, a:visited:hover, div.post.reply p.body a:hover { - color: rgb(138, 138, 35); + color: #8A8A23!important; } a.email span.name { - color: #ECDDCA !important; + color: #4B4B4B !important; } @@ -36,6 +49,8 @@ textarea { background: #dedede url('img/testorange_textarea_bg.gif') repeat-x; } input, textarea { +background: #200000; +color: #99938D; } hr { @@ -58,7 +73,7 @@ h1 { clear:both; text-align:center; font-size: 2.5em; - color: sandybrown; + color: #583E28; width:100%; } div.title { @@ -68,12 +83,12 @@ div.banner, .replymode, .catalogmode { text-align:center; margin: 5px 0 5px 0; padding: 5px 2px 5px 2px; - color: sandybrown; + color: #583E28; font-weight: bold; width:100%; } .postblock, form table th { - color: sandybrown; + color: #583E28; font-size: 11px; font-weight: bold; text-align: center !important; @@ -140,13 +155,13 @@ div.banner, .replymode, .catalogmode { } p.intro span.subject { -color: #D11C2A; +color: #771018; font-weight: bold; } span.name, .postername { - color: #DAAD66 !important; + color: #8A775B !important; font-weight:bold; } span.trip, .postertrip { @@ -159,52 +174,30 @@ span.trip, .postertrip { span.omitted, .omittedposts { color: #A39E96; } -.reply { +div.post.reply { padding: 5px; - border: 1px sandyBrown solid !important; - background: #200000 !important; + border: 1px #583E28 solid !important; + background: #200000; -webkit-border-radius: 10px; -khtml-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; } +div.post.reply.highlighted { +background: #583E28; +} + .replyhl { background-color: #1e1e1e; color: #bebebe; } -.doubledash { - vertical-align:top; - clear:both; - float:left; -} -.replytitle { - font-size: 1.2em; - color:#fff; - font-weight:800; -} -.commentpostername { - color: #fff; - font-weight:800; -} -.thumbnailmsg { - font-size: small; - color: #bebebe; -} form table th, div.banner, div.pages, .replymode, .postblock, .passvalid, .catalogmode { background: #200000!important; - border: 1px solid sandyBrown; + border: 1px solid #583E28; } div.pages { color: rgb(143, 139, 139); border: 0; background: none !important; } - -.abbrev { - color:#707070; -} -.highlight { - background:#000; - border: 1px dashed #ff9100; -} From d1e05f7a2f266f47aaff3d2195515b2f1234439f Mon Sep 17 00:00:00 2001 From: cccxd Date: Sat, 19 Jan 2013 21:22:40 +0100 Subject: [PATCH 189/289] style --- stylesheets/img/jungle_bg.png | Bin 0 -> 97254 bytes stylesheets/img/jungle_bg1.png | Bin 0 -> 100273 bytes stylesheets/img/jungle_td.png | Bin 0 -> 147347 bytes stylesheets/img/jungle_td2.png | Bin 0 -> 129711 bytes stylesheets/img/rect820.png | Bin 0 -> 38261 bytes stylesheets/img/rect821.png | Bin 0 -> 38762 bytes stylesheets/jungle.css | 135 +++++++++++++++++++++ stylesheets/piwnichan.css | 206 +++++++++++++++++++++++++++++++++ 8 files changed, 341 insertions(+) create mode 100644 stylesheets/img/jungle_bg.png create mode 100644 stylesheets/img/jungle_bg1.png create mode 100644 stylesheets/img/jungle_td.png create mode 100644 stylesheets/img/jungle_td2.png create mode 100755 stylesheets/img/rect820.png create mode 100755 stylesheets/img/rect821.png create mode 100644 stylesheets/jungle.css create mode 100644 stylesheets/piwnichan.css diff --git a/stylesheets/img/jungle_bg.png b/stylesheets/img/jungle_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..649bafe7b7520bcbc7e6b85f93a1a8f32c9eee98 GIT binary patch literal 97254 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
      `$qY-M9DXUx_K!fYKg%Jf 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 Hr-UW|yQQXy literal 0 HcmV?d00001 diff --git a/stylesheets/img/jungle_td2.png b/stylesheets/img/jungle_td2.png new file mode 100644 index 0000000000000000000000000000000000000000..4c6cd1a0b4186117c41e304458f77f1335287b93 GIT binary patch literal 129711 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 T+%ioFKW2j?%zW8KqUH!2+4u3XV-FG&w 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

      >c@9(7EgS`_`Le^y{aAlY84h+ti@79 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 literal 0 HcmV?d00001 diff --git a/stylesheets/jungle.css b/stylesheets/jungle.css new file mode 100644 index 00000000..881eb88b --- /dev/null +++ b/stylesheets/jungle.css @@ -0,0 +1,135 @@ +/* based on jungle.css from brchan.org */ + +body { + background: #ffe; + background-image: url('img/jungle_bg1.png'), url('img/jungle_bg.png'); + background-repeat: repeat-x, repeat; + +background-attachment: scroll, scroll; + color: #054500; + font-family: serif; + font-size: 16px; +} +div.title h1 { + font-size: 24px; +} +div.title p { + font-size: 10px; +} +a:link, a:visited, p.intro a.email span.name { + color: #00E; +} +a:link:hover { + color: #d00; +} +a.post_no { + color: #800000; +} + +desktop-style .bl-menu{ + background-image: url('img/jungle_bg1.png'), url('img/jungle_bg.png'); + background-repeat: repeat-x, repeat; + background-attachment: scroll, scroll; +} + +.boardlist .board a { +background: #65AB6B; +border: 1px solid #054500; +color: #054500; +font-weight: 600; +} + + +div.post.reply { + background-image: url('img/jungle_td.png'); + border: 1px solid #E5D959; +border-left: none; +border-top: none; +webkit-border-radius: 5px; +-moz-border-radius: 5px; +border-radius: 5px; +-webkit-box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35); +-moz-box-shadow: 0px 2px 3px rgba(0,0,0,0.35); +-o-box-shadow: 0px 2px 3px rgba(0,0,0,0.35); +box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35); +} +div.post.reply.highlighted { + background-image: url('img/jungle_td2.png'); + border: 1px solid #E5D959; +border-left: none; +border-top: none; +webkit-border-radius: 5px; +-moz-border-radius: 5px; +border-radius: 5px; +-webkit-box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35); +-moz-box-shadow: 0px 2px 3px rgba(0,0,0,0.35); +-o-box-shadow: 0px 2px 3px rgba(0,0,0,0.35); +box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35); +} +div.post.reply div.body a { + color: #00E; +} +p.intro span.subject { + color: #d00; +} +form table tr th { + background: #65AB6B; +border: 1px solid #054500; +font-weight: 600; +} +div.ban h2 { + background: #FCA; + color: inherit; +} +div.ban { + border-color: #800; +} +div.ban p { + color: black; +} +div.pages { + padding: 7px 5px; + color: #054500; + font-size: 12pt; + + background-image: url('img/jungle_td.png'); + border-width: 1px; + border-style: inset; + +} +div.pages a.selected { + color: #800; +} +hr { + border-width: 1px; + border-style: inset; +} +div.boardlist { + color: #B86; +} +div.boardlist a { + color: #800; +} +unimportant, .unimportant * { + font-size: 13px; +} +table.modlog tr th { + background: #EA8; +} + +p.intro span.name { +color: maroon; +font-weight: 600; +} + +header div.subtitle, h1 { +color: #054500; +} +.desktop-style div.boardlist:nth-child(1) { + text-shadow: #fff 1px 1px 1px, #fff -1px -1px 1px; +} + + +.desktop-style div.boardlist:nth-child(1):hover { + background-color: rgba(90%, 90%, 90%, 0.55); +} diff --git a/stylesheets/piwnichan.css b/stylesheets/piwnichan.css new file mode 100644 index 00000000..2c1ea49a --- /dev/null +++ b/stylesheets/piwnichan.css @@ -0,0 +1,206 @@ +/* piwnichan */ + + + +body { + font-family: sans-serif; + font-size: 12px; + color:#47506F; + background:#000006 url('img/rect820.png') fixed top right no-repeat; +} + +.desktop-style .bl-menu{ +background-color: #030511; +} + +.boardlist .board a { +background-color: #030511; +} + + +span.quote { +color: #296353; +} + + div.pages a.selected { +color: #FFFCFC !important;} + +div.post.reply div.body a { +color: #6F0A0A; +} + +a:link, a:visited, div.post.reply p.body a { + color: #355097; + text-decoration: none; +} +a:link:hover, a:visited:hover, div.post.reply p.body a:hover { + color: #5A8C99; +} + +a.email span.name { + color: #5A8C99 !important; +} + +p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +color: #6E0877; +} + +div.post.reply.highlighted { +background: #000E3A; +} + + +input, textarea { + background: url("img/rect821.png") no-repeat fixed right top #030511; + color: #47506F; + +} + +hr { + height:3px; + border-width: 0px; + background:url(img/img/hr_d_blue2.png) center no-repeat; + background-size:100% 100%; + -moz-background-size:100% 100%; +} + +.reflink a:hover{ + font-weight: bold; +} +.adminbar { + text-align:right; + clear:both; + float:right; +} +h1 { + clear:both; + text-align:center; + font-size: 2.5em; + color: #47506F; + width:100%; +} +div.title { + color: #AF8C5D; +} +div.banner, .replymode, .catalogmode { + text-align:center; + margin: 5px 0 5px 0; + padding: 5px 2px 5px 2px; + color: #47506F; + font-weight: bold; + width:100%; +} +.postblock, form table th { + color: sandybrown; + font-size: 11px; + font-weight: bold; + text-align: center !important; +} + +.postarea { +} +.rules { + width: 468px; + font-size: 10px; +} +.rules li { + margin-left: 1em; +} +.footer { + text-align:center; + font-size:12px; +} +.passvalid { + text-align:center; + width:100%; + color:#ffffff; +} +.dellist { + font-weight: bold; + text-align:center; +} +.delbuttons { + text-align:center; + padding-bottom:4px; + +} +.managehead { + background-color: #1e1e1e; + color: #bebebe; + padding:0px; +} +.postlists { + background: #000; + width:100%; + padding:0px; + color: #bebebe; +} +.row1 { + background-color: #1e1e1e; + color: #bebebe; +} +.row2 { + background: #1e1e1e; + color: #bebebe; +} +.unkfunc { + background:inherit; + color:#789922; +} +.filesize { + text-decoration:none; +} +.filetitle { + background:inherit; + font-size:1.2em; + color: #bebebe; + font-weight:800; +} + +p.intro span.subject { +color: #4D2C80; +font-weight: bold; +} + + +span.name, .postername { + color: #06546D !important; + font-weight:bold; +} +span.trip, .postertrip { + color: #B88146; +} +.oldpost { + color:#CC1105; + font-weight:800; +} +span.omitted, .omittedposts { + color: #7C776F; +} +div.post.reply { + padding: 5px; + + background:#030511 url('img/rect821.png') fixed top right no-repeat; + color:#47506F; + border: 1px solid #000E3A!important; + + + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +} +.replyhl { + background-color: #1e1e1e; + color: #bebebe; +} +form table th, div.banner, div.pages, .replymode, .postblock, .passvalid, .catalogmode { + background: #030511!important; + color:#47506F; + border: 1px solid #0A1E55 +} +div.pages { + color: rgb(143, 139, 139); + border: 0; + background: none !important; +} From 9c1984a4ea61f4361893f7991141d8b7a06e0fd8 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 15 Jun 2013 01:36:30 -0400 Subject: [PATCH 190/289] stylesheets: add photon.css by Turanga --- stylesheets/photon.css | 321 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 stylesheets/photon.css diff --git a/stylesheets/photon.css b/stylesheets/photon.css new file mode 100644 index 00000000..09735d5c --- /dev/null +++ b/stylesheets/photon.css @@ -0,0 +1,321 @@ +/*https://github.com/turanga/Tinyboard/blob/efe78b81c1ffca32bcf9601d0e3877bb65c70df1/stylesheets/photon.css*/ + + +.floatiframe{ +float:left; +padding:10px; +} + + +div.boardlist { + color: #8899AA; + font-size: 12pt; + margin-top: 0px; + background-color: #DDDDDD; + border: 1px solid #cccccc; + border-radius: 4px 4px 4px 4px; + margin-top: 0; + padding: 10px; + position: fixed; + top: 0; +} +div.boardlist.bottom { + margin-top: 20px; + position: inherit; + background:inherit; +} + + + +.return1 a{ +float:left; +font-size: inherit; + +} + +div.blotter { + background: none repeat scroll 0 0 #DDDDDD; + border: 1px solid #CCCCCC; + border-radius: 5px 5px 5px 5px; + clear: both; + color: #006AB9; + font-weight: bold; + margin-bottom: 0.5em; + padding: 2px; + text-align: center; +} + + + +div.title { + margin-bottom: 0em; + clear: both; + color: #FFAB3F; + font-size: 2em; + font-weight: bold; + +} + +div.ban h2 { + border-radius: 6px 6px 6px 6px; +} + +div.ban { + background: none repeat scroll 0 0 #DDDDDD; + border: 1px solid #CCCCCC; + margin: 30px auto; + max-width: 700px; + border-radius: 7px; + +} + +form { + margin-bottom: 0px; +} + + +form { + margin-bottom: 0px; +} + +span.heading { + color: #FFAB3F; + display: block; + font-size: 12pt; + font-weight: bold; +} + +textarea#body{ + height: 136px; + width: 518px; +} + + + +html, body { + background: none; + background-color: #EEEEEE; + color: #333333; + font-family: "Trebuchet MS",Trebuchet,serif; + font-size: 12pt; +} +a { + color: #FF6600; +} +a:hover { + color: #0066FF; +} +.adminbar { + clear:both; + float:right; + font-size: .8em; +} +.adminbar a { + font-weight: bold; +} +.logo { + clear:both; + text-align:left; + font-size:2em; + font-weight: bold; + color:#FF6600; + /*width:100%;*/ +} +.theader, .passvalid { + background:#DDDDDD; + text-align:center; + padding:2px; + color:#2266AA; + clear: both; + font-weight: bold; + margin-bottom: .5em; + border: solid 1px #CCCCCC; + -moz-border-radius: 5px; +} +.postarea { +} +.rules { + font-size:0.7em; +} +.postblock { + background:transparent; + color:#002244; + font-weight:bold; +} +.footer { + text-align:center; + font-size:12px; + font-family:serif; + margin: 2em 0 0 0; +} +.dellist { + font-weight: bold; + text-align:center; +} +.delbuttons { + text-align:center; + padding-bottom:4px; +} +.managehead { + background:#DDDDDD; + color:#002244; + padding:0px; +} +.postlists { + background:#FFFFFF; + width:100%; + padding:0px; + color:#800000; +} +.row1 { + background:#DDDDDD; + color:#002244; +} +.row2 { + background:#CCCCCC; + color:#002244; +} +.unkfunc { + background:inherit; + color:#789922; +} +.reflink { + font-size: .8em; + font-weight: bold; +} +.filesize { + text-decoration:none; + color: #666666; + font-size: .8em; +} +.filetitle { + background:inherit; + font-size:1.2em; + color:#002244; + font-weight:bold; +} +.postername { + color:#004A99; + font-weight:bold; +} +.postertrip { + color:#FF3300; +} +.oldpost { + color:#CC1105; + font-weight:bold; +} +.omittedposts { + color:#666666; +} +.reply { + background:#DDDDDD; + border: solid 1px #CCCCCC; + padding: 0; + margin: 0; + -moz-border-radius: 5px; +} +blockquote { + margin: .5em .5em .5em 1em; +} +blockquote p { + margin: 0; + padding: 0; +} +.reply blockquote { + margin: .5em; +} +.doubledash { + display: none; + vertical-align:top; + clear:both; + float:left; +} +.replytitle { + font-size: 1.2em; + color:#002244; + font-weight:bold; +} +.commentpostername { + color:#004A99; + font-weight:800; +} +.thumbnailmsg { + font-size: .8em; + color:#666666; +} +hr { + border-style: solid none none none; + border-width: 1px; + border-color: #BBBBBB; +} +table { + border-style: none; +} +table td { + border-style: none; +} +.nothumb { + background-color: #FFFFFF; + border-style: dotted; + margin: .3em .5em; +} + +.abbrev { + color:#666666; +} +.highlight { + background:#EEDACB; + color:#333333; + border: 2px dashed #EE6600; +} + + +div.banner, div.banner a { + color: inherit; +} +div.banner { + background-color: inherit; +} +form table tr th { + background: none; +} + +div.post.reply { + background: none repeat scroll 0 0 #DDDDDD; + border: 1px solid #CCCCCC; + border-radius: 5px 5px 5px 5px; +} +div.title,h1 { + color: #FF6600; + font-size: 32px; + font-weight: bold; +} +div.title p { + font-size: 26px; + margin: 0; +} + +h1 { + letter-spacing: inherit; +} + +div.banner { + background: none repeat scroll 0 0 #DDDDDD; + border: 1px solid #CCCCCC; + border-radius: 5px 5px 5px 5px; + clear: both; + color: #2266AA; + font-weight: bold; + margin-bottom: 0.5em; + padding: 2px; + text-align: center; +} + +form table tr td div { + padding-left: 0px; + +} +.recaptchatable .recaptcha_image_cell { + padding: 0px !important; +} From 590d46366b93a3dd27c338899dbebeb85abe0a49 Mon Sep 17 00:00:00 2001 From: lanc33 Date: Sat, 22 Jun 2013 12:16:10 -0300 Subject: [PATCH 191/289] Added gentoochan.css. --- stylesheets/gentoochan.css | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 stylesheets/gentoochan.css diff --git a/stylesheets/gentoochan.css b/stylesheets/gentoochan.css new file mode 100644 index 00000000..8213eb26 --- /dev/null +++ b/stylesheets/gentoochan.css @@ -0,0 +1,67 @@ +body { + background: #0E0E0E url(data:image/gif;base64,R0lGODlhGAAMAKEEAOXl5ebm5vDw8PHx8SH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAGAAMAAACRpQiY6cLa146MyY1EJQKjG81lNGRUPOIkgMJHtquBgIO7xwvpbrpduUSuXq8ntEC0bBEylYitdDAdM1ViaobkgKgZwyDLAAAOw==) repeat 0 0!important; + color: #000; +} +a:link, a:visited, p.intro a.email span.name { + -webkit-transition: all ease-in 0.3s; + -moz-transition: all ease-in 0.3s; + color: rgba(0, 0, 0, 0.6); + text-decoration:none !important; +} +a:link:hover { + -moz-transition: all ease-in 0.5s; + text-shadow: 0px 0px 2px #000; +} +a.post_no { + color: #fff; +} +.boardlist { + color: #ccc; +} +div.post.reply, input, textarea { + background: rgba(0, 0, 0, 0.1)!important; + border: 1px solid rgba(0, 0, 0, 0.2)!important; + border-radius: 2px !important; +} +div.post.reply.highlighted { + background: #f0c0b0; + border-color: #d9bfb7; +} +div.post.reply p.body a { + color: navy; +} +p.intro span.subject { + color: #000; +} +form table tr th { + background: #EA8; +} +div.ban h2 { + background: #FCA; + color: inherit; +} +div.ban { + border-color: #000; +} +div.ban p { + color: black; +} +div.pages { + background: #F0E0D6; + border-color: #D9BFB7; +} +div.pages a.selected { + color: #800; +} +hr { + border-color: rgba(0, 0, 0, 0.2); +} +div.boardlist { + color: rgba(0, 0, 0, 0.2); +} +div.boardlist a { + color: #000; +} +table.modlog tr th { + background: #EA8; +} From 780dd56eab1b92f9d65eb75c795ad825884f04ba Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 27 Jul 2013 02:34:15 -0400 Subject: [PATCH 192/289] dark.css stylesheet fixes Conflicts: stylesheets/dark.css --- stylesheets/dark.css | 50 +++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/stylesheets/dark.css b/stylesheets/dark.css index 2248c9d3..c4a6855c 100644 --- a/stylesheets/dark.css +++ b/stylesheets/dark.css @@ -8,13 +8,16 @@ body { font-family: sans-serif; font-size: 12px; } +span.quote { + color:#B8D962; +} h1 { font-size: 20pt; text-align: center; letter-spacing: 0px; } div.title, h1 { - color: lime; + color: #32DD72; font-family: Arial, Helvetica, sans-serif; } div.title p { @@ -22,35 +25,41 @@ div.title p { } a:link, a:visited, p.intro a.email span.name { color: #CCCCCC; - text-decoration: underline; + text-decoration: none; font-family: sans-serif; } a:link:hover, a:visited:hover { - color: #FF0000; + color: #fff; font-family: sans-serif; - text-decoration: underline overline; + text-decoration: none; + } a.post_no { color: #AAAAAA; text-decoration: none; } a.post_no:hover { - color: maroon; + color: #32DD72 !important; text-decoration: underline overline; } div.post.reply { background: #333333; border: #555555 1px solid; + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + } div.post.reply.highlighted { - background: transparent; + background: #555; border: transparent 1px solid; } div.post.reply div.body a:link, div.post.reply div.body a:visited { color: #CCCCCC; } div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { - color: #FF0000; + color: #32DD72; } p.intro span.subject { font-size: 12px; @@ -59,7 +68,7 @@ p.intro span.subject { font-weight: 800; } p.intro span.name { - color: #00CC00; + color: #32DD72; font-weight: 800; } p.intro a.capcode, p.intro a.nametag { @@ -67,7 +76,7 @@ p.intro a.capcode, p.intro a.nametag { margin-left: 0; } p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { - color: #00CCCC; + color: #32ddaf; } input[type="text"], textarea, select { background: #333333; @@ -91,8 +100,8 @@ form table tr th { padding: 0; } div.banner { - background: #00AA00; - color: #FFFFFF; + background: #32DD72; + color: #000; text-align: center; width: 250px; padding: 4px; @@ -102,6 +111,9 @@ div.banner { margin-right: auto; font-size: 12px; } +div.banner a { + color:#000; +} input[type="submit"] { background: #333333; border: #888888 1px solid; @@ -110,7 +122,10 @@ input[type="submit"] { input[type="submit"]:hover { background: #555555; border: #888888 1px solid; - color: #FF0000; + color: #32DD72; +} +input[type="text"]:focus { + border:#aaa 1px solid; } p.fileinfo a:hover { text-decoration: underline; @@ -134,7 +149,9 @@ hr { } div.boardlist { color: #999999; + background-color: rgba(12%, 12%, 12%, 0.10); } + div.ban { background-color: transparent; border: transparent 0px solid; @@ -148,3 +165,12 @@ table.modlog tr th { background: #333333; color: #AAAAAA; } + +.desktop-style div.boardlist:nth-child(1) { + text-shadow: black 1px 1px 1px, black -1px -1px 1px, black -1px 1px 1px, black 1px -1px 1px; +} + + +.desktop-style div.boardlist:nth-child(1):hover { + background-color: rgba(30%, 30%, 30%, 0.65); +} \ No newline at end of file From 256d4e24e5d78901e94b50bc97103b0f3d3c7092 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 03:37:01 -0400 Subject: [PATCH 193/289] Line endings fix --- stylesheets/stripes.css | 134 ++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/stylesheets/stripes.css b/stylesheets/stripes.css index da3f2aab..61a9d326 100644 --- a/stylesheets/stripes.css +++ b/stylesheets/stripes.css @@ -1,67 +1,67 @@ -/** - * stripes.css - * for vichan by klaczy - */ -body { - background: url('img/stripes_bg.png'); - color: #BBB; - font-family: 'Hevletica', sans-serif; - font-size: 12px; -} -div.boardlist:nth-child(1):hover { - background: #222 !important; -} -div.reply, div.pages { - background: -moz-linear-gradient(bottom, #323232 40%, #2E2E2E 75%) !important; - border: 1px solid #2D2D2D !important; - box-shadow: 0px 0px 10px #2C2C2C; - color: #BBB !important; -} -.reply { - margin-top: 0.5em !important; -} -.body a, a:hover { - color: #FF6666; -} -table th { background: none !important } -a, a:visited { - color: #BBB; -} -hr { - border: 0 !important; - height: 1px !important; - background-color: #AAA !important; - margin: 1.5em 0 1.5em !important; -} -.name, .body a { - color: #FF6666 !important; -} -.subject, h1, .subtitle, .selected { - color: #FF6699 !important; -} -.capcode { - color: #FF66CC !important; -} -input, textarea { - background: url('img/stripes_textarea.png'); - border: 1px #CCC; - border-radius: 3px; - padding: 3px; -} -input[type="text"] { width: 200px } -textarea { - background-size: 100% 100%; - background-color: #FCFCFC; - background-repeat: repeat-x; - width: 100%; - height: 200px; -} -input[type="submit"] { - border: 1px solid rgb(204, 204, 204); - background: url('img/stripes_submit.png'); - height: 23px; - margin-left: 0.5em; -} -.delete { - margin-top: 0.5em; -} +/** + * stripes.css + * for vichan by klaczy + */ +body { + background: url('img/stripes_bg.png'); + color: #BBB; + font-family: 'Hevletica', sans-serif; + font-size: 12px; +} +div.boardlist:nth-child(1):hover { + background: #222 !important; +} +div.reply, div.pages { + background: -moz-linear-gradient(bottom, #323232 40%, #2E2E2E 75%) !important; + border: 1px solid #2D2D2D !important; + box-shadow: 0px 0px 10px #2C2C2C; + color: #BBB !important; +} +.reply { + margin-top: 0.5em !important; +} +.body a, a:hover { + color: #FF6666; +} +table th { background: none !important } +a, a:visited { + color: #BBB; +} +hr { + border: 0 !important; + height: 1px !important; + background-color: #AAA !important; + margin: 1.5em 0 1.5em !important; +} +.name, .body a { + color: #FF6666 !important; +} +.subject, h1, .subtitle, .selected { + color: #FF6699 !important; +} +.capcode { + color: #FF66CC !important; +} +input, textarea { + background: url('img/stripes_textarea.png'); + border: 1px #CCC; + border-radius: 3px; + padding: 3px; +} +input[type="text"] { width: 200px } +textarea { + background-size: 100% 100%; + background-color: #FCFCFC; + background-repeat: repeat-x; + width: 100%; + height: 200px; +} +input[type="submit"] { + border: 1px solid rgb(204, 204, 204); + background: url('img/stripes_submit.png'); + height: 23px; + margin-left: 0.5em; +} +.delete { + margin-top: 0.5em; +} From 4851d4cabeebdd72764e75fe8d51f45c0e436c32 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 03:51:50 -0400 Subject: [PATCH 194/289] Forgot "global $config" here --- inc/image.php | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/image.php b/inc/image.php index 99c10252..c39d7694 100644 --- a/inc/image.php +++ b/inc/image.php @@ -173,6 +173,7 @@ class ImageImagick extends ImageBase { } } public function to($src) { + global $config; if ($config['strip_exif']) { $this->image->stripImage(); } From 22f3a95e0e421de05a11633eac846df96a2a4768 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 04:24:34 -0400 Subject: [PATCH 195/289] convert+gifscale didn't respect $config['thumb_keep_animation_frames'] --- inc/config.php | 7 +++---- inc/image.php | 5 ++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/inc/config.php b/inc/config.php index 75384d3f..cec996c1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -412,9 +412,9 @@ // Thumbnail extension, empty for inherited (png recommended) $config['thumb_ext'] = 'png'; - // EXPERIMENTAL: // Maximum amount of frames to resize (more frames means more processing power). "1" means no animated thumbnails. - // Requires $config['thumb_ext'] to be 'gif' $config['imagick'] to be enabled. + // 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. $config['thumb_keep_animation_frames'] = 1; // Thumbnailing method: @@ -426,8 +426,7 @@ // 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. - + // have less artifacts than if resized with ImageMagick. $config['thumb_method'] = 'gd'; // Strip EXIF metadata from JPEG files diff --git a/inc/image.php b/inc/image.php index c39d7694..5910cb85 100644 --- a/inc/image.php +++ b/inc/image.php @@ -282,10 +282,13 @@ class ImageConvert extends ImageBase { $quality = $config['thumb_quality'] * 10; + $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) { if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . - escapeshellarg($this->src . '') . " > " . escapeshellarg($this->temp)) || !file_exists($this->temp)) + escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . + 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} " . From 0fe552857468aa12097a74e08f51f5aaa983be07 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 15:20:12 -0400 Subject: [PATCH 196/289] Upgrade Twig library --- inc/lib/Twig/Autoloader.php | 20 +- inc/lib/Twig/Compiler.php | 82 +- inc/lib/Twig/CompilerInterface.php | 10 +- inc/lib/Twig/Environment.php | 516 ++++++-- inc/lib/Twig/Error.php | 156 ++- inc/lib/Twig/Error/Loader.php | 15 +- inc/lib/Twig/Error/Runtime.php | 3 +- inc/lib/Twig/Error/Syntax.php | 3 +- inc/lib/Twig/ExistsLoaderInterface.php | 28 + inc/lib/Twig/ExpressionParser.php | 304 ++++- inc/lib/Twig/Extension.php | 4 +- inc/lib/Twig/Extension/Core.php | 1053 ++++++++++++----- inc/lib/Twig/Extension/Debug.php | 71 ++ inc/lib/Twig/Extension/Escaper.php | 44 +- inc/lib/Twig/Extension/Staging.php | 113 ++ inc/lib/Twig/Extension/StringLoader.php | 64 + inc/lib/Twig/ExtensionInterface.php | 25 +- .../Twig/Extensions/Extension/Tinyboard.php | 5 - inc/lib/Twig/Filter.php | 31 +- inc/lib/Twig/Filter/Function.php | 8 +- inc/lib/Twig/Filter/Method.php | 11 +- inc/lib/Twig/Filter/Node.php | 39 + inc/lib/Twig/FilterCallableInterface.php | 23 + inc/lib/Twig/FilterInterface.php | 22 +- inc/lib/Twig/Function.php | 25 +- inc/lib/Twig/Function/Function.php | 8 +- inc/lib/Twig/Function/Method.php | 11 +- inc/lib/Twig/Function/Node.php | 39 + inc/lib/Twig/FunctionCallableInterface.php | 23 + inc/lib/Twig/FunctionInterface.php | 18 +- inc/lib/Twig/Lexer.php | 222 ++-- inc/lib/Twig/LexerInterface.php | 10 +- inc/lib/Twig/Loader/Array.php | 39 +- inc/lib/Twig/Loader/Chain.php | 79 +- inc/lib/Twig/Loader/Filesystem.php | 129 +- inc/lib/Twig/Loader/String.php | 34 +- inc/lib/Twig/LoaderInterface.php | 21 +- inc/lib/Twig/Markup.php | 14 +- inc/lib/Twig/Node.php | 11 +- inc/lib/Twig/Node/AutoEscape.php | 3 +- inc/lib/Twig/Node/Block.php | 3 +- inc/lib/Twig/Node/BlockReference.php | 3 +- inc/lib/Twig/Node/Body.php | 19 + inc/lib/Twig/Node/Do.php | 38 + inc/lib/Twig/Node/Embed.php | 38 + inc/lib/Twig/Node/Expression.php | 3 +- inc/lib/Twig/Node/Expression/Array.php | 51 +- inc/lib/Twig/Node/Expression/AssignName.php | 6 +- .../Twig/Node/Expression/Binary/FloorDiv.php | 4 +- .../Twig/Node/Expression/BlockReference.php | 3 +- inc/lib/Twig/Node/Expression/Call.php | 178 +++ .../Node/Expression/ExtensionReference.php | 3 +- inc/lib/Twig/Node/Expression/Filter.php | 60 +- .../Twig/Node/Expression/Filter/Default.php | 43 + inc/lib/Twig/Node/Expression/Function.php | 40 +- inc/lib/Twig/Node/Expression/GetAttr.php | 56 +- inc/lib/Twig/Node/Expression/MethodCall.php | 41 + inc/lib/Twig/Node/Expression/Name.php | 71 +- inc/lib/Twig/Node/Expression/Parent.php | 24 +- inc/lib/Twig/Node/Expression/TempName.php | 26 + inc/lib/Twig/Node/Expression/Test.php | 44 +- .../Twig/Node/Expression/Test/Constant.php | 46 + inc/lib/Twig/Node/Expression/Test/Defined.php | 54 + .../Twig/Node/Expression/Test/Divisibleby.php | 33 + inc/lib/Twig/Node/Expression/Test/Even.php | 32 + inc/lib/Twig/Node/Expression/Test/Null.php | 31 + inc/lib/Twig/Node/Expression/Test/Odd.php | 32 + inc/lib/Twig/Node/Expression/Test/Sameas.php | 29 + inc/lib/Twig/Node/Flush.php | 36 + inc/lib/Twig/Node/For.php | 63 +- inc/lib/Twig/Node/ForLoop.php | 55 + inc/lib/Twig/Node/If.php | 3 +- inc/lib/Twig/Node/Import.php | 3 +- inc/lib/Twig/Node/Include.php | 45 +- inc/lib/Twig/Node/Macro.php | 59 +- inc/lib/Twig/Node/Module.php | 129 +- inc/lib/Twig/Node/Print.php | 3 +- inc/lib/Twig/Node/Sandbox.php | 3 +- inc/lib/Twig/Node/SandboxedModule.php | 23 +- inc/lib/Twig/Node/SandboxedPrint.php | 3 +- inc/lib/Twig/Node/Set.php | 9 +- inc/lib/Twig/Node/SetTemp.php | 35 + inc/lib/Twig/Node/Spaceless.php | 3 +- inc/lib/Twig/Node/Text.php | 3 +- inc/lib/Twig/NodeInterface.php | 12 +- inc/lib/Twig/NodeOutputInterface.php | 3 +- inc/lib/Twig/NodeTraverser.php | 3 +- inc/lib/Twig/NodeVisitor/Escaper.php | 60 +- inc/lib/Twig/NodeVisitor/Optimizer.php | 68 +- inc/lib/Twig/NodeVisitor/SafeAnalysis.php | 32 +- inc/lib/Twig/NodeVisitor/Sandbox.php | 7 +- inc/lib/Twig/NodeVisitorInterface.php | 13 +- inc/lib/Twig/Parser.php | 126 +- inc/lib/Twig/ParserInterface.php | 8 +- inc/lib/Twig/Sandbox/SecurityError.php | 3 +- inc/lib/Twig/Sandbox/SecurityPolicy.php | 3 +- .../Twig/Sandbox/SecurityPolicyInterface.php | 9 +- inc/lib/Twig/SimpleFilter.php | 94 ++ inc/lib/Twig/SimpleFunction.php | 84 ++ inc/lib/Twig/SimpleTest.php | 46 + inc/lib/Twig/Template.php | 215 ++-- inc/lib/Twig/TemplateInterface.php | 10 +- inc/lib/Twig/Test.php | 34 + inc/lib/Twig/Test/Function.php | 12 +- inc/lib/Twig/Test/IntegrationTestCase.php | 154 +++ inc/lib/Twig/Test/Method.php | 15 +- inc/lib/Twig/Test/Node.php | 37 + inc/lib/Twig/Test/NodeTestCase.php | 58 + inc/lib/Twig/TestCallableInterface.php | 21 + inc/lib/Twig/TestInterface.php | 6 +- inc/lib/Twig/Token.php | 50 +- inc/lib/Twig/TokenParser.php | 6 +- inc/lib/Twig/TokenParser/AutoEscape.php | 36 +- inc/lib/Twig/TokenParser/Block.php | 10 +- inc/lib/Twig/TokenParser/Do.php | 42 + inc/lib/Twig/TokenParser/Embed.php | 66 ++ inc/lib/Twig/TokenParser/Extends.php | 8 +- inc/lib/Twig/TokenParser/Filter.php | 2 +- inc/lib/Twig/TokenParser/Flush.php | 42 + inc/lib/Twig/TokenParser/For.php | 66 +- inc/lib/Twig/TokenParser/From.php | 6 +- inc/lib/Twig/TokenParser/If.php | 15 +- inc/lib/Twig/TokenParser/Import.php | 4 +- inc/lib/Twig/TokenParser/Include.php | 29 +- inc/lib/Twig/TokenParser/Macro.php | 21 +- inc/lib/Twig/TokenParser/Sandbox.php | 15 +- inc/lib/Twig/TokenParser/Set.php | 6 +- inc/lib/Twig/TokenParser/Spaceless.php | 2 +- inc/lib/Twig/TokenParser/Use.php | 9 +- inc/lib/Twig/TokenParserBroker.php | 39 +- inc/lib/Twig/TokenParserBrokerInterface.php | 14 +- inc/lib/Twig/TokenParserInterface.php | 11 +- inc/lib/Twig/TokenStream.php | 12 +- 133 files changed, 5080 insertions(+), 1386 deletions(-) create mode 100644 inc/lib/Twig/ExistsLoaderInterface.php create mode 100644 inc/lib/Twig/Extension/Debug.php create mode 100644 inc/lib/Twig/Extension/Staging.php create mode 100644 inc/lib/Twig/Extension/StringLoader.php create mode 100644 inc/lib/Twig/Filter/Node.php create mode 100644 inc/lib/Twig/FilterCallableInterface.php create mode 100644 inc/lib/Twig/Function/Node.php create mode 100644 inc/lib/Twig/FunctionCallableInterface.php create mode 100644 inc/lib/Twig/Node/Body.php create mode 100644 inc/lib/Twig/Node/Do.php create mode 100644 inc/lib/Twig/Node/Embed.php create mode 100644 inc/lib/Twig/Node/Expression/Call.php create mode 100644 inc/lib/Twig/Node/Expression/Filter/Default.php create mode 100644 inc/lib/Twig/Node/Expression/MethodCall.php create mode 100644 inc/lib/Twig/Node/Expression/TempName.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Constant.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Defined.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Divisibleby.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Even.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Null.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Odd.php create mode 100644 inc/lib/Twig/Node/Expression/Test/Sameas.php create mode 100644 inc/lib/Twig/Node/Flush.php create mode 100644 inc/lib/Twig/Node/ForLoop.php create mode 100644 inc/lib/Twig/Node/SetTemp.php create mode 100644 inc/lib/Twig/SimpleFilter.php create mode 100644 inc/lib/Twig/SimpleFunction.php create mode 100644 inc/lib/Twig/SimpleTest.php create mode 100644 inc/lib/Twig/Test.php create mode 100644 inc/lib/Twig/Test/IntegrationTestCase.php create mode 100644 inc/lib/Twig/Test/Node.php create mode 100644 inc/lib/Twig/Test/NodeTestCase.php create mode 100644 inc/lib/Twig/TestCallableInterface.php create mode 100644 inc/lib/Twig/TokenParser/Do.php create mode 100644 inc/lib/Twig/TokenParser/Embed.php create mode 100644 inc/lib/Twig/TokenParser/Flush.php diff --git a/inc/lib/Twig/Autoloader.php b/inc/lib/Twig/Autoloader.php index a93b8caf..7007d315 100644 --- a/inc/lib/Twig/Autoloader.php +++ b/inc/lib/Twig/Autoloader.php @@ -12,28 +12,30 @@ /** * Autoloads Twig classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Autoloader { /** * Registers Twig_Autoloader as an SPL autoloader. + * + * @param Boolean $prepend Whether to prepend the autoloader or not. */ - static public function register() + public static function register($prepend = false) { - ini_set('unserialize_callback_func', 'spl_autoload_call'); - spl_autoload_register(array(new self, 'autoload')); + if (version_compare(phpversion(), '5.3.0', '>=')) { + spl_autoload_register(array(new self, 'autoload'), true, $prepend); + } else { + spl_autoload_register(array(new self, 'autoload')); + } } /** * Handles autoloading of classes. * - * @param string $class A class name. - * - * @return boolean Returns true if the class has been loaded + * @param string $class A class name. */ - static public function autoload($class) + public static function autoload($class) { if (0 !== strpos($class, 'Twig')) { return; diff --git a/inc/lib/Twig/Compiler.php b/inc/lib/Twig/Compiler.php index db2e8de4..99aecbcc 100644 --- a/inc/lib/Twig/Compiler.php +++ b/inc/lib/Twig/Compiler.php @@ -13,8 +13,7 @@ /** * Compiles a node to PHP code. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Compiler implements Twig_CompilerInterface { @@ -22,6 +21,10 @@ class Twig_Compiler implements Twig_CompilerInterface protected $source; protected $indentation; protected $env; + protected $debugInfo; + protected $sourceOffset; + protected $sourceLine; + protected $filename; /** * Constructor. @@ -31,6 +34,12 @@ class Twig_Compiler implements Twig_CompilerInterface public function __construct(Twig_Environment $env) { $this->env = $env; + $this->debugInfo = array(); + } + + public function getFilename() + { + return $this->filename; } /** @@ -56,8 +65,8 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Compiles a node. * - * @param Twig_NodeInterface $node The node to compile - * @param integer $indent The current indentation + * @param Twig_NodeInterface $node The node to compile + * @param integer $indentation The current indentation * * @return Twig_Compiler The current compiler instance */ @@ -65,8 +74,15 @@ class Twig_Compiler implements Twig_CompilerInterface { $this->lastLine = null; $this->source = ''; + $this->sourceOffset = 0; + // source code starts at 1 (as we then increment it when we encounter new lines) + $this->sourceLine = 1; $this->indentation = $indentation; + if ($node instanceof Twig_Node_Module) { + $this->filename = $node->getAttribute('filename'); + } + $node->compile($this); return $this; @@ -86,7 +102,7 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Adds a raw string to the compiled code. * - * @param string $string The string + * @param string $string The string * * @return Twig_Compiler The current compiler instance */ @@ -113,6 +129,11 @@ class Twig_Compiler implements Twig_CompilerInterface return $this; } + /** + * Appends an indentation to the current PHP code after compilation. + * + * @return Twig_Compiler The current compiler instance + */ public function addIndentation() { $this->source .= str_repeat(' ', $this->indentation * 4); @@ -123,7 +144,7 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Adds a quoted string to the compiled code. * - * @param string $string The string + * @param string $value The string * * @return Twig_Compiler The current compiler instance */ @@ -137,19 +158,27 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Returns a PHP representation of a given value. * - * @param mixed $value The value to convert + * @param mixed $value The value to convert * * @return Twig_Compiler The current compiler instance */ public function repr($value) { if (is_int($value) || is_float($value)) { + if (false !== $locale = setlocale(LC_NUMERIC, 0)) { + setlocale(LC_NUMERIC, 'C'); + } + $this->raw($value); - } else if (null === $value) { + + if (false !== $locale) { + setlocale(LC_NUMERIC, $locale); + } + } elseif (null === $value) { $this->raw('null'); - } else if (is_bool($value)) { + } elseif (is_bool($value)) { $this->raw($value ? 'true' : 'false'); - } else if (is_array($value)) { + } elseif (is_array($value)) { $this->raw('array('); $i = 0; foreach ($value as $key => $value) { @@ -178,17 +207,35 @@ class Twig_Compiler implements Twig_CompilerInterface public function addDebugInfo(Twig_NodeInterface $node) { if ($node->getLine() != $this->lastLine) { - $this->lastLine = $node->getLine(); $this->write("// line {$node->getLine()}\n"); + + // when mbstring.func_overload is set to 2 + // mb_substr_count() replaces substr_count() + // but they have different signatures! + if (((int) ini_get('mbstring.func_overload')) & 2) { + // this is much slower than the "right" version + $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n"); + } else { + $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); + } + $this->sourceOffset = strlen($this->source); + $this->debugInfo[$this->sourceLine] = $node->getLine(); + + $this->lastLine = $node->getLine(); } return $this; } + public function getDebugInfo() + { + return $this->debugInfo; + } + /** * Indents the generated code. * - * @param integer $indent The number of indentation to add + * @param integer $step The number of indentation to add * * @return Twig_Compiler The current compiler instance */ @@ -202,18 +249,19 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Outdents the generated code. * - * @param integer $indent The number of indentation to remove + * @param integer $step The number of indentation to remove * * @return Twig_Compiler The current compiler instance */ public function outdent($step = 1) { - $this->indentation -= $step; - - if ($this->indentation < 0) { - throw new Twig_Error('Unable to call outdent() as the indentation would become negative'); + // can't outdent by more steps than the current indentation level + if ($this->indentation < $step) { + throw new LogicException('Unable to call outdent() as the indentation would become negative'); } + $this->indentation -= $step; + return $this; } } diff --git a/inc/lib/Twig/CompilerInterface.php b/inc/lib/Twig/CompilerInterface.php index 0a13edf2..e293ec91 100644 --- a/inc/lib/Twig/CompilerInterface.php +++ b/inc/lib/Twig/CompilerInterface.php @@ -12,24 +12,24 @@ /** * Interface implemented by compiler classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_CompilerInterface { /** * Compiles a node. * - * @param Twig_NodeInterface $node The node to compile + * @param Twig_NodeInterface $node The node to compile * * @return Twig_CompilerInterface The current compiler instance */ - function compile(Twig_NodeInterface $node); + public function compile(Twig_NodeInterface $node); /** * Gets the current PHP code after compilation. * * @return string The PHP code */ - function getSource(); + public function getSource(); } diff --git a/inc/lib/Twig/Environment.php b/inc/lib/Twig/Environment.php index b91c80c5..3afa73d6 100644 --- a/inc/lib/Twig/Environment.php +++ b/inc/lib/Twig/Environment.php @@ -12,12 +12,11 @@ /** * Stores the Twig configuration. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Environment { - const VERSION = '1.2.0'; + const VERSION = '1.13.1'; protected $charset; protected $loader; @@ -36,6 +35,7 @@ class Twig_Environment protected $functions; protected $globals; protected $runtimeInitialized; + protected $extensionInitialized; protected $loadedTemplates; protected $strictVariables; protected $unaryOperators; @@ -43,23 +43,23 @@ class Twig_Environment protected $templateClassPrefix = '__TwigTemplate_'; protected $functionCallbacks; protected $filterCallbacks; + protected $staging; /** * Constructor. * * Available options: * - * * debug: When set to `true`, the generated templates have a __toString() - * method that you can use to display the generated nodes (default to - * false). + * * debug: When set to true, it automatically set "auto_reload" to true as + * well (default to false). * - * * charset: The charset used by the templates (default to utf-8). + * * charset: The charset used by the templates (default to UTF-8). * * * base_template_class: The base template class to use for generated * templates (default to Twig_Template). * * * cache: An absolute path where to store the compiled templates, or - * false to disable compilation cache (default) + * false to disable compilation cache (default). * * * auto_reload: Whether to reload the template is the original source changed. * If you don't provide the auto_reload option, it will be @@ -68,14 +68,18 @@ class Twig_Environment * * strict_variables: Whether to ignore invalid variables in templates * (default to false). * - * * autoescape: Whether to enable auto-escaping (default to true); + * * autoescape: Whether to enable auto-escaping (default to html): + * * false: disable auto-escaping + * * true: equivalent to html + * * html, js: set the autoescaping to one of the supported strategies + * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename" * * * optimizations: A flag that indicates which optimizations to apply * (default to -1 which means that all optimizations are enabled; - * set it to 0 to disable) + * set it to 0 to disable). * - * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance - * @param array $options An array of options + * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance + * @param array $options An array of options */ public function __construct(Twig_LoaderInterface $loader = null, $options = array()) { @@ -88,26 +92,27 @@ class Twig_Environment 'charset' => 'UTF-8', 'base_template_class' => 'Twig_Template', 'strict_variables' => false, - 'autoescape' => true, + 'autoescape' => 'html', 'cache' => false, 'auto_reload' => null, 'optimizations' => -1, ), $options); $this->debug = (bool) $options['debug']; - $this->charset = $options['charset']; + $this->charset = strtoupper($options['charset']); $this->baseTemplateClass = $options['base_template_class']; $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; - $this->extensions = array( - 'core' => new Twig_Extension_Core(), - 'escaper' => new Twig_Extension_Escaper((bool) $options['autoescape']), - 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']), - ); $this->strictVariables = (bool) $options['strict_variables']; $this->runtimeInitialized = false; $this->setCache($options['cache']); $this->functionCallbacks = array(); $this->filterCallbacks = array(); + + $this->addExtension(new Twig_Extension_Core()); + $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); + $this->addExtension(new Twig_Extension_Optimizer($options['optimizations'])); + $this->extensionInitialized = false; + $this->staging = new Twig_Extension_Staging(); } /** @@ -250,13 +255,14 @@ class Twig_Environment /** * Gets the template class associated with the given string. * - * @param string $name The name for which to calculate the template class name + * @param string $name The name for which to calculate the template class name + * @param integer $index The index if it is an embedded template * * @return string The template class name */ - public function getTemplateClass($name) + public function getTemplateClass($name, $index = null) { - return $this->templateClassPrefix.md5($this->loader->getCacheKey($name)); + return $this->templateClassPrefix.md5($this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index); } /** @@ -282,16 +288,28 @@ class Twig_Environment return $this->loadTemplate($name)->render($context); } + /** + * Displays a template. + * + * @param string $name The template name + * @param array $context An array of parameters to pass to the template + */ + public function display($name, array $context = array()) + { + $this->loadTemplate($name)->display($context); + } + /** * Loads a template by name. * - * @param string $name The template name + * @param string $name The template name + * @param integer $index The index if it is an embedded template * * @return Twig_TemplateInterface A template instance representing the given template name */ - public function loadTemplate($name) + public function loadTemplate($name, $index = null) { - $cls = $this->getTemplateClass($name); + $cls = $this->getTemplateClass($name, $index); if (isset($this->loadedTemplates[$cls])) { return $this->loadedTemplates[$cls]; @@ -299,10 +317,10 @@ class Twig_Environment if (!class_exists($cls, false)) { if (false === $cache = $this->getCacheFilename($name)) { - eval('?>'.$this->compileSource($this->loader->getSource($name), $name)); + eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name)); } else { - if (!is_file($cache) || ($this->isAutoReload() && !$this->loader->isFresh($name, filemtime($cache)))) { - $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name)); + if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) { + $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name)); } require_once $cache; @@ -316,6 +334,30 @@ class Twig_Environment return $this->loadedTemplates[$cls] = new $cls($this); } + /** + * Returns true if the template is still fresh. + * + * Besides checking the loader for freshness information, + * this method also checks if the enabled extensions have + * not changed. + * + * @param string $name The template name + * @param timestamp $time The last modification time of the cached template + * + * @return Boolean true if the template is fresh, false otherwise + */ + public function isTemplateFresh($name, $time) + { + foreach ($this->extensions as $extension) { + $r = new ReflectionObject($extension); + if (filemtime($r->getFileName()) > $time) { + return false; + } + } + + return $this->getLoader()->isFresh($name, $time); + } + public function resolveTemplate($names) { if (!is_array($names)) { @@ -510,6 +552,10 @@ class Twig_Environment */ public function getLoader() { + if (null === $this->loader) { + throw new LogicException('You must set a loader first.'); + } + return $this->loader; } @@ -520,7 +566,7 @@ class Twig_Environment */ public function setCharset($charset) { - $this->charset = $charset; + $this->charset = strtoupper($charset); } /** @@ -580,16 +626,28 @@ class Twig_Environment */ public function addExtension(Twig_ExtensionInterface $extension) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); + } + $this->extensions[$extension->getName()] = $extension; } /** * Removes an extension by name. * + * This method is deprecated and you should not use it. + * * @param string $name The extension name + * + * @deprecated since 1.12 (to be removed in 2.0) */ public function removeExtension($name) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); + } + unset($this->extensions[$name]); } @@ -622,39 +680,46 @@ class Twig_Environment */ public function addTokenParser(Twig_TokenParserInterface $parser) { - if (null === $this->parsers) { - $this->getTokenParsers(); + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a token parser as extensions have already been initialized.'); } - $this->parsers->addTokenParser($parser); + $this->staging->addTokenParser($parser); } /** * Gets the registered Token Parsers. * - * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances + * @return Twig_TokenParserBrokerInterface A broker containing token parsers */ public function getTokenParsers() { - if (null === $this->parsers) { - $this->parsers = new Twig_TokenParserBroker; - foreach ($this->getExtensions() as $extension) { - $parsers = $extension->getTokenParsers(); - foreach($parsers as $parser) { - if ($parser instanceof Twig_TokenParserInterface) { - $this->parsers->addTokenParser($parser); - } else if ($parser instanceof Twig_TokenParserBrokerInterface) { - $this->parsers->addTokenParserBroker($parser); - } else { - throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); - } - } - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->parsers; } + /** + * Gets registered tags. + * + * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes. + * + * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances + */ + public function getTags() + { + $tags = array(); + foreach ($this->getTokenParsers()->getParsers() as $parser) { + if ($parser instanceof Twig_TokenParserInterface) { + $tags[$parser->getTag()] = $parser; + } + } + + return $tags; + } + /** * Registers a Node Visitor. * @@ -662,11 +727,11 @@ class Twig_Environment */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { - if (null === $this->visitors) { - $this->getNodeVisitors(); + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a node visitor as extensions have already been initialized.', $extension->getName()); } - $this->visitors[] = $visitor; + $this->staging->addNodeVisitor($visitor); } /** @@ -676,11 +741,8 @@ class Twig_Environment */ public function getNodeVisitors() { - if (null === $this->visitors) { - $this->visitors = array(); - foreach ($this->getExtensions() as $extension) { - $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->visitors; @@ -689,16 +751,25 @@ class Twig_Environment /** * Registers a Filter. * - * @param string $name The filter name - * @param Twig_FilterInterface $visitor A Twig_FilterInterface instance + * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance + * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance */ - public function addFilter($name, Twig_FilterInterface $filter) + public function addFilter($name, $filter = null) { - if (null === $this->filters) { - $this->loadFilters(); + if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { + throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter'); } - $this->filters[$name] = $filter; + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addFilter($name, $filter); } /** @@ -709,18 +780,31 @@ class Twig_Environment * * @param string $name The filter name * - * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists + * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist */ public function getFilter($name) { - if (null === $this->filters) { - $this->loadFilters(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->filters[$name])) { return $this->filters[$name]; } + foreach ($this->filters as $pattern => $filter) { + $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); + + if ($count) { + if (preg_match('#^'.$pattern.'$#', $name, $matches)) { + array_shift($matches); + $filter->setArguments($matches); + + return $filter; + } + } + } + foreach ($this->filterCallbacks as $callback) { if (false !== $filter = call_user_func($callback, $name)) { return $filter; @@ -738,29 +822,43 @@ class Twig_Environment /** * Gets the registered Filters. * + * Be warned that this method cannot return filters defined with registerUndefinedFunctionCallback. + * * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances + * + * @see registerUndefinedFilterCallback */ - protected function loadFilters() + public function getFilters() { - $this->filters = array(); - foreach ($this->getExtensions() as $extension) { - $this->filters = array_merge($this->filters, $extension->getFilters()); + if (!$this->extensionInitialized) { + $this->initExtensions(); } + + return $this->filters; } /** * Registers a Test. * - * @param string $name The test name - * @param Twig_TestInterface $visitor A Twig_TestInterface instance + * @param string|Twig_SimpleTest $name The test name or a Twig_SimpleTest instance + * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance */ - public function addTest($name, Twig_TestInterface $test) + public function addTest($name, $test = null) { - if (null === $this->tests) { - $this->getTests(); + if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { + throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest'); } - $this->tests[$name] = $test; + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addTest($name, $test); } /** @@ -770,29 +868,55 @@ class Twig_Environment */ public function getTests() { - if (null === $this->tests) { - $this->tests = array(); - foreach ($this->getExtensions() as $extension) { - $this->tests = array_merge($this->tests, $extension->getTests()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->tests; } /** - * Registers a Function. + * Gets a test by name. * - * @param string $name The function name - * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance + * @param string $name The test name + * + * @return Twig_Test|false A Twig_Test instance or false if the test does not exist */ - public function addFunction($name, Twig_FunctionInterface $function) + public function getTest($name) { - if (null === $this->functions) { - $this->loadFunctions(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } - $this->functions[$name] = $function; + if (isset($this->tests[$name])) { + return $this->tests[$name]; + } + + return false; + } + + /** + * Registers a Function. + * + * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance + * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance + */ + public function addFunction($name, $function = null) + { + if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { + throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction'); + } + + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addFunction($name, $function); } /** @@ -803,18 +927,31 @@ class Twig_Environment * * @param string $name function name * - * @return Twig_Function|false A Twig_Function instance or false if the function does not exists + * @return Twig_Function|false A Twig_Function instance or false if the function does not exist */ public function getFunction($name) { - if (null === $this->functions) { - $this->loadFunctions(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->functions[$name])) { return $this->functions[$name]; } + foreach ($this->functions as $pattern => $function) { + $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); + + if ($count) { + if (preg_match('#^'.$pattern.'$#', $name, $matches)) { + array_shift($matches); + $function->setArguments($matches); + + return $function; + } + } + } + foreach ($this->functionCallbacks as $callback) { if (false !== $function = call_user_func($callback, $name)) { return $function; @@ -829,27 +966,53 @@ class Twig_Environment $this->functionCallbacks[] = $callable; } - protected function loadFunctions() + /** + * Gets registered functions. + * + * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback. + * + * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances + * + * @see registerUndefinedFunctionCallback + */ + public function getFunctions() { - $this->functions = array(); - foreach ($this->getExtensions() as $extension) { - $this->functions = array_merge($this->functions, $extension->getFunctions()); + if (!$this->extensionInitialized) { + $this->initExtensions(); } + + return $this->functions; } /** * Registers a Global. * + * New globals can be added before compiling or rendering a template; + * but after, you can only update existing globals. + * * @param string $name The global name * @param mixed $value The global value */ public function addGlobal($name, $value) { - if (null === $this->globals) { - $this->getGlobals(); + if ($this->extensionInitialized || $this->runtimeInitialized) { + if (null === $this->globals) { + $this->globals = $this->initGlobals(); + } + + /* This condition must be uncommented in Twig 2.0 + if (!array_key_exists($name, $this->globals)) { + throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); + } + */ } - $this->globals[$name] = $value; + if ($this->extensionInitialized || $this->runtimeInitialized) { + // update the value + $this->globals[$name] = $value; + } else { + $this->staging->addGlobal($name, $value); + } } /** @@ -859,16 +1022,37 @@ class Twig_Environment */ public function getGlobals() { + if (!$this->runtimeInitialized && !$this->extensionInitialized) { + return $this->initGlobals(); + } + if (null === $this->globals) { - $this->globals = array(); - foreach ($this->getExtensions() as $extension) { - $this->globals = array_merge($this->globals, $extension->getGlobals()); - } + $this->globals = $this->initGlobals(); } return $this->globals; } + /** + * Merges a context with the defined globals. + * + * @param array $context An array representing the context + * + * @return array The context merged with the globals + */ + public function mergeGlobals(array $context) + { + // we don't use array_merge as the context being generally + // bigger than globals, this code is faster. + foreach ($this->getGlobals() as $key => $value) { + if (!array_key_exists($key, $context)) { + $context[$key] = $value; + } + } + + return $context; + } + /** * Gets the registered unary Operators. * @@ -876,8 +1060,8 @@ class Twig_Environment */ public function getUnaryOperators() { - if (null === $this->unaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->unaryOperators; @@ -890,24 +1074,121 @@ class Twig_Environment */ public function getBinaryOperators() { - if (null === $this->binaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->binaryOperators; } - protected function initOperators() + public function computeAlternatives($name, $items) { - $this->unaryOperators = array(); - $this->binaryOperators = array(); - foreach ($this->getExtensions() as $extension) { - $operators = $extension->getOperators(); + $alternatives = array(); + foreach ($items as $item) { + $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = $lev; + } + } + asort($alternatives); - if (!$operators) { - continue; + return array_keys($alternatives); + } + + protected function initGlobals() + { + $globals = array(); + foreach ($this->extensions as $extension) { + $extGlob = $extension->getGlobals(); + if (!is_array($extGlob)) { + throw new UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', get_class($extension))); } + $globals[] = $extGlob; + } + + $globals[] = $this->staging->getGlobals(); + + return call_user_func_array('array_merge', $globals); + } + + protected function initExtensions() + { + if ($this->extensionInitialized) { + return; + } + + $this->extensionInitialized = true; + $this->parsers = new Twig_TokenParserBroker(); + $this->filters = array(); + $this->functions = array(); + $this->tests = array(); + $this->visitors = array(); + $this->unaryOperators = array(); + $this->binaryOperators = array(); + + foreach ($this->extensions as $extension) { + $this->initExtension($extension); + } + $this->initExtension($this->staging); + } + + protected function initExtension(Twig_ExtensionInterface $extension) + { + // filters + foreach ($extension->getFilters() as $name => $filter) { + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } elseif ($filter instanceof Twig_SimpleFilter) { + $name = $filter->getName(); + } + + $this->filters[$name] = $filter; + } + + // functions + foreach ($extension->getFunctions() as $name => $function) { + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } elseif ($function instanceof Twig_SimpleFunction) { + $name = $function->getName(); + } + + $this->functions[$name] = $function; + } + + // tests + foreach ($extension->getTests() as $name => $test) { + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } elseif ($test instanceof Twig_SimpleTest) { + $name = $test->getName(); + } + + $this->tests[$name] = $test; + } + + // token parsers + foreach ($extension->getTokenParsers() as $parser) { + if ($parser instanceof Twig_TokenParserInterface) { + $this->parsers->addTokenParser($parser); + } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { + $this->parsers->addTokenParserBroker($parser); + } else { + throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); + } + } + + // node visitors + foreach ($extension->getNodeVisitors() as $visitor) { + $this->visitors[] = $visitor; + } + + // operators + if ($operators = $extension->getOperators()) { if (2 !== count($operators)) { throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); } @@ -919,20 +1200,25 @@ class Twig_Environment protected function writeCacheFile($file, $content) { - if (!is_dir(dirname($file))) { - mkdir(dirname($file), 0777, true); + $dir = dirname($file); + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { + throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir)); + } + } elseif (!is_writable($dir)) { + throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir)); } $tmpFile = tempnam(dirname($file), basename($file)); if (false !== @file_put_contents($tmpFile, $content)) { // rename does not work on Win32 before 5.2.6 if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) { - chmod($file, 0644); + @chmod($file, 0666 & ~umask()); return; } } - throw new Twig_Error_Runtime(sprintf('Failed to write cache file "%s".', $file)); + throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file)); } } diff --git a/inc/lib/Twig/Error.php b/inc/lib/Twig/Error.php index ed0836c4..72d91a98 100644 --- a/inc/lib/Twig/Error.php +++ b/inc/lib/Twig/Error.php @@ -12,8 +12,24 @@ /** * Twig base exception. * - * @package twig - * @author Fabien Potencier + * This exception class and its children must only be used when + * an error occurs during the loading of a template, when a syntax error + * is detected in a template, or when rendering a template. Other + * errors must use regular PHP exception classes (like when the template + * cache directory is not writable for instance). + * + * To help debugging template issues, this class tracks the original template + * name and line where the error occurred. + * + * Whenever possible, you must set these information (original template name + * and line number) yourself by passing them to the constructor. If some or all + * these information are not available from where you throw the exception, then + * this class will guess them automatically (when the line number is set to -1 + * and/or the filename is set to null). As this is a costly operation, this + * can be disabled by passing false for both the filename and the line number + * when creating a new instance of this class. + * + * @author Fabien Potencier */ class Twig_Error extends Exception { @@ -25,6 +41,15 @@ class Twig_Error extends Exception /** * Constructor. * + * Set both the line number and the filename to false to + * disable automatic guessing of the original template name + * and line number. + * + * Set the line number to -1 to enable its automatic guessing. + * Set the filename to null to enable its automatic guessing. + * + * By default, automatic guessing is enabled. + * * @param string $message The error message * @param integer $lineno The template line where the error occurred * @param string $filename The template file name where the error occurred @@ -32,22 +57,23 @@ class Twig_Error extends Exception */ public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) { - if (-1 === $lineno || null === $filename) { - list($lineno, $filename) = $this->findTemplateInfo(null !== $previous ? $previous : $this, $lineno, $filename); + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $this->previous = $previous; + parent::__construct(''); + } else { + parent::__construct('', 0, $previous); } $this->lineno = $lineno; $this->filename = $filename; + + if (-1 === $this->lineno || null === $this->filename) { + $this->guessTemplateInfo(); + } + $this->rawMessage = $message; $this->updateRepr(); - - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $this->previous = $previous; - parent::__construct($this->message); - } else { - parent::__construct($this->message, 0, $previous); - } } /** @@ -104,13 +130,21 @@ class Twig_Error extends Exception $this->updateRepr(); } + public function guess() + { + $this->guessTemplateInfo(); + $this->updateRepr(); + } + /** * For PHP < 5.3.0, provides access to the getPrevious() method. * - * @param string $method The method name - * @param array $arguments The parameters to be passed to the method + * @param string $method The method name + * @param array $arguments The parameters to be passed to the method * * @return Exception The previous exception or null + * + * @throws BadMethodCallException */ public function __call($method, $arguments) { @@ -131,11 +165,16 @@ class Twig_Error extends Exception $dot = true; } - if (null !== $this->filename) { - $this->message .= sprintf(' in %s', json_encode($this->filename)); + if ($this->filename) { + if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { + $filename = sprintf('"%s"', $this->filename); + } else { + $filename = json_encode($this->filename); + } + $this->message .= sprintf(' in %s', $filename); } - if ($this->lineno >= 0) { + if ($this->lineno && $this->lineno >= 0) { $this->message .= sprintf(' at line %d', $this->lineno); } @@ -144,52 +183,57 @@ class Twig_Error extends Exception } } - protected function findTemplateInfo(Exception $e, $currentLine, $currentFile) + protected function guessTemplateInfo() { - if (!function_exists('token_get_all')) { - return array($currentLine, $currentFile); + $template = null; + + if (version_compare(phpversion(), '5.3.6', '>=')) { + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT); + } else { + $backtrace = debug_backtrace(); } - $traces = $e->getTrace(); - foreach ($traces as $i => $trace) { - if (!isset($trace['class']) || 'Twig_Template' === $trace['class']) { - continue; - } - - $r = new ReflectionClass($trace['class']); - if (!$r->implementsInterface('Twig_TemplateInterface')) { - continue; - } - - if (!is_file($r->getFilename())) { - // probably an eval()'d code - return array($currentLine, $currentFile); - } - - if (0 === $i) { - $line = $e->getLine(); - } else { - $line = isset($traces[$i - 1]['line']) ? $traces[$i - 1]['line'] : -log(0); - } - - $tokens = token_get_all(file_get_contents($r->getFilename())); - $templateline = -1; - $template = null; - foreach ($tokens as $token) { - if (isset($token[2]) && $token[2] >= $line) { - return array($templateline, $template); - } - - if (T_COMMENT === $token[0] && null === $template && preg_match('#/\* +(.+) +\*/#', $token[1], $match)) { - $template = $match[1]; - } elseif (T_COMMENT === $token[0] && preg_match('#^//\s*line (\d+)\s*$#', $token[1], $match)) { - $templateline = $match[1]; + foreach ($backtrace as $trace) { + if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) { + if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) { + $template = $trace['object']; } } - - return array($currentLine, $template); } - return array($currentLine, $currentFile); + // update template filename + if (null !== $template && null === $this->filename) { + $this->filename = $template->getTemplateName(); + } + + if (null === $template || $this->lineno > -1) { + return; + } + + $r = new ReflectionObject($template); + $file = $r->getFileName(); + + $exceptions = array($e = $this); + while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { + $exceptions[] = $e; + } + + while ($e = array_pop($exceptions)) { + $traces = $e->getTrace(); + while ($trace = array_shift($traces)) { + if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { + continue; + } + + foreach ($template->getDebugInfo() as $codeLine => $templateLine) { + if ($codeLine <= $trace['line']) { + // update template line + $this->lineno = $templateLine; + + return; + } + } + } + } } } diff --git a/inc/lib/Twig/Error/Loader.php b/inc/lib/Twig/Error/Loader.php index 418a7760..68efb574 100644 --- a/inc/lib/Twig/Error/Loader.php +++ b/inc/lib/Twig/Error/Loader.php @@ -12,9 +12,20 @@ /** * Exception thrown when an error occurs during template loading. * - * @package twig - * @author Fabien Potencier + * Automatic template information guessing is always turned off as + * if a template cannot be loaded, there is nothing to guess. + * However, when a template is loaded from another one, then, we need + * to find the current context and this is automatically done by + * Twig_Template::displayWithErrorHandling(). + * + * This strategy makes Twig_Environment::resolveTemplate() much faster. + * + * @author Fabien Potencier */ class Twig_Error_Loader extends Twig_Error { + public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, false, false, $previous); + } } diff --git a/inc/lib/Twig/Error/Runtime.php b/inc/lib/Twig/Error/Runtime.php index 8a387fa8..8b6ceddb 100644 --- a/inc/lib/Twig/Error/Runtime.php +++ b/inc/lib/Twig/Error/Runtime.php @@ -13,8 +13,7 @@ /** * Exception thrown when an error occurs at runtime. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Error_Runtime extends Twig_Error { diff --git a/inc/lib/Twig/Error/Syntax.php b/inc/lib/Twig/Error/Syntax.php index a2650c36..0f5c5792 100644 --- a/inc/lib/Twig/Error/Syntax.php +++ b/inc/lib/Twig/Error/Syntax.php @@ -13,8 +13,7 @@ /** * Exception thrown when a syntax error occurs during lexing or parsing of a template. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Error_Syntax extends Twig_Error { diff --git a/inc/lib/Twig/ExistsLoaderInterface.php b/inc/lib/Twig/ExistsLoaderInterface.php new file mode 100644 index 00000000..ce434765 --- /dev/null +++ b/inc/lib/Twig/ExistsLoaderInterface.php @@ -0,0 +1,28 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_ExistsLoaderInterface +{ + /** + * Check if we have the source code of a template, given its name. + * + * @param string $name The name of the template to check if we can load + * + * @return boolean If the template source code is handled by this loader or not + */ + public function exists($name); +} diff --git a/inc/lib/Twig/ExpressionParser.php b/inc/lib/Twig/ExpressionParser.php index b4fc5d5d..9cf19344 100644 --- a/inc/lib/Twig/ExpressionParser.php +++ b/inc/lib/Twig/ExpressionParser.php @@ -18,8 +18,7 @@ * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm * @see http://en.wikipedia.org/wiki/Operator-precedence_parser * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_ExpressionParser { @@ -89,9 +88,19 @@ class Twig_ExpressionParser { while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { $this->parser->getStream()->next(); - $expr2 = $this->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value'); - $expr3 = $this->parseExpression(); + if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $expr2 = $this->parseExpression(); + if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $this->parser->getStream()->next(); + $expr3 = $this->parseExpression(); + } else { + $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine()); + } + } else { + $this->parser->getStream()->next(); + $expr2 = $expr; + $expr3 = $this->parseExpression(); + } $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); } @@ -143,31 +152,67 @@ class Twig_ExpressionParser break; case Twig_Token::NUMBER_TYPE: - case Twig_Token::STRING_TYPE: $this->parser->getStream()->next(); $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); break; + case Twig_Token::STRING_TYPE: + case Twig_Token::INTERPOLATION_START_TYPE: + $node = $this->parseStringExpression(); + break; + default: if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) { $node = $this->parseArrayExpression(); } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { $node = $this->parseHashExpression(); } else { - throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine()); + throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); } } return $this->parsePostfixExpression($node); } + public function parseStringExpression() + { + $stream = $this->parser->getStream(); + + $nodes = array(); + // a string cannot be followed by another string in a single expression + $nextCanBeString = true; + while (true) { + if ($stream->test(Twig_Token::STRING_TYPE) && $nextCanBeString) { + $token = $stream->next(); + $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); + $nextCanBeString = false; + } elseif ($stream->test(Twig_Token::INTERPOLATION_START_TYPE)) { + $stream->next(); + $nodes[] = $this->parseExpression(); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $nextCanBeString = true; + } else { + break; + } + } + + $expr = array_shift($nodes); + foreach ($nodes as $node) { + $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine()); + } + + return $expr; + } + public function parseArrayExpression() { $stream = $this->parser->getStream(); $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected'); - $elements = array(); + + $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine()); + $first = true; while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { - if (!empty($elements)) { + if (!$first) { $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma'); // trailing ,? @@ -175,21 +220,24 @@ class Twig_ExpressionParser break; } } + $first = false; - $elements[] = $this->parseExpression(); + $node->addElement($this->parseExpression()); } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed'); - return new Twig_Node_Expression_Array($elements, $stream->getCurrent()->getLine()); + return $node; } public function parseHashExpression() { $stream = $this->parser->getStream(); $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected'); - $elements = array(); + + $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine()); + $first = true; while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) { - if (!empty($elements)) { + if (!$first) { $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma'); // trailing ,? @@ -197,19 +245,33 @@ class Twig_ExpressionParser break; } } + $first = false; - if (!$stream->test(Twig_Token::STRING_TYPE) && !$stream->test(Twig_Token::NUMBER_TYPE)) { + // a hash key can be: + // + // * a number -- 12 + // * a string -- 'a' + // * a name, which is equivalent to a string -- a + // * an expression, which must be enclosed in parentheses -- (1 + 2) + if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) { + $token = $stream->next(); + $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine()); + } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { + $key = $this->parseExpression(); + } else { $current = $stream->getCurrent(); - throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string or a number (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine()); + + throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); } - $key = $stream->next()->getValue(); $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); - $elements[$key] = $this->parseExpression(); + $value = $this->parseExpression(); + + $node->addElement($value, $key); } $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed'); - return new Twig_Node_Expression_Array($elements, $stream->getCurrent()->getLine()); + return $node; } public function parsePostfixExpression($node) @@ -234,43 +296,56 @@ class Twig_ExpressionParser public function getFunctionNode($name, $line) { - $args = $this->parseArguments(); switch ($name) { case 'parent': + $args = $this->parseArguments(); if (!count($this->parser->getBlockStack())) { - throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line); + throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); } - if (!$this->parser->getParent()) { - throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend another one is forbidden', $line); + if (!$this->parser->getParent() && !$this->parser->hasTraits()) { + throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line, $this->parser->getFilename()); } return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); case 'block': - return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line); + return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line); case 'attribute': + $args = $this->parseArguments(); if (count($args) < 2) { - throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attribute)', $line); + throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); } return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line); default: - if (null !== $alias = $this->parser->getImportedFunction($name)) { - return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $line), $args, Twig_TemplateInterface::METHOD_CALL, $line); + if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { + $arguments = new Twig_Node_Expression_Array(array(), $line); + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); + } + + $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line); + $node->setAttribute('safe', true); + + return $node; } - return new Twig_Node_Expression_Function($name, $args, $line); + $args = $this->parseArguments(true); + $class = $this->getFunctionNodeClass($name, $line); + + return new $class($name, $args, $line); } } public function parseSubscriptExpression($node) { - $token = $this->parser->getStream()->next(); + $stream = $this->parser->getStream(); + $token = $stream->next(); $lineno = $token->getLine(); - $arguments = new Twig_Node(); + $arguments = new Twig_Node_Expression_Array(array(), $lineno); $type = Twig_TemplateInterface::ANY_CALL; if ($token->getValue() == '.') { - $token = $this->parser->getStream()->next(); + $token = $stream->next(); if ( $token->getType() == Twig_Token::NAME_TYPE || @@ -280,20 +355,60 @@ class Twig_ExpressionParser ) { $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno); - if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) { + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $type = Twig_TemplateInterface::METHOD_CALL; - $arguments = $this->parseArguments(); - } else { - $arguments = new Twig_Node(); + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); + } } } else { - throw new Twig_Error_Syntax('Expected name or number', $lineno); + throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); + } + + if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { + if (!$arg instanceof Twig_Node_Expression_Constant) { + throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); + } + + $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); + $node->setAttribute('safe', true); + + return $node; } } else { $type = Twig_TemplateInterface::ARRAY_CALL; - $arg = $this->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ']'); + // slice? + $slice = false; + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $slice = true; + $arg = new Twig_Node_Expression_Constant(0, $token->getLine()); + } else { + $arg = $this->parseExpression(); + } + + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $slice = true; + $stream->next(); + } + + if ($slice) { + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { + $length = new Twig_Node_Expression_Constant(null, $token->getLine()); + } else { + $length = $this->parseExpression(); + } + + $class = $this->getFilterNodeClass('slice', $token->getLine()); + $arguments = new Twig_Node(array($arg, $length)); + $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine()); + + $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); + + return $filter; + } + + $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']'); } return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno); @@ -315,10 +430,12 @@ class Twig_ExpressionParser if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $arguments = new Twig_Node(); } else { - $arguments = $this->parseArguments(); + $arguments = $this->parseArguments(true); } - $node = new Twig_Node_Expression_Filter($node, $name, $arguments, $token->getLine(), $tag); + $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine()); + + $node = new $class($node, $name, $arguments, $token->getLine(), $tag); if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) { break; @@ -330,17 +447,62 @@ class Twig_ExpressionParser return $node; } - public function parseArguments() + /** + * Parses arguments. + * + * @param Boolean $namedArguments Whether to allow named arguments or not + * @param Boolean $definition Whether we are parsing arguments for a function definition + */ + public function parseArguments($namedArguments = false, $definition = false) { $args = array(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis'); + $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) { if (!empty($args)) { $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); } - $args[] = $this->parseExpression(); + + if ($definition) { + $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name'); + $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine()); + } else { + $value = $this->parseExpression(); + } + + $name = null; + if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) { + $token = $stream->next(); + if (!$value instanceof Twig_Node_Expression_Name) { + throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename()); + } + $name = $value->getAttribute('name'); + + if ($definition) { + $value = $this->parsePrimaryExpression(); + + if (!$this->checkConstantExpression($value)) { + throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); + } + } else { + $value = $this->parseExpression(); + } + } + + if ($definition) { + if (null === $name) { + $name = $value->getAttribute('name'); + $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); + } + $args[$name] = $value; + } else { + if (null === $name) { + $args[] = $value; + } else { + $args[$name] = $value; + } + } } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); @@ -353,7 +515,7 @@ class Twig_ExpressionParser while (true) { $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); if (in_array($token->getValue(), array('true', 'false', 'none'))) { - throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine()); + throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename()); } $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine()); @@ -379,4 +541,60 @@ class Twig_ExpressionParser return new Twig_Node($targets); } + + protected function getFunctionNodeClass($name, $line) + { + $env = $this->parser->getEnvironment(); + + if (false === $function = $env->getFunction($name)) { + $message = sprintf('The function "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); + } + + if ($function instanceof Twig_SimpleFunction) { + return $function->getNodeClass(); + } + + return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function'; + } + + protected function getFilterNodeClass($name, $line) + { + $env = $this->parser->getEnvironment(); + + if (false === $filter = $env->getFilter($name)) { + $message = sprintf('The filter "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); + } + + if ($filter instanceof Twig_SimpleFilter) { + return $filter->getNodeClass(); + } + + return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter'; + } + + // checks that the node only contains "constant" elements + protected function checkConstantExpression(Twig_NodeInterface $node) + { + if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) { + return false; + } + + foreach ($node as $n) { + if (!$this->checkConstantExpression($n)) { + return false; + } + } + + return true; + } } diff --git a/inc/lib/Twig/Extension.php b/inc/lib/Twig/Extension.php index ac289cb4..931fc033 100644 --- a/inc/lib/Twig/Extension.php +++ b/inc/lib/Twig/Extension.php @@ -82,9 +82,9 @@ abstract class Twig_Extension implements Twig_ExtensionInterface } /** - * Returns a list of global functions to add to the existing list. + * Returns a list of global variables to add to the existing list. * - * @return array An array of global functions + * @return array An array of global variables */ public function getGlobals() { diff --git a/inc/lib/Twig/Extension/Core.php b/inc/lib/Twig/Extension/Core.php index a4153245..e68687b4 100644 --- a/inc/lib/Twig/Extension/Core.php +++ b/inc/lib/Twig/Extension/Core.php @@ -14,6 +14,83 @@ if (!defined('ENT_SUBSTITUTE')) { */ class Twig_Extension_Core extends Twig_Extension { + protected $dateFormats = array('F j, Y H:i', '%d days'); + protected $numberFormat = array(0, '.', ','); + protected $timezone = null; + + /** + * Sets the default format to be used by the date filter. + * + * @param string $format The default date format string + * @param string $dateIntervalFormat The default date interval format string + */ + public function setDateFormat($format = null, $dateIntervalFormat = null) + { + if (null !== $format) { + $this->dateFormats[0] = $format; + } + + if (null !== $dateIntervalFormat) { + $this->dateFormats[1] = $dateIntervalFormat; + } + } + + /** + * Gets the default format to be used by the date filter. + * + * @return array The default date format string and the default date interval format string + */ + public function getDateFormat() + { + return $this->dateFormats; + } + + /** + * Sets the default timezone to be used by the date filter. + * + * @param DateTimeZone|string $timezone The default timezone string or a DateTimeZone object + */ + public function setTimezone($timezone) + { + $this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone); + } + + /** + * Gets the default timezone to be used by the date filter. + * + * @return DateTimeZone The default timezone currently in use + */ + public function getTimezone() + { + if (null === $this->timezone) { + $this->timezone = new DateTimeZone(date_default_timezone_get()); + } + + return $this->timezone; + } + + /** + * Sets the default format to be used by the number_format filter. + * + * @param integer $decimal The number of decimal places to use. + * @param string $decimalPoint The character(s) to use for the decimal point. + * @param string $thousandSep The character(s) to use for the thousands separator. + */ + public function setNumberFormat($decimal, $decimalPoint, $thousandSep) + { + $this->numberFormat = array($decimal, $decimalPoint, $thousandSep); + } + + /** + * Get the default format used by the number_format filter. + * + * @return array The arguments for number_format() + */ + public function getNumberFormat() + { + return $this->numberFormat; + } + /** * Returns the token parser instance to add to the existing list. * @@ -34,6 +111,9 @@ class Twig_Extension_Core extends Twig_Extension new Twig_TokenParser_From(), new Twig_TokenParser_Set(), new Twig_TokenParser_Spaceless(), + new Twig_TokenParser_Flush(), + new Twig_TokenParser_Do(), + new Twig_TokenParser_Embed(), ); } @@ -46,40 +126,53 @@ class Twig_Extension_Core extends Twig_Extension { $filters = array( // formatting filters - 'date' => new Twig_Filter_Function('twig_date_format_filter'), - 'format' => new Twig_Filter_Function('sprintf'), - 'replace' => new Twig_Filter_Function('twig_strtr'), + new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('format', 'sprintf'), + new Twig_SimpleFilter('replace', 'strtr'), + new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('abs', 'abs'), // encoding - 'url_encode' => new Twig_Filter_Function('twig_urlencode_filter'), - 'json_encode' => new Twig_Filter_Function('twig_jsonencode_filter'), + new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'), + new Twig_SimpleFilter('json_encode', 'twig_jsonencode_filter'), + new Twig_SimpleFilter('convert_encoding', 'twig_convert_encoding'), // string filters - 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)), - 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)), - 'upper' => new Twig_Filter_Function('strtoupper'), - 'lower' => new Twig_Filter_Function('strtolower'), - 'striptags' => new Twig_Filter_Function('strip_tags'), + new Twig_SimpleFilter('title', 'twig_title_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('capitalize', 'twig_capitalize_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('upper', 'strtoupper'), + new Twig_SimpleFilter('lower', 'strtolower'), + new Twig_SimpleFilter('striptags', 'strip_tags'), + new Twig_SimpleFilter('trim', 'trim'), + new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), // array helpers - 'join' => new Twig_Filter_Function('twig_join_filter'), - 'reverse' => new Twig_Filter_Function('twig_reverse_filter'), - 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), - 'sort' => new Twig_Filter_Function('twig_sort_filter'), - 'merge' => new Twig_Filter_Function('twig_array_merge'), + new Twig_SimpleFilter('join', 'twig_join_filter'), + new Twig_SimpleFilter('split', 'twig_split_filter'), + new Twig_SimpleFilter('sort', 'twig_sort_filter'), + new Twig_SimpleFilter('merge', 'twig_array_merge'), + new Twig_SimpleFilter('batch', 'twig_array_batch'), + + // string/array filters + new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('length', 'twig_length_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('slice', 'twig_slice', array('needs_environment' => true)), + new Twig_SimpleFilter('first', 'twig_first', array('needs_environment' => true)), + new Twig_SimpleFilter('last', 'twig_last', array('needs_environment' => true)), // iteration and runtime - 'default' => new Twig_Filter_Function('twig_default_filter'), - 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'), + new Twig_SimpleFilter('default', '_twig_default_filter', array('node_class' => 'Twig_Node_Expression_Filter_Default')), + new Twig_SimpleFilter('keys', 'twig_get_array_keys_filter'), // escaping - 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), - 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('escape', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('e', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), ); if (function_exists('mb_get_info')) { - $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true)); - $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true)); + $filters[] = new Twig_SimpleFilter('upper', 'twig_upper_filter', array('needs_environment' => true)); + $filters[] = new Twig_SimpleFilter('lower', 'twig_lower_filter', array('needs_environment' => true)); } return $filters; @@ -93,29 +186,33 @@ class Twig_Extension_Core extends Twig_Extension public function getFunctions() { return array( - 'range' => new Twig_Function_Function('range'), - 'constant' => new Twig_Function_Function('constant'), - 'cycle' => new Twig_Function_Function('twig_cycle'), + new Twig_SimpleFunction('range', 'range'), + new Twig_SimpleFunction('constant', 'twig_constant'), + new Twig_SimpleFunction('cycle', 'twig_cycle'), + new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)), + new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)), + new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true, 'is_safe' => array('all'))), ); } /** - * Returns a list of filters to add to the existing list. + * Returns a list of tests to add to the existing list. * - * @return array An array of filters + * @return array An array of tests */ public function getTests() { return array( - 'even' => new Twig_Test_Function('twig_test_even'), - 'odd' => new Twig_Test_Function('twig_test_odd'), - 'defined' => new Twig_Test_Function('twig_test_defined'), - 'sameas' => new Twig_Test_Function('twig_test_sameas'), - 'none' => new Twig_Test_Function('twig_test_none'), - 'null' => new Twig_Test_Function('twig_test_none'), - 'divisibleby' => new Twig_Test_Function('twig_test_divisibleby'), - 'constant' => new Twig_Test_Function('twig_test_constant'), - 'empty' => new Twig_Test_Function('twig_test_empty'), + new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')), + new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')), + new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')), + new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), + new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), + new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), + new Twig_SimpleTest('empty', 'twig_test_empty'), + new Twig_SimpleTest('iterable', 'twig_test_iterable'), ); } @@ -129,15 +226,15 @@ class Twig_Extension_Core extends Twig_Extension return array( array( 'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), - '-' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Neg'), - '+' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Pos'), + '-' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Neg'), + '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'), ), array( - 'b-and' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-xor' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-or' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), @@ -146,6 +243,7 @@ class Twig_Extension_Core extends Twig_Extension '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), @@ -155,7 +253,6 @@ class Twig_Extension_Core extends Twig_Extension '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '..' => array('precedence' => 110, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), ), ); @@ -169,13 +266,35 @@ class Twig_Extension_Core extends Twig_Extension public function parseTestExpression(Twig_Parser $parser, $node) { $stream = $parser->getStream(); - $name = $stream->expect(Twig_Token::NAME_TYPE); + $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); $arguments = null; if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { - $arguments = $parser->getExpressionParser()->parseArguments(); + $arguments = $parser->getExpressionParser()->parseArguments(true); } - return new Twig_Node_Expression_Test($node, $name->getValue(), $arguments, $parser->getCurrentToken()->getLine()); + $class = $this->getTestNodeClass($parser, $name, $node->getLine()); + + return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); + } + + protected function getTestNodeClass(Twig_Parser $parser, $name, $line) + { + $env = $parser->getEnvironment(); + $testMap = $env->getTests(); + if (!isset($testMap[$name])) { + $message = sprintf('The test "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); + } + + if ($testMap[$name] instanceof Twig_SimpleTest) { + return $testMap[$name]->getNodeClass(); + } + + return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test'; } /** @@ -192,18 +311,77 @@ class Twig_Extension_Core extends Twig_Extension /** * Cycles over a value. * - * @param ArrayAccess|array $values An array or an ArrayAccess instance - * @param integer $i The cycle value + * @param ArrayAccess|array $values An array or an ArrayAccess instance + * @param integer $position The cycle position * * @return string The next value in the cycle */ -function twig_cycle($values, $i) +function twig_cycle($values, $position) { if (!is_array($values) && !$values instanceof ArrayAccess) { return $values; } - return $values[$i % count($values)]; + return $values[$position % count($values)]; +} + +/** + * Returns a random value depending on the supplied parameter type: + * - a random item from a Traversable or array + * - a random character from a string + * - a random integer between 0 and the integer parameter + * + * @param Twig_Environment $env A Twig_Environment instance + * @param Traversable|array|integer|string $values The values to pick a random item from + * + * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is). + * + * @return mixed A random value from the given sequence + */ +function twig_random(Twig_Environment $env, $values = null) +{ + if (null === $values) { + return mt_rand(); + } + + if (is_int($values) || is_float($values)) { + return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values); + } + + if ($values instanceof Traversable) { + $values = iterator_to_array($values); + } elseif (is_string($values)) { + if ('' === $values) { + return ''; + } + if (null !== $charset = $env->getCharset()) { + if ('UTF-8' != $charset) { + $values = twig_convert_encoding($values, 'UTF-8', $charset); + } + + // unicode version of str_split() + // split at all positions, but not after the start and not before the end + $values = preg_split('/(? $value) { + $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8'); + } + } + } else { + return $values[mt_rand(0, strlen($values) - 1)]; + } + } + + if (!is_array($values)) { + return $values; + } + + if (0 === count($values)) { + throw new Twig_Error_Runtime('The random function cannot pick from an empty array.'); + } + + return $values[array_rand($values, 1)]; } /** @@ -213,44 +391,143 @@ function twig_cycle($values, $i) * {{ post.published_at|date("m/d/Y") }} * * - * @param DateTime|string $date A date - * @param string $format A format - * @param DateTimeZone|string $timezone A timezone + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|DateInterval|string $date A date + * @param string $format A format + * @param DateTimeZone|string $timezone A timezone * - * @return string The formatter date + * @return string The formatted date */ -function twig_date_format_filter($date, $format = 'F j, Y H:i', $timezone = null) +function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null) { - if (!$date instanceof DateTime) { - if (ctype_digit((string) $date)) { - $date = new DateTime('@'.$date); - $date->setTimezone(new DateTimeZone(date_default_timezone_get())); - } else { - $date = new DateTime($date); - } + if (null === $format) { + $formats = $env->getExtension('core')->getDateFormat(); + $format = $date instanceof DateInterval ? $formats[1] : $formats[0]; } - if (null !== $timezone) { - if (!$timezone instanceof DateTimeZone) { - $timezone = new DateTimeZone($timezone); - } - - $date->setTimezone($timezone); + if ($date instanceof DateInterval) { + return $date->format($format); } - return $date->format($format); + return twig_date_converter($env, $date, $timezone)->format($format); } /** - * URL encodes a string. + * Returns a new date object modified * - * @param string $url A URL - * @param bool $raw true to use rawurlencode() instead of urlencode + *

      + *   {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
      + * 
      + * + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|string $date A date + * @param string $modifier A modifier string + * + * @return DateTime A new date object + */ +function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) +{ + $date = twig_date_converter($env, $date, false); + $date->modify($modifier); + + return $date; +} + +/** + * Converts an input to a DateTime instance. + * + *
      + *    {% if date(user.created_at) < date('+2days') %}
      + *      {# do something #}
      + *    {% endif %}
      + * 
      + * + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|string $date A date + * @param DateTimeZone|string $timezone A timezone + * + * @return DateTime A DateTime instance + */ +function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null) +{ + // determine the timezone + if (!$timezone) { + $defaultTimezone = $env->getExtension('core')->getTimezone(); + } elseif (!$timezone instanceof DateTimeZone) { + $defaultTimezone = new DateTimeZone($timezone); + } else { + $defaultTimezone = $timezone; + } + + if ($date instanceof DateTime) { + $date = clone $date; + if (false !== $timezone) { + $date->setTimezone($defaultTimezone); + } + + return $date; + } + + $asString = (string) $date; + if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { + $date = '@'.$date; + } + + $date = new DateTime($date, $defaultTimezone); + if (false !== $timezone) { + $date->setTimezone($defaultTimezone); + } + + return $date; +} + +/** + * Number format filter. + * + * All of the formatting options can be left null, in that case the defaults will + * be used. Supplying any of the parameters will override the defaults set in the + * environment object. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $number A float/int/string of the number to format + * @param integer $decimal The number of decimal points to display. + * @param string $decimalPoint The character(s) to use for the decimal point. + * @param string $thousandSep The character(s) to use for the thousands separator. + * + * @return string The formatted number + */ +function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null) +{ + $defaults = $env->getExtension('core')->getNumberFormat(); + if (null === $decimal) { + $decimal = $defaults[0]; + } + + if (null === $decimalPoint) { + $decimalPoint = $defaults[1]; + } + + if (null === $thousandSep) { + $thousandSep = $defaults[2]; + } + + return number_format((float) $number, $decimal, $decimalPoint, $thousandSep); +} + +/** + * URL encodes a string as a path segment or an array as a query string. + * + * @param string|array $url A URL or an array of query parameters + * @param bool $raw true to use rawurlencode() instead of urlencode * * @return string The URL encoded value */ function twig_urlencode_filter($url, $raw = false) { + if (is_array($url)) { + return http_build_query($url, '', '&'); + } + if ($raw) { return rawurlencode($url); } @@ -260,7 +537,7 @@ function twig_urlencode_filter($url, $raw = false) if (version_compare(PHP_VERSION, '5.3.0', '<')) { /** - * JSON encodes a PHP variable. + * JSON encodes a variable. * * @param mixed $value The value to encode. * @param integer $options Not used on PHP 5.2.x @@ -279,7 +556,7 @@ if (version_compare(PHP_VERSION, '5.3.0', '<')) { } } else { /** - * JSON encodes a PHP variable. + * JSON encodes a variable. * * @param mixed $value The value to encode. * @param integer $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT @@ -324,12 +601,72 @@ function _twig_markup2string(&$value) function twig_array_merge($arr1, $arr2) { if (!is_array($arr1) || !is_array($arr2)) { - throw new Twig_Error_Runtime('The merge filter only work with arrays or hashes.'); + throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.'); } return array_merge($arr1, $arr2); } +/** + * Slices a variable. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * @param integer $start Start of the slice + * @param integer $length Size of the slice + * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) + * + * @return mixed The sliced variable + */ +function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false) +{ + if ($item instanceof Traversable) { + $item = iterator_to_array($item, false); + } + + if (is_array($item)) { + return array_slice($item, $start, $length, $preserveKeys); + } + + $item = (string) $item; + + if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) { + return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset); + } + + return null === $length ? substr($item, $start) : substr($item, $start, $length); +} + +/** + * Returns the first element of the item. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * + * @return mixed The first element of the item + */ +function twig_first(Twig_Environment $env, $item) +{ + $elements = twig_slice($env, $item, 0, 1, false); + + return is_string($elements) ? $elements[0] : current($elements); +} + +/** + * Returns the last element of the item. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * + * @return mixed The last element of the item + */ +function twig_last(Twig_Environment $env, $item) +{ + $elements = twig_slice($env, $item, -1, 1, false); + + return is_string($elements) ? $elements[0] : current($elements); +} + /** * Joins the values to a string. * @@ -350,30 +687,55 @@ function twig_array_merge($arr1, $arr2) */ function twig_join_filter($value, $glue = '') { + if ($value instanceof Traversable) { + $value = iterator_to_array($value, false); + } + return implode($glue, (array) $value); } /** - * Returns the value or the default value when it is undefined or empty. + * Splits the string into an array. * *
      + *  {{ "one,two,three"|split(',') }}
      + *  {# returns [one, two, three] #}
        *
      - *  {{ var.foo|default('foo item on var is not defined') }}
      + *  {{ "one,two,three,four,five"|split(',', 3) }}
      + *  {# returns [one, two, "three,four,five"] #}
        *
      + *  {{ "123"|split('') }}
      + *  {# returns [1, 2, 3] #}
      + *
      + *  {{ "aabbcc"|split('', 2) }}
      + *  {# returns [aa, bb, cc] #}
        * 
      * - * @param mixed $value A value - * @param mixed $default The default value + * @param string $value A string + * @param string $delimiter The delimiter + * @param integer $limit The limit * - * @param mixed The value or the default value; + * @return array The split string as an array */ -function twig_default_filter($value, $default = '') +function twig_split_filter($value, $delimiter, $limit = null) +{ + if (empty($delimiter)) { + return str_split($value, null === $limit ? 1 : $limit); + } + + return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); +} + +// The '_default' filter is used internally to avoid using the ternary operator +// which costs a lot for big contexts (before PHP 5.4). So, on average, +// a function call is cheaper. +function _twig_default_filter($value, $default = '') { if (twig_test_empty($value)) { return $default; - } else { - return $value; } + + return $value; } /** @@ -405,23 +767,43 @@ function twig_get_array_keys_filter($array) } /** - * Reverses an array. + * Reverses a variable. * - * @param array|Traversable $array An array or a Traversable instance + * @param Twig_Environment $env A Twig_Environment instance + * @param array|Traversable|string $item An array, a Traversable instance, or a string + * @param Boolean $preserveKeys Whether to preserve key or not * - * return array The array reversed + * @return mixed The reversed input */ -function twig_reverse_filter($array) +function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false) { - if (is_object($array) && $array instanceof Traversable) { - return array_reverse(iterator_to_array($array)); + if (is_object($item) && $item instanceof Traversable) { + return array_reverse(iterator_to_array($item), $preserveKeys); } - if (!is_array($array)) { - return array(); + if (is_array($item)) { + return array_reverse($item, $preserveKeys); } - return array_reverse($array); + if (null !== $charset = $env->getCharset()) { + $string = (string) $item; + + if ('UTF-8' != $charset) { + $item = twig_convert_encoding($string, 'UTF-8', $charset); + } + + preg_match_all('/./us', $item, $matches); + + $string = implode('', array_reverse($matches[0])); + + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, $charset, 'UTF-8'); + } + + return $string; + } + + return strrev((string) $item); } /** @@ -440,78 +822,151 @@ function twig_sort_filter($array) function twig_in_filter($value, $compare) { if (is_array($compare)) { - return in_array($value, $compare); + return in_array($value, $compare, is_object($value)); } elseif (is_string($compare)) { + if (!strlen($value)) { + return empty($compare); + } + return false !== strpos($compare, (string) $value); - } elseif (is_object($compare) && $compare instanceof Traversable) { - return in_array($value, iterator_to_array($compare, false)); + } elseif ($compare instanceof Traversable) { + return in_array($value, iterator_to_array($compare, false), is_object($value)); } return false; } -/** - * Replaces placeholders in a string. - * - *
      - *  {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
      - * 
      - * - * @param string $pattern A string - * @param string $replacements The values for the placeholders - * - * @return string The string where the placeholders have been replaced - */ -function twig_strtr($pattern, $replacements) -{ - return str_replace(array_keys($replacements), array_values($replacements), $pattern); -} - /** * Escapes a string. * - * @param Twig_Environment $env A Twig_Environment instance - * @param string $string The value to be escaped - * @param string $type The escaping strategy - * @param string $charset The charset + * @param Twig_Environment $env A Twig_Environment instance + * @param string $string The value to be escaped + * @param string $strategy The escaping strategy + * @param string $charset The charset + * @param Boolean $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) */ -function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $charset = null) +function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false) { - if (is_object($string) && $string instanceof Twig_Markup) { + if ($autoescape && $string instanceof Twig_Markup) { return $string; } - if (!is_string($string) && !(is_object($string) && method_exists($string, '__toString'))) { - return $string; + if (!is_string($string)) { + if (is_object($string) && method_exists($string, '__toString')) { + $string = (string) $string; + } else { + return $string; + } } if (null === $charset) { $charset = $env->getCharset(); } - switch ($type) { + switch ($strategy) { + case 'html': + // see http://php.net/htmlspecialchars + + // Using a static variable to avoid initializing the array + // each time the function is called. Moving the declaration on the + // top of the function slow downs other escaping strategies. + static $htmlspecialcharsCharsets = array( + 'ISO-8859-1' => true, 'ISO8859-1' => true, + 'ISO-8859-15' => true, 'ISO8859-15' => true, + 'utf-8' => true, 'UTF-8' => true, + 'CP866' => true, 'IBM866' => true, '866' => true, + 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, + '1251' => true, + 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, + 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, + 'BIG5' => true, '950' => true, + 'GB2312' => true, '936' => true, + 'BIG5-HKSCS' => true, + 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, + 'EUC-JP' => true, 'EUCJP' => true, + 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, + ); + + if (isset($htmlspecialcharsCharsets[$charset])) { + return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); + } + + if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) { + // cache the lowercase variant for future iterations + $htmlspecialcharsCharsets[$charset] = true; + + return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); + } + + $string = twig_convert_encoding($string, 'UTF-8', $charset); + $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + + return twig_convert_encoding($string, $charset, 'UTF-8'); + case 'js': // escape all non-alphanumeric characters // into their \xHH or \uHHHH representations if ('UTF-8' != $charset) { - $string = _twig_convert_encoding($string, 'UTF-8', $charset); + $string = twig_convert_encoding($string, 'UTF-8', $charset); } - if (null === $string = preg_replace_callback('#[^\p{L}\p{N} ]#u', '_twig_escape_js_callback', $string)) { + if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } + $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string); + if ('UTF-8' != $charset) { - $string = _twig_convert_encoding($string, $charset, 'UTF-8'); + $string = twig_convert_encoding($string, $charset, 'UTF-8'); } return $string; - case 'html': - return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); + case 'css': + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, 'UTF-8', $charset); + } + + if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); + } + + $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string); + + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, $charset, 'UTF-8'); + } + + return $string; + + case 'html_attr': + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, 'UTF-8', $charset); + } + + if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); + } + + $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string); + + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, $charset, 'UTF-8'); + } + + return $string; + + case 'url': + // hackish test to avoid version_compare that is much slower, this works unless PHP releases a 5.10.* + // at that point however PHP 5.2.* support can be removed + if (PHP_VERSION < '5.3.0') { + return str_replace('%7E', '~', rawurlencode($string)); + } + + return rawurlencode($string); default: - throw new Twig_Error_Runtime(sprintf('Invalid escape type "%s".', $type)); + throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy)); } } @@ -521,28 +976,26 @@ function twig_escape_filter_is_safe(Twig_Node $filterArgs) foreach ($filterArgs as $arg) { if ($arg instanceof Twig_Node_Expression_Constant) { return array($arg->getAttribute('value')); - } else { - return array(); } - break; + return array(); } return array('html'); } -if (function_exists('iconv')) { - function _twig_convert_encoding($string, $to, $from) - { - return iconv($from, $to, $string); - } -} elseif (function_exists('mb_convert_encoding')) { - function _twig_convert_encoding($string, $to, $from) +if (function_exists('mb_convert_encoding')) { + function twig_convert_encoding($string, $to, $from) { return mb_convert_encoding($string, $to, $from); } +} elseif (function_exists('iconv')) { + function twig_convert_encoding($string, $to, $from) + { + return iconv($from, $to, $string); + } } else { - function _twig_convert_encoding($string, $to, $from) + function twig_convert_encoding($string, $to, $from) { throw new Twig_Error_Runtime('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).'); } @@ -554,22 +1007,98 @@ function _twig_escape_js_callback($matches) // \xHH if (!isset($char[1])) { - return '\\x'.substr('00'.bin2hex($char), -2); + return '\\x'.strtoupper(substr('00'.bin2hex($char), -2)); } // \uHHHH - $char = _twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); + $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); - return '\\u'.substr('0000'.bin2hex($char), -4); + return '\\u'.strtoupper(substr('0000'.bin2hex($char), -4)); +} + +function _twig_escape_css_callback($matches) +{ + $char = $matches[0]; + + // \xHH + if (!isset($char[1])) { + $hex = ltrim(strtoupper(bin2hex($char)), '0'); + if (0 === strlen($hex)) { + $hex = '0'; + } + + return '\\'.$hex.' '; + } + + // \uHHHH + $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); + + return '\\'.ltrim(strtoupper(bin2hex($char)), '0').' '; +} + +/** + * This function is adapted from code coming from Zend Framework. + * + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +function _twig_escape_html_attr_callback($matches) +{ + /* + * While HTML supports far more named entities, the lowest common denominator + * has become HTML5's XML Serialisation which is restricted to the those named + * entities that XML supports. Using HTML entities would result in this error: + * XML Parsing Error: undefined entity + */ + static $entityMap = array( + 34 => 'quot', /* quotation mark */ + 38 => 'amp', /* ampersand */ + 60 => 'lt', /* less-than sign */ + 62 => 'gt', /* greater-than sign */ + ); + + $chr = $matches[0]; + $ord = ord($chr); + + /** + * The following replaces characters undefined in HTML with the + * hex entity for the Unicode replacement character. + */ + if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f)) { + return '�'; + } + + /** + * Check if the current character to escape has a name entity we should + * replace it with while grabbing the hex value of the character. + */ + if (strlen($chr) == 1) { + $hex = strtoupper(substr('00'.bin2hex($chr), -2)); + } else { + $chr = twig_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); + $hex = strtoupper(substr('0000'.bin2hex($chr), -4)); + } + + $int = hexdec($hex); + if (array_key_exists($int, $entityMap)) { + return sprintf('&%s;', $entityMap[$int]); + } + + /** + * Per OWASP recommendations, we'll use hex entities for any other + * characters where a named entity does not exist. + */ + + return sprintf('&#x%s;', $hex); } // add multibyte extensions if possible if (function_exists('mb_get_info')) { /** - * Returns the length of a PHP variable. + * Returns the length of a variable. * * @param Twig_Environment $env A Twig_Environment instance - * @param mixed $thing A PHP variable + * @param mixed $thing A variable * * @return integer The length of the value */ @@ -648,13 +1177,12 @@ if (function_exists('mb_get_info')) { } } // and byte fallback -else -{ +else { /** - * Returns the length of a PHP variable. + * Returns the length of a variable. * * @param Twig_Environment $env A Twig_Environment instance - * @param mixed $thing A PHP variable + * @param mixed $thing A variable * * @return integer The length of the value */ @@ -693,134 +1221,11 @@ else /* used internally */ function twig_ensure_traversable($seq) { - if (is_array($seq) || (is_object($seq) && $seq instanceof Traversable)) { + if ($seq instanceof Traversable || is_array($seq)) { return $seq; - } else { - return array(); } -} -/** - * Checks that a variable points to the same memory address than another one. - * - *
      - * {% if foo.attribute is sameas(false) %}
      - *    the foo attribute really is the ``false`` PHP value
      - * {% endif %}
      - * 
      - * - * @param mixed $value A PHP variable - * @param mixed $test The PHP variable to test against - * - * @return Boolean true if the values are the same, false otherwise - */ -function twig_test_sameas($value, $test) -{ - return $value === $test; -} - -/** - * Checks that a variable is null. - * - *
      - *  {{ var is none }}
      - * 
      - * - * @param mixed $value a PHP variable. - * - * @return Boolean true if the value is null, false otherwise - */ -function twig_test_none($value) -{ - return null === $value; -} - -/** - * Checks if a variable is divisible by a number. - * - *
      - *  {% if loop.index is divisibleby(3) %}
      - * 
      - * - * @param integer $value A PHP value - * @param integer $num A number - * - * @return Boolean true if the value is divisible by the number, false otherwise - */ -function twig_test_divisibleby($value, $num) -{ - return 0 == $value % $num; -} - -/** - * Checks if a number is even. - * - *
      - *  {{ var is even }}
      - * 
      - * - * @param integer $value An integer - * - * @return Boolean true if the value is even, false otherwise - */ -function twig_test_even($value) -{ - return $value % 2 == 0; -} - -/** - * Checks if a number is odd. - * - *
      - *  {{ var is odd }}
      - * 
      - * - * @param integer $value An integer - * - * @return Boolean true if the value is odd, false otherwise - */ -function twig_test_odd($value) -{ - return $value % 2 == 1; -} - -/** - * Checks if a variable is the exact same value as a constant. - * - *
      - *  {% if post.status is constant('Post::PUBLISHED') %}
      - *    the status attribute is exactly the same as Post::PUBLISHED
      - *  {% endif %}
      - * 
      - * - * @param mixed $value A PHP value - * @param mixed $constant The constant to test against - * - * @return Boolean true if the value is the same as the constant, false otherwise - */ -function twig_test_constant($value, $constant) -{ - return constant($constant) === $value; -} - -/** - * Checks if a variable is defined in the current context. - * - *
      - * {# defined works with variable names #}
      - * {% if foo is defined %}
      - *     {# ... #}
      - * {% endif %}
      - * 
      - * - * @param mixed $name A PHP variable - * @param array $context The current context - * - * @return Boolean true if the value is defined, false otherwise - */ -function twig_test_defined($name, $context) -{ - return array_key_exists($name, $context); + return array(); } /** @@ -833,7 +1238,7 @@ function twig_test_defined($name, $context) * {% endif %} * * - * @param mixed $value A PHP variable + * @param mixed $value A variable * * @return Boolean true if the value is empty, false otherwise */ @@ -842,5 +1247,109 @@ function twig_test_empty($value) if ($value instanceof Countable) { return 0 == count($value); } - return false === $value || (empty($value) && '0' != $value); + + return '' === $value || false === $value || null === $value || array() === $value; +} + +/** + * Checks if a variable is traversable. + * + *
      + * {# evaluates to true if the foo variable is an array or a traversable object #}
      + * {% if foo is traversable %}
      + *     {# ... #}
      + * {% endif %}
      + * 
      + * + * @param mixed $value A variable + * + * @return Boolean true if the value is traversable + */ +function twig_test_iterable($value) +{ + return $value instanceof Traversable || is_array($value); +} + +/** + * Renders a template. + * + * @param string $template The template to render + * @param array $variables The variables to pass to the template + * @param Boolean $with_context Whether to pass the current context variables or not + * @param Boolean $ignore_missing Whether to ignore missing templates or not + * @param Boolean $sandboxed Whether to sandbox the template or not + * + * @return string The rendered template + */ +function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false) +{ + if ($withContext) { + $variables = array_merge($context, $variables); + } + + if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) { + $sandbox = $env->getExtension('sandbox'); + if (!$alreadySandboxed = $sandbox->isSandboxed()) { + $sandbox->enableSandbox(); + } + } + + try { + return $env->resolveTemplate($template)->render($variables); + } catch (Twig_Error_Loader $e) { + if (!$ignoreMissing) { + throw $e; + } + } + + if ($isSandboxed && !$alreadySandboxed) { + $sandbox->disableSandbox(); + } +} + +/** + * Provides the ability to get constants from instances as well as class/global constants. + * + * @param string $constant The name of the constant + * @param null|object $object The object to get the constant from + * + * @return string + */ +function twig_constant($constant, $object = null) +{ + if (null !== $object) { + $constant = get_class($object).'::'.$constant; + } + + return constant($constant); +} + +/** + * Batches item. + * + * @param array $items An array of items + * @param integer $size The size of the batch + * @param string $fill A string to fill missing items + * + * @return array + */ +function twig_array_batch($items, $size, $fill = null) +{ + if ($items instanceof Traversable) { + $items = iterator_to_array($items, false); + } + + $size = ceil($size); + + $result = array_chunk($items, $size, true); + + if (null !== $fill) { + $last = count($result) - 1; + $result[$last] = array_merge( + $result[$last], + array_fill(0, $size - count($result[$last]), $fill) + ); + } + + return $result; } diff --git a/inc/lib/Twig/Extension/Debug.php b/inc/lib/Twig/Extension/Debug.php new file mode 100644 index 00000000..e3a85bfe --- /dev/null +++ b/inc/lib/Twig/Extension/Debug.php @@ -0,0 +1,71 @@ + $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)), + ); + } + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + public function getName() + { + return 'debug'; + } +} + +function twig_var_dump(Twig_Environment $env, $context) +{ + if (!$env->isDebug()) { + return; + } + + ob_start(); + + $count = func_num_args(); + if (2 === $count) { + $vars = array(); + foreach ($context as $key => $value) { + if (!$value instanceof Twig_Template) { + $vars[$key] = $value; + } + } + + var_dump($vars); + } else { + for ($i = 2; $i < $count; $i++) { + var_dump(func_get_arg($i)); + } + } + + return ob_get_clean(); +} diff --git a/inc/lib/Twig/Extension/Escaper.php b/inc/lib/Twig/Extension/Escaper.php index 43ae1113..c9a7f68e 100644 --- a/inc/lib/Twig/Extension/Escaper.php +++ b/inc/lib/Twig/Extension/Escaper.php @@ -10,11 +10,11 @@ */ class Twig_Extension_Escaper extends Twig_Extension { - protected $autoescape; + protected $defaultStrategy; - public function __construct($autoescape = true) + public function __construct($defaultStrategy = 'html') { - $this->autoescape = $autoescape; + $this->setDefaultStrategy($defaultStrategy); } /** @@ -45,13 +45,44 @@ class Twig_Extension_Escaper extends Twig_Extension public function getFilters() { return array( - 'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))), + new Twig_SimpleFilter('raw', 'twig_raw_filter', array('is_safe' => array('all'))), ); } - public function isGlobal() + /** + * Sets the default strategy to use when not defined by the user. + * + * The strategy can be a valid PHP callback that takes the template + * "filename" as an argument and returns the strategy to use. + * + * @param mixed $defaultStrategy An escaping strategy + */ + public function setDefaultStrategy($defaultStrategy) { - return $this->autoescape; + // for BC + if (true === $defaultStrategy) { + $defaultStrategy = 'html'; + } + + $this->defaultStrategy = $defaultStrategy; + } + + /** + * Gets the default strategy to use when not defined by the user. + * + * @param string $filename The template "filename" + * + * @return string The default strategy to use for the template + */ + public function getDefaultStrategy($filename) + { + // disable string callables to avoid calling a function named html or js, + // or any other upcoming escaping strategy + if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) { + return call_user_func($this->defaultStrategy, $filename); + } + + return $this->defaultStrategy; } /** @@ -74,4 +105,3 @@ function twig_raw_filter($string) { return $string; } - diff --git a/inc/lib/Twig/Extension/Staging.php b/inc/lib/Twig/Extension/Staging.php new file mode 100644 index 00000000..8ab0f459 --- /dev/null +++ b/inc/lib/Twig/Extension/Staging.php @@ -0,0 +1,113 @@ + + */ +class Twig_Extension_Staging extends Twig_Extension +{ + protected $functions = array(); + protected $filters = array(); + protected $visitors = array(); + protected $tokenParsers = array(); + protected $globals = array(); + protected $tests = array(); + + public function addFunction($name, $function) + { + $this->functions[$name] = $function; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return $this->functions; + } + + public function addFilter($name, $filter) + { + $this->filters[$name] = $filter; + } + + /** + * {@inheritdoc} + */ + public function getFilters() + { + return $this->filters; + } + + public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) + { + $this->visitors[] = $visitor; + } + + /** + * {@inheritdoc} + */ + public function getNodeVisitors() + { + return $this->visitors; + } + + public function addTokenParser(Twig_TokenParserInterface $parser) + { + $this->tokenParsers[] = $parser; + } + + /** + * {@inheritdoc} + */ + public function getTokenParsers() + { + return $this->tokenParsers; + } + + public function addGlobal($name, $value) + { + $this->globals[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function getGlobals() + { + return $this->globals; + } + + public function addTest($name, $test) + { + $this->tests[$name] = $test; + } + + /** + * {@inheritdoc} + */ + public function getTests() + { + return $this->tests; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'staging'; + } +} diff --git a/inc/lib/Twig/Extension/StringLoader.php b/inc/lib/Twig/Extension/StringLoader.php new file mode 100644 index 00000000..20f3f994 --- /dev/null +++ b/inc/lib/Twig/Extension/StringLoader.php @@ -0,0 +1,64 @@ + true)), + ); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'string_loader'; + } +} + +/** + * Loads a template from a string. + * + *
      + * {{ include(template_from_string("Hello {{ name }}")) }}
      + * 
      + * + * @param Twig_Environment $env A Twig_Environment instance + * @param string $template A template as a string + * + * @return Twig_Template A Twig_Template instance + */ +function twig_template_from_string(Twig_Environment $env, $template) +{ + static $loader; + + if (null === $loader) { + $loader = new Twig_Loader_String(); + } + + $current = $env->getLoader(); + $env->setLoader($loader); + try { + $template = $env->loadTemplate($template); + } catch (Exception $e) { + $env->setLoader($current); + + throw $e; + } + $env->setLoader($current); + + return $template; +} diff --git a/inc/lib/Twig/ExtensionInterface.php b/inc/lib/Twig/ExtensionInterface.php index f8b232a5..f189e9d9 100644 --- a/inc/lib/Twig/ExtensionInterface.php +++ b/inc/lib/Twig/ExtensionInterface.php @@ -12,8 +12,7 @@ /** * Interface implemented by extension classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_ExtensionInterface { @@ -24,61 +23,61 @@ interface Twig_ExtensionInterface * * @param Twig_Environment $environment The current Twig_Environment instance */ - function initRuntime(Twig_Environment $environment); + public function initRuntime(Twig_Environment $environment); /** * Returns the token parser instances to add to the existing list. * * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances */ - function getTokenParsers(); + public function getTokenParsers(); /** * Returns the node visitor instances to add to the existing list. * * @return array An array of Twig_NodeVisitorInterface instances */ - function getNodeVisitors(); + public function getNodeVisitors(); /** * Returns a list of filters to add to the existing list. * * @return array An array of filters */ - function getFilters(); + public function getFilters(); /** * Returns a list of tests to add to the existing list. * * @return array An array of tests */ - function getTests(); + public function getTests(); /** * Returns a list of functions to add to the existing list. * * @return array An array of functions */ - function getFunctions(); + public function getFunctions(); /** * Returns a list of operators to add to the existing list. * * @return array An array of operators */ - function getOperators(); + public function getOperators(); /** - * Returns a list of global functions to add to the existing list. + * Returns a list of global variables to add to the existing list. * - * @return array An array of global functions + * @return array An array of global variables */ - function getGlobals(); + public function getGlobals(); /** * Returns the name of the extension. * * @return string The extension name */ - function getName(); + public function getName(); } diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 58a98c40..8c8d9456 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -23,7 +23,6 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension 'count' => new Twig_Filter_Function('count'), 'ago' => new Twig_Filter_Function('ago'), 'until' => new Twig_Filter_Function('until'), - 'split' => new Twig_Filter_Function('twig_split_filter'), 'push' => new Twig_Filter_Function('twig_push_filter'), 'bidi_cleanup' => new Twig_Filter_Function('bidi_cleanup'), 'addslashes' => new Twig_Filter_Function('addslashes') @@ -61,10 +60,6 @@ function twig_timezone_function() { return 'Z'; } -function twig_split_filter($str, $delim) { - return explode($delim, $str); -} - function twig_push_filter($array, $value) { array_push($array, $value); return $array; diff --git a/inc/lib/Twig/Filter.php b/inc/lib/Twig/Filter.php index 9595a1a8..5cfbb662 100644 --- a/inc/lib/Twig/Filter.php +++ b/inc/lib/Twig/Filter.php @@ -12,12 +12,15 @@ /** * Represents a template filter. * - * @package twig - * @author Fabien Potencier + * Use Twig_SimpleFilter instead. + * + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ -abstract class Twig_Filter implements Twig_FilterInterface +abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface { protected $options; + protected $arguments = array(); public function __construct(array $options = array()) { @@ -25,9 +28,21 @@ abstract class Twig_Filter implements Twig_FilterInterface 'needs_environment' => false, 'needs_context' => false, 'pre_escape' => null, + 'preserves_safety' => null, + 'callable' => null, ), $options); } + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + public function needsEnvironment() { return $this->options['needs_environment']; @@ -47,12 +62,20 @@ abstract class Twig_Filter implements Twig_FilterInterface if (isset($this->options['is_safe_callback'])) { return call_user_func($this->options['is_safe_callback'], $filterArgs); } + } - return array(); + public function getPreservesSafety() + { + return $this->options['preserves_safety']; } public function getPreEscape() { return $this->options['pre_escape']; } + + public function getCallable() + { + return $this->options['callable']; + } } diff --git a/inc/lib/Twig/Filter/Function.php b/inc/lib/Twig/Filter/Function.php index 1de078b2..ad374a55 100644 --- a/inc/lib/Twig/Filter/Function.php +++ b/inc/lib/Twig/Filter/Function.php @@ -12,8 +12,10 @@ /** * Represents a function template filter. * - * @package twig - * @author Fabien Potencier + * Use Twig_SimpleFilter instead. + * + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Filter_Function extends Twig_Filter { @@ -21,6 +23,8 @@ class Twig_Filter_Function extends Twig_Filter public function __construct($function, array $options = array()) { + $options['callable'] = $function; + parent::__construct($options); $this->function = $function; diff --git a/inc/lib/Twig/Filter/Method.php b/inc/lib/Twig/Filter/Method.php index d831e0f2..63c8c3be 100644 --- a/inc/lib/Twig/Filter/Method.php +++ b/inc/lib/Twig/Filter/Method.php @@ -12,15 +12,20 @@ /** * Represents a method template filter. * - * @package twig - * @author Fabien Potencier + * Use Twig_SimpleFilter instead. + * + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Filter_Method extends Twig_Filter { - protected $extension, $method; + protected $extension; + protected $method; public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + parent::__construct($options); $this->extension = $extension; diff --git a/inc/lib/Twig/Filter/Node.php b/inc/lib/Twig/Filter/Node.php new file mode 100644 index 00000000..8744c5e0 --- /dev/null +++ b/inc/lib/Twig/Filter/Node.php @@ -0,0 +1,39 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +class Twig_Filter_Node extends Twig_Filter +{ + protected $class; + + public function __construct($class, array $options = array()) + { + parent::__construct($options); + + $this->class = $class; + } + + public function getClass() + { + return $this->class; + } + + public function compile() + { + } +} diff --git a/inc/lib/Twig/FilterCallableInterface.php b/inc/lib/Twig/FilterCallableInterface.php new file mode 100644 index 00000000..145534df --- /dev/null +++ b/inc/lib/Twig/FilterCallableInterface.php @@ -0,0 +1,23 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_FilterCallableInterface +{ + public function getCallable(); +} diff --git a/inc/lib/Twig/FilterInterface.php b/inc/lib/Twig/FilterInterface.php index 4ac19ceb..5319ecc9 100644 --- a/inc/lib/Twig/FilterInterface.php +++ b/inc/lib/Twig/FilterInterface.php @@ -12,8 +12,10 @@ /** * Represents a template filter. * - * @package twig - * @author Fabien Potencier + * Use Twig_SimpleFilter instead. + * + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_FilterInterface { @@ -22,13 +24,19 @@ interface Twig_FilterInterface * * @return string The PHP code for the filter */ - function compile(); + public function compile(); - function needsEnvironment(); + public function needsEnvironment(); - function needsContext(); + public function needsContext(); - function getSafe(Twig_Node $filterArgs); + public function getSafe(Twig_Node $filterArgs); - function getPreEscape(); + public function getPreservesSafety(); + + public function getPreEscape(); + + public function setArguments($arguments); + + public function getArguments(); } diff --git a/inc/lib/Twig/Function.php b/inc/lib/Twig/Function.php index 1197924a..b5ffb2b0 100644 --- a/inc/lib/Twig/Function.php +++ b/inc/lib/Twig/Function.php @@ -12,21 +12,35 @@ /** * Represents a template function. * - * @package twig - * @author Fabien Potencier + * Use Twig_SimpleFunction instead. + * + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ -abstract class Twig_Function implements Twig_FunctionInterface +abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface { protected $options; + protected $arguments = array(); public function __construct(array $options = array()) { $this->options = array_merge(array( 'needs_environment' => false, 'needs_context' => false, + 'callable' => null, ), $options); } + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + public function needsEnvironment() { return $this->options['needs_environment']; @@ -49,4 +63,9 @@ abstract class Twig_Function implements Twig_FunctionInterface return array(); } + + public function getCallable() + { + return $this->options['callable']; + } } diff --git a/inc/lib/Twig/Function/Function.php b/inc/lib/Twig/Function/Function.php index 3237d8c5..d1e1b96a 100644 --- a/inc/lib/Twig/Function/Function.php +++ b/inc/lib/Twig/Function/Function.php @@ -13,8 +13,10 @@ /** * Represents a function template function. * - * @package twig - * @author Arnaud Le Blanc + * Use Twig_SimpleFunction instead. + * + * @author Arnaud Le Blanc + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Function_Function extends Twig_Function { @@ -22,6 +24,8 @@ class Twig_Function_Function extends Twig_Function public function __construct($function, array $options = array()) { + $options['callable'] = $function; + parent::__construct($options); $this->function = $function; diff --git a/inc/lib/Twig/Function/Method.php b/inc/lib/Twig/Function/Method.php index 7328566e..67039a95 100644 --- a/inc/lib/Twig/Function/Method.php +++ b/inc/lib/Twig/Function/Method.php @@ -13,15 +13,20 @@ /** * Represents a method template function. * - * @package twig - * @author Arnaud Le Blanc + * Use Twig_SimpleFunction instead. + * + * @author Arnaud Le Blanc + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_Function_Method extends Twig_Function { - protected $extension, $method; + protected $extension; + protected $method; public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + parent::__construct($options); $this->extension = $extension; diff --git a/inc/lib/Twig/Function/Node.php b/inc/lib/Twig/Function/Node.php new file mode 100644 index 00000000..06a0d0db --- /dev/null +++ b/inc/lib/Twig/Function/Node.php @@ -0,0 +1,39 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +class Twig_Function_Node extends Twig_Function +{ + protected $class; + + public function __construct($class, array $options = array()) + { + parent::__construct($options); + + $this->class = $class; + } + + public function getClass() + { + return $this->class; + } + + public function compile() + { + } +} diff --git a/inc/lib/Twig/FunctionCallableInterface.php b/inc/lib/Twig/FunctionCallableInterface.php new file mode 100644 index 00000000..0aab4f5e --- /dev/null +++ b/inc/lib/Twig/FunctionCallableInterface.php @@ -0,0 +1,23 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_FunctionCallableInterface +{ + public function getCallable(); +} diff --git a/inc/lib/Twig/FunctionInterface.php b/inc/lib/Twig/FunctionInterface.php index ccc9fd93..67f4f89c 100644 --- a/inc/lib/Twig/FunctionInterface.php +++ b/inc/lib/Twig/FunctionInterface.php @@ -13,8 +13,10 @@ /** * Represents a template function. * - * @package twig - * @author Arnaud Le Blanc + * Use Twig_SimpleFunction instead. + * + * @author Arnaud Le Blanc + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_FunctionInterface { @@ -23,11 +25,15 @@ interface Twig_FunctionInterface * * @return string The PHP code for the function */ - function compile(); + public function compile(); - function needsEnvironment(); + public function needsEnvironment(); - function needsContext(); + public function needsContext(); - function getSafe(Twig_Node $filterArgs); + public function getSafe(Twig_Node $filterArgs); + + public function setArguments($arguments); + + public function getArguments(); } diff --git a/inc/lib/Twig/Lexer.php b/inc/lib/Twig/Lexer.php index 868a814e..000b038e 100644 --- a/inc/lib/Twig/Lexer.php +++ b/inc/lib/Twig/Lexer.php @@ -13,8 +13,7 @@ /** * Lexes a template string. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Lexer implements Twig_LexerInterface { @@ -24,21 +23,28 @@ class Twig_Lexer implements Twig_LexerInterface protected $lineno; protected $end; protected $state; + protected $states; protected $brackets; - protected $env; protected $filename; protected $options; - protected $operatorRegex; + protected $regexes; + protected $position; + protected $positions; + protected $currentVarBlockLine; - const STATE_DATA = 0; - const STATE_BLOCK = 1; - const STATE_VAR = 2; + const STATE_DATA = 0; + const STATE_BLOCK = 1; + const STATE_VAR = 2; + const STATE_STRING = 3; + const STATE_INTERPOLATION = 4; - const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A'; - const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A'; - const REGEX_STRING = '/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As'; - const PUNCTUATION = '()[]{}?:.,|'; + const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A'; + const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A'; + const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As'; + const REGEX_DQ_STRING_DELIM = '/"/A'; + const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As'; + const PUNCTUATION = '()[]{}?:.,|'; public function __construct(Twig_Environment $env, array $options = array()) { @@ -49,14 +55,28 @@ class Twig_Lexer implements Twig_LexerInterface 'tag_block' => array('{%', '%}'), 'tag_variable' => array('{{', '}}'), 'whitespace_trim' => '-', + 'interpolation' => array('#{', '}'), ), $options); + + $this->regexes = array( + 'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A', + 'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A', + 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s', + 'operator' => $this->getOperatorRegex(), + 'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s', + 'lex_block_raw' => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As', + 'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', + 'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s', + 'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A', + 'interpolation_end' => '/\s*'.preg_quote($this->options['interpolation'][1], '/').'/A', + ); } /** * Tokenizes a source code. * - * @param string $code The source code - * @param string $filename A unique identifier for the source code + * @param string $code The source code + * @param string $filename A unique identifier for the source code * * @return Twig_TokenStream A token stream instance */ @@ -74,7 +94,13 @@ class Twig_Lexer implements Twig_LexerInterface $this->end = strlen($this->code); $this->tokens = array(); $this->state = self::STATE_DATA; + $this->states = array(); $this->brackets = array(); + $this->position = -1; + + // find all token starts in one go + preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, PREG_OFFSET_CAPTURE); + $this->positions = $matches; while ($this->cursor < $this->end) { // dispatch to the lexing functions depending @@ -91,6 +117,14 @@ class Twig_Lexer implements Twig_LexerInterface case self::STATE_VAR: $this->lexVar(); break; + + case self::STATE_STRING: + $this->lexString(); + break; + + case self::STATE_INTERPOLATION: + $this->lexInterpolation(); + break; } } @@ -110,77 +144,66 @@ class Twig_Lexer implements Twig_LexerInterface protected function lexData() { - $pos = $this->end; - $append = ''; - - // Find the first token after the cursor - foreach (array('tag_comment', 'tag_variable', 'tag_block') as $type) { - $tmpPos = strpos($this->code, $this->options[$type][0], $this->cursor); - if (false !== $tmpPos && $tmpPos < $pos) { - $trimBlock = false; - $append = ''; - $pos = $tmpPos; - $token = $this->options[$type][0]; - if (strpos($this->code, $this->options['whitespace_trim'], $pos) === ($pos + strlen($token))) { - $trimBlock = true; - $append = $this->options['whitespace_trim']; - } - } - } - // if no matches are left we return the rest of the template as simple text token - if ($pos === $this->end) { + if ($this->position == count($this->positions[0]) - 1) { $this->pushToken(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor)); $this->cursor = $this->end; + return; } + // Find the first token after the current cursor + $position = $this->positions[0][++$this->position]; + while ($position[1] < $this->cursor) { + if ($this->position == count($this->positions[0]) - 1) { + return; + } + $position = $this->positions[0][++$this->position]; + } + // push the template text first - $text = $textContent = substr($this->code, $this->cursor, $pos - $this->cursor); - if (true === $trimBlock) { + $text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor); + if (isset($this->positions[2][$this->position][0])) { $text = rtrim($text); } $this->pushToken(Twig_Token::TEXT_TYPE, $text); - $this->moveCursor($textContent.$token.$append); + $this->moveCursor($textContent.$position[0]); - switch ($token) { + switch ($this->positions[1][$this->position][0]) { case $this->options['tag_comment'][0]: $this->lexComment(); break; case $this->options['tag_block'][0]: // raw data? - if (preg_match('/\s*raw\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor)) { + if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) { $this->moveCursor($match[0]); - $this->lexRawData(); - $this->state = self::STATE_DATA; + $this->lexRawData($match[1]); // {% line \d+ %} - } else if (preg_match('/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor)) { + } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) { $this->moveCursor($match[0]); $this->lineno = (int) $match[1]; - $this->state = self::STATE_DATA; } else { $this->pushToken(Twig_Token::BLOCK_START_TYPE); - $this->state = self::STATE_BLOCK; + $this->pushState(self::STATE_BLOCK); + $this->currentVarBlockLine = $this->lineno; } break; case $this->options['tag_variable'][0]: $this->pushToken(Twig_Token::VAR_START_TYPE); - $this->state = self::STATE_VAR; + $this->pushState(self::STATE_VAR); + $this->currentVarBlockLine = $this->lineno; break; } } protected function lexBlock() { - $trimTag = preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/'); - $endTag = preg_quote($this->options['tag_block'][1], '/'); - - if (empty($this->brackets) && preg_match('/\s*(?:'.$trimTag.'\s*|\s*'.$endTag.')\n?/A', $this->code, $match, null, $this->cursor)) { + if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, null, $this->cursor)) { $this->pushToken(Twig_Token::BLOCK_END_TYPE); $this->moveCursor($match[0]); - $this->state = self::STATE_DATA; + $this->popState(); } else { $this->lexExpression(); } @@ -188,13 +211,10 @@ class Twig_Lexer implements Twig_LexerInterface protected function lexVar() { - $trimTag = preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/'); - $endTag = preg_quote($this->options['tag_variable'][1], '/'); - - if (empty($this->brackets) && preg_match('/\s*'.$trimTag.'\s*|\s*'.$endTag.'/A', $this->code, $match, null, $this->cursor)) { + if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, null, $this->cursor)) { $this->pushToken(Twig_Token::VAR_END_TYPE); $this->moveCursor($match[0]); - $this->state = self::STATE_DATA; + $this->popState(); } else { $this->lexExpression(); } @@ -207,12 +227,12 @@ class Twig_Lexer implements Twig_LexerInterface $this->moveCursor($match[0]); if ($this->cursor >= $this->end) { - throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable')); + throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename); } } // operators - if (preg_match($this->getOperatorRegex(), $this->code, $match, null, $this->cursor)) { + if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) { $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]); $this->moveCursor($match[0]); } @@ -223,7 +243,11 @@ class Twig_Lexer implements Twig_LexerInterface } // numbers elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) { - $this->pushToken(Twig_Token::NUMBER_TYPE, ctype_digit($match[0]) ? (int) $match[0] : (float) $match[0]); + $number = (float) $match[0]; // floats + if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) { + $number = (int) $match[0]; // integers lower than the maximum + } + $this->pushToken(Twig_Token::NUMBER_TYPE, $number); $this->moveCursor($match[0]); } // punctuation @@ -252,35 +276,80 @@ class Twig_Lexer implements Twig_LexerInterface $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1))); $this->moveCursor($match[0]); } + // opening double quoted string + elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { + $this->brackets[] = array('"', $this->lineno); + $this->pushState(self::STATE_STRING); + $this->moveCursor($match[0]); + } // unlexable else { throw new Twig_Error_Syntax(sprintf('Unexpected character "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename); } } - protected function lexRawData() + protected function lexRawData($tag) { - if (!preg_match('/'.preg_quote($this->options['tag_block'][0], '/').'\s*endraw\s*'.preg_quote($this->options['tag_block'][1], '/').'/s', $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { - throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "block"')); + if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { + throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename); } + $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor); - $this->pushToken(Twig_Token::TEXT_TYPE, $text); $this->moveCursor($text.$match[0][0]); + + if (false !== strpos($match[1][0], $this->options['whitespace_trim'])) { + $text = rtrim($text); + } + + $this->pushToken(Twig_Token::TEXT_TYPE, $text); } protected function lexComment() { - $commentEndRegex = '/(?:'.preg_quote($this->options['whitespace_trim'], '/') - .preg_quote($this->options['tag_comment'][1], '/').'\s*|' - .preg_quote($this->options['tag_comment'][1], '/').')\n?/s'; - - if (!preg_match($commentEndRegex, $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { + if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { throw new Twig_Error_Syntax('Unclosed comment', $this->lineno, $this->filename); } $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]); } + protected function lexString() + { + if (preg_match($this->regexes['interpolation_start'], $this->code, $match, null, $this->cursor)) { + $this->brackets[] = array($this->options['interpolation'][0], $this->lineno); + $this->pushToken(Twig_Token::INTERPOLATION_START_TYPE); + $this->moveCursor($match[0]); + $this->pushState(self::STATE_INTERPOLATION); + + } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) { + $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0])); + $this->moveCursor($match[0]); + + } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { + + list($expect, $lineno) = array_pop($this->brackets); + if ($this->code[$this->cursor] != '"') { + throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename); + } + + $this->popState(); + ++$this->cursor; + } + } + + protected function lexInterpolation() + { + $bracket = end($this->brackets); + if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, null, $this->cursor)) { + array_pop($this->brackets); + $this->pushToken(Twig_Token::INTERPOLATION_END_TYPE); + $this->moveCursor($match[0]); + $this->popState(); + } else { + $this->lexExpression(); + } + } + protected function pushToken($type, $value = '') { // do not push empty text tokens @@ -299,10 +368,6 @@ class Twig_Lexer implements Twig_LexerInterface protected function getOperatorRegex() { - if (null !== $this->operatorRegex) { - return $this->operatorRegex; - } - $operators = array_merge( array('='), array_keys($this->env->getUnaryOperators()), @@ -317,12 +382,27 @@ class Twig_Lexer implements Twig_LexerInterface // an operator that ends with a character must be followed by // a whitespace or a parenthesis if (ctype_alpha($operator[$length - 1])) { - $regex[] = preg_quote($operator, '/').'(?=[ ()])'; + $regex[] = preg_quote($operator, '/').'(?=[\s()])'; } else { $regex[] = preg_quote($operator, '/'); } } - return $this->operatorRegex = '/'.implode('|', $regex).'/A'; + return '/'.implode('|', $regex).'/A'; + } + + protected function pushState($state) + { + $this->states[] = $this->state; + $this->state = $state; + } + + protected function popState() + { + if (0 === count($this->states)) { + throw new Exception('Cannot pop state without a previous state'); + } + + $this->state = array_pop($this->states); } } diff --git a/inc/lib/Twig/LexerInterface.php b/inc/lib/Twig/LexerInterface.php index 02233849..4b83f81b 100644 --- a/inc/lib/Twig/LexerInterface.php +++ b/inc/lib/Twig/LexerInterface.php @@ -12,18 +12,18 @@ /** * Interface implemented by lexer classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_LexerInterface { /** * Tokenizes a source code. * - * @param string $code The source code - * @param string $filename A unique identifier for the source code + * @param string $code The source code + * @param string $filename A unique identifier for the source code * * @return Twig_TokenStream A token stream instance */ - function tokenize($code, $filename = null); + public function tokenize($code, $filename = null); } diff --git a/inc/lib/Twig/Loader/Array.php b/inc/lib/Twig/Loader/Array.php index e8dc1605..89087aea 100644 --- a/inc/lib/Twig/Loader/Array.php +++ b/inc/lib/Twig/Loader/Array.php @@ -17,10 +17,9 @@ * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Loader_Array implements Twig_LoaderInterface +class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { protected $templates; @@ -47,18 +46,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface */ public function setTemplate($name, $template) { - $this->templates[$name] = $template; + $this->templates[(string) $name] = $template; } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { + $name = (string) $name; if (!isset($this->templates[$name])) { throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); } @@ -67,14 +63,19 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + return isset($this->templates[(string) $name]); + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { + $name = (string) $name; if (!isset($this->templates[$name])) { throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); } @@ -83,13 +84,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { + $name = (string) $name; + if (!isset($this->templates[$name])) { + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + } + return true; } } diff --git a/inc/lib/Twig/Loader/Chain.php b/inc/lib/Twig/Loader/Chain.php index 48dd8b84..1f1cf065 100644 --- a/inc/lib/Twig/Loader/Chain.php +++ b/inc/lib/Twig/Loader/Chain.php @@ -12,11 +12,11 @@ /** * Loads templates from other loaders. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Loader_Chain implements Twig_LoaderInterface +class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { + private $hasSourceCache = array(); protected $loaders; /** @@ -40,61 +40,100 @@ class Twig_Loader_Chain implements Twig_LoaderInterface public function addLoader(Twig_LoaderInterface $loader) { $this->loaders[] = $loader; + $this->hasSourceCache = array(); } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getSource($name); } catch (Twig_Error_Loader $e) { + $exceptions[] = $e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions))); } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + $name = (string) $name; + + if (isset($this->hasSourceCache[$name])) { + return $this->hasSourceCache[$name]; + } + + foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface) { + if ($loader->exists($name)) { + return $this->hasSourceCache[$name] = true; + } + + continue; + } + + try { + $loader->getSource($name); + + return $this->hasSourceCache[$name] = true; + } catch (Twig_Error_Loader $e) { + } + } + + return $this->hasSourceCache[$name] = false; + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getCacheKey($name); } catch (Twig_Error_Loader $e) { + $exceptions[] = get_class($loader).': '.$e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->isFresh($name, $time); } catch (Twig_Error_Loader $e) { + $exceptions[] = get_class($loader).': '.$e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); } } diff --git a/inc/lib/Twig/Loader/Filesystem.php b/inc/lib/Twig/Loader/Filesystem.php index be348aa3..f9211cbd 100644 --- a/inc/lib/Twig/Loader/Filesystem.php +++ b/inc/lib/Twig/Loader/Filesystem.php @@ -12,10 +12,9 @@ /** * Loads template from the filesystem. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Loader_Filesystem implements Twig_LoaderInterface +class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { protected $paths; protected $cache; @@ -25,44 +24,64 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface * * @param string|array $paths A path or an array of paths where to look for templates */ - public function __construct($paths) + public function __construct($paths = array()) { - $this->setPaths($paths); + if ($paths) { + $this->setPaths($paths); + } } /** * Returns the paths to the templates. * + * @param string $namespace A path namespace + * * @return array The array of paths where to look for templates */ - public function getPaths() + public function getPaths($namespace = '__main__') { - return $this->paths; + return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array(); + } + + /** + * Returns the path namespaces. + * + * The "__main__" namespace is always defined. + * + * @return array The array of defined namespaces + */ + public function getNamespaces() + { + return array_keys($this->paths); } /** * Sets the paths where templates are stored. * - * @param string|array $paths A path or an array of paths where to look for templates + * @param string|array $paths A path or an array of paths where to look for templates + * @param string $namespace A path namespace */ - public function setPaths($paths) + public function setPaths($paths, $namespace = '__main__') { if (!is_array($paths)) { $paths = array($paths); } - $this->paths = array(); + $this->paths[$namespace] = array(); foreach ($paths as $path) { - $this->addPath($path); + $this->addPath($path, $namespace); } } /** * Adds a path where templates are stored. * - * @param string $path A path where to look for templates + * @param string $path A path where to look for templates + * @param string $namespace A path name + * + * @throws Twig_Error_Loader */ - public function addPath($path) + public function addPath($path, $namespace = '__main__') { // invalidate the cache $this->cache = array(); @@ -71,15 +90,37 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); } - $this->paths[] = $path; + $this->paths[$namespace][] = rtrim($path, '/\\'); } /** - * Gets the source code of a template, given its name. + * Prepends a path where templates are stored. * - * @param string $name The name of the template to load + * @param string $path A path where to look for templates + * @param string $namespace A path name * - * @return string The template source code + * @throws Twig_Error_Loader + */ + public function prependPath($path, $namespace = '__main__') + { + // invalidate the cache + $this->cache = array(); + + if (!is_dir($path)) { + throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); + } + + $path = rtrim($path, '/\\'); + + if (!isset($this->paths[$namespace])) { + $this->paths[$namespace][] = $path; + } else { + array_unshift($this->paths[$namespace], $path); + } + } + + /** + * {@inheritdoc} */ public function getSource($name) { @@ -87,11 +128,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} */ public function getCacheKey($name) { @@ -99,18 +136,36 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} + */ + public function exists($name) + { + $name = (string) $name; + if (isset($this->cache[$name])) { + return true; + } + + try { + $this->findTemplate($name); + + return true; + } catch (Twig_Error_Loader $exception) { + return false; + } + } + + /** + * {@inheritdoc} */ public function isFresh($name, $time) { - return filemtime($this->findTemplate($name)) < $time; + return filemtime($this->findTemplate($name)) <= $time; } protected function findTemplate($name) { + $name = (string) $name; + // normalize name $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); @@ -120,13 +175,28 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface $this->validateName($name); - foreach ($this->paths as $path) { + $namespace = '__main__'; + if (isset($name[0]) && '@' == $name[0]) { + if (false === $pos = strpos($name, '/')) { + throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); + } + + $namespace = substr($name, 1, $pos - 1); + + $name = substr($name, $pos + 1); + } + + if (!isset($this->paths[$namespace])) { + throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); + } + + foreach ($this->paths[$namespace] as $path) { if (is_file($path.'/'.$name)) { return $this->cache[$name] = $path.'/'.$name; } } - throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths))); + throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); } protected function validateName($name) @@ -135,6 +205,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); } + $name = ltrim($name, '/'); $parts = explode('/', $name); $level = 0; foreach ($parts as $part) { diff --git a/inc/lib/Twig/Loader/String.php b/inc/lib/Twig/Loader/String.php index 26eb0096..8ad9856c 100644 --- a/inc/lib/Twig/Loader/String.php +++ b/inc/lib/Twig/Loader/String.php @@ -12,22 +12,21 @@ /** * Loads a template from a string. * + * This loader should only be used for unit testing as it has many limitations + * (for instance, the include or extends tag does not make any sense for a string + * loader). + * * When using this loader with a cache mechanism, you should know that a new cache * key is generated each time a template content "changes" (the cache key being the * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Loader_String implements Twig_LoaderInterface +class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { @@ -35,11 +34,15 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + return true; + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { @@ -47,10 +50,7 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { diff --git a/inc/lib/Twig/LoaderInterface.php b/inc/lib/Twig/LoaderInterface.php index f0bd3a5b..927786d1 100644 --- a/inc/lib/Twig/LoaderInterface.php +++ b/inc/lib/Twig/LoaderInterface.php @@ -12,34 +12,41 @@ /** * Interface all loaders must implement. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_LoaderInterface { /** * Gets the source code of a template, given its name. * - * @param string $name The name of the template to load + * @param string $name The name of the template to load * * @return string The template source code + * + * @throws Twig_Error_Loader When $name is not found */ - function getSource($name); + public function getSource($name); /** * Gets the cache key to use for the cache for a given template name. * - * @param string $name The name of the template to load + * @param string $name The name of the template to load * * @return string The cache key + * + * @throws Twig_Error_Loader When $name is not found */ - function getCacheKey($name); + public function getCacheKey($name); /** * Returns true if the template is still fresh. * * @param string $name The template name * @param timestamp $time The last modification time of the cached template + * + * @return Boolean true if the template is fresh, false otherwise + * + * @throws Twig_Error_Loader When $name is not found */ - function isFresh($name, $time); + public function isFresh($name, $time); } diff --git a/inc/lib/Twig/Markup.php b/inc/lib/Twig/Markup.php index c1a1469c..69871fcb 100644 --- a/inc/lib/Twig/Markup.php +++ b/inc/lib/Twig/Markup.php @@ -12,20 +12,26 @@ /** * Marks a content as safe. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Markup +class Twig_Markup implements Countable { protected $content; + protected $charset; - public function __construct($content) + public function __construct($content, $charset) { $this->content = (string) $content; + $this->charset = $charset; } public function __toString() { return $this->content; } + + public function count() + { + return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content); + } } diff --git a/inc/lib/Twig/Node.php b/inc/lib/Twig/Node.php index 22e65d45..931b4635 100644 --- a/inc/lib/Twig/Node.php +++ b/inc/lib/Twig/Node.php @@ -13,10 +13,9 @@ /** * Represents a node in the AST. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ -class Twig_Node implements Twig_NodeInterface, Countable, IteratorAggregate +class Twig_Node implements Twig_NodeInterface { protected $nodes; protected $attributes; @@ -134,12 +133,12 @@ class Twig_Node implements Twig_NodeInterface, Countable, IteratorAggregate * * @param string The attribute name * - * @return mixed The attribute value + * @return mixed The attribute value */ public function getAttribute($name) { if (!array_key_exists($name, $this->attributes)) { - throw new Twig_Error_Runtime(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this))); + throw new LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this))); } return $this->attributes[$name]; @@ -188,7 +187,7 @@ class Twig_Node implements Twig_NodeInterface, Countable, IteratorAggregate public function getNode($name) { if (!array_key_exists($name, $this->nodes)) { - throw new Twig_Error_Runtime(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this))); + throw new LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this))); } return $this->nodes[$name]; diff --git a/inc/lib/Twig/Node/AutoEscape.php b/inc/lib/Twig/Node/AutoEscape.php index a0c2ee6d..8f190e0b 100644 --- a/inc/lib/Twig/Node/AutoEscape.php +++ b/inc/lib/Twig/Node/AutoEscape.php @@ -18,8 +18,7 @@ * * If autoescaping is disabled, then the value is false. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_AutoEscape extends Twig_Node { diff --git a/inc/lib/Twig/Node/Block.php b/inc/lib/Twig/Node/Block.php index 5548ad06..50eb67ed 100644 --- a/inc/lib/Twig/Node/Block.php +++ b/inc/lib/Twig/Node/Block.php @@ -13,8 +13,7 @@ /** * Represents a block node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Block extends Twig_Node { diff --git a/inc/lib/Twig/Node/BlockReference.php b/inc/lib/Twig/Node/BlockReference.php index 53f6287c..013e369e 100644 --- a/inc/lib/Twig/Node/BlockReference.php +++ b/inc/lib/Twig/Node/BlockReference.php @@ -13,8 +13,7 @@ /** * Represents a block call node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface { diff --git a/inc/lib/Twig/Node/Body.php b/inc/lib/Twig/Node/Body.php new file mode 100644 index 00000000..3ffb1342 --- /dev/null +++ b/inc/lib/Twig/Node/Body.php @@ -0,0 +1,19 @@ + + */ +class Twig_Node_Body extends Twig_Node +{ +} diff --git a/inc/lib/Twig/Node/Do.php b/inc/lib/Twig/Node/Do.php new file mode 100644 index 00000000..c528066b --- /dev/null +++ b/inc/lib/Twig/Node/Do.php @@ -0,0 +1,38 @@ + + */ +class Twig_Node_Do extends Twig_Node +{ + public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null) + { + parent::__construct(array('expr' => $expr), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('') + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Embed.php b/inc/lib/Twig/Node/Embed.php new file mode 100644 index 00000000..4c9456dc --- /dev/null +++ b/inc/lib/Twig/Node/Embed.php @@ -0,0 +1,38 @@ + + */ +class Twig_Node_Embed extends Twig_Node_Include +{ + // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) + public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) + { + parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); + + $this->setAttribute('filename', $filename); + $this->setAttribute('index', $index); + } + + protected function addGetTemplate(Twig_Compiler $compiler) + { + $compiler + ->write("\$this->env->loadTemplate(") + ->string($this->getAttribute('filename')) + ->raw(', ') + ->string($this->getAttribute('index')) + ->raw(")") + ; + } +} diff --git a/inc/lib/Twig/Node/Expression.php b/inc/lib/Twig/Node/Expression.php index 13b170e5..a7382e7d 100644 --- a/inc/lib/Twig/Node/Expression.php +++ b/inc/lib/Twig/Node/Expression.php @@ -13,8 +13,7 @@ /** * Abstract class for all nodes that represents an expression. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ abstract class Twig_Node_Expression extends Twig_Node { diff --git a/inc/lib/Twig/Node/Expression/Array.php b/inc/lib/Twig/Node/Expression/Array.php index 2d860823..1da785fe 100644 --- a/inc/lib/Twig/Node/Expression/Array.php +++ b/inc/lib/Twig/Node/Expression/Array.php @@ -10,9 +10,54 @@ */ class Twig_Node_Expression_Array extends Twig_Node_Expression { + protected $index; + public function __construct(array $elements, $lineno) { parent::__construct($elements, array(), $lineno); + + $this->index = -1; + foreach ($this->getKeyValuePairs() as $pair) { + if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) { + $this->index = $pair['key']->getAttribute('value'); + } + } + } + + public function getKeyValuePairs() + { + $pairs = array(); + + foreach (array_chunk($this->nodes, 2) as $pair) { + $pairs[] = array( + 'key' => $pair[0], + 'value' => $pair[1], + ); + } + + return $pairs; + } + + public function hasElement(Twig_Node_Expression $key) + { + foreach ($this->getKeyValuePairs() as $pair) { + // we compare the string representation of the keys + // to avoid comparing the line numbers which are not relevant here. + if ((string) $key == (string) $pair['key']) { + return true; + } + } + + return false; + } + + public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null) + { + if (null === $key) { + $key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine()); + } + + array_push($this->nodes, $key, $value); } /** @@ -24,16 +69,16 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression { $compiler->raw('array('); $first = true; - foreach ($this->nodes as $name => $node) { + foreach ($this->getKeyValuePairs() as $pair) { if (!$first) { $compiler->raw(', '); } $first = false; $compiler - ->repr($name) + ->subcompile($pair['key']) ->raw(' => ') - ->subcompile($node) + ->subcompile($pair['value']) ; } $compiler->raw(')'); diff --git a/inc/lib/Twig/Node/Expression/AssignName.php b/inc/lib/Twig/Node/Expression/AssignName.php index 67f12509..2ddea78c 100644 --- a/inc/lib/Twig/Node/Expression/AssignName.php +++ b/inc/lib/Twig/Node/Expression/AssignName.php @@ -19,6 +19,10 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name */ public function compile(Twig_Compiler $compiler) { - $compiler->raw(sprintf('$context[\'%s\']', $this->getAttribute('name'))); + $compiler + ->raw('$context[') + ->string($this->getAttribute('name')) + ->raw(']') + ; } } diff --git a/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php index e86b1ea0..7fbd0556 100644 --- a/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php +++ b/inc/lib/Twig/Node/Expression/Binary/FloorDiv.php @@ -17,9 +17,9 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary */ public function compile(Twig_Compiler $compiler) { - $compiler->raw('floor('); + $compiler->raw('intval(floor('); parent::compile($compiler); - $compiler->raw(')'); + $compiler->raw('))'); } public function operator(Twig_Compiler $compiler) diff --git a/inc/lib/Twig/Node/Expression/BlockReference.php b/inc/lib/Twig/Node/Expression/BlockReference.php index 174d9097..647196eb 100644 --- a/inc/lib/Twig/Node/Expression/BlockReference.php +++ b/inc/lib/Twig/Node/Expression/BlockReference.php @@ -13,8 +13,7 @@ /** * Represents a block call node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression { diff --git a/inc/lib/Twig/Node/Expression/Call.php b/inc/lib/Twig/Node/Expression/Call.php new file mode 100644 index 00000000..87b62deb --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Call.php @@ -0,0 +1,178 @@ +getAttribute('callable'); + + $closingParenthesis = false; + if ($callable) { + if (is_string($callable)) { + $compiler->raw($callable); + } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) { + $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1])); + } else { + $type = ucfirst($this->getAttribute('type')); + $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name'))); + $closingParenthesis = true; + } + } else { + $compiler->raw($this->getAttribute('thing')->compile()); + } + + $this->compileArguments($compiler); + + if ($closingParenthesis) { + $compiler->raw(')'); + } + } + + protected function compileArguments(Twig_Compiler $compiler) + { + $compiler->raw('('); + + $first = true; + + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + $compiler->raw('$this->env'); + $first = false; + } + + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->raw('$context'); + $first = false; + } + + if ($this->hasAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->string($argument); + $first = false; + } + } + + if ($this->hasNode('node')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($this->getNode('node')); + $first = false; + } + + if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) { + $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null; + + $arguments = $this->getArguments($callable, $this->getNode('arguments')); + + foreach ($arguments as $node) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($node); + $first = false; + } + } + + $compiler->raw(')'); + } + + protected function getArguments($callable, $arguments) + { + $parameters = array(); + $named = false; + foreach ($arguments as $name => $node) { + if (!is_int($name)) { + $named = true; + $name = $this->normalizeName($name); + } elseif ($named) { + throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); + } + + $parameters[$name] = $node; + } + + if (!$named) { + return $parameters; + } + + if (!$callable) { + throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name'))); + } + + // manage named arguments + if (is_array($callable)) { + $r = new ReflectionMethod($callable[0], $callable[1]); + } elseif (is_object($callable) && !$callable instanceof Closure) { + $r = new ReflectionObject($callable); + $r = $r->getMethod('__invoke'); + } else { + $r = new ReflectionFunction($callable); + } + + $definition = $r->getParameters(); + if ($this->hasNode('node')) { + array_shift($definition); + } + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + array_shift($definition); + } + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + array_shift($definition); + } + if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + array_shift($definition); + } + } + + $arguments = array(); + $pos = 0; + foreach ($definition as $param) { + $name = $this->normalizeName($param->name); + + if (array_key_exists($name, $parameters)) { + if (array_key_exists($pos, $parameters)) { + throw new Twig_Error_Syntax(sprintf('Arguments "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + + $arguments[] = $parameters[$name]; + unset($parameters[$name]); + } elseif (array_key_exists($pos, $parameters)) { + $arguments[] = $parameters[$pos]; + unset($parameters[$pos]); + ++$pos; + } elseif ($param->isDefaultValueAvailable()) { + $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1); + } elseif ($param->isOptional()) { + break; + } else { + throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + } + + foreach (array_keys($parameters) as $name) { + throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name'))); + } + + return $arguments; + } + + protected function normalizeName($name) + { + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name)); + } +} diff --git a/inc/lib/Twig/Node/Expression/ExtensionReference.php b/inc/lib/Twig/Node/Expression/ExtensionReference.php index cb4efad0..00ac6701 100644 --- a/inc/lib/Twig/Node/Expression/ExtensionReference.php +++ b/inc/lib/Twig/Node/Expression/ExtensionReference.php @@ -12,8 +12,7 @@ /** * Represents an extension call node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression { diff --git a/inc/lib/Twig/Node/Expression/Filter.php b/inc/lib/Twig/Node/Expression/Filter.php index 101e6df0..207b062a 100644 --- a/inc/lib/Twig/Node/Expression/Filter.php +++ b/inc/lib/Twig/Node/Expression/Filter.php @@ -9,7 +9,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Filter extends Twig_Node_Expression +class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call { public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) { @@ -19,54 +19,18 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression public function compile(Twig_Compiler $compiler) { $name = $this->getNode('filter')->getAttribute('value'); - if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { - throw new Twig_Error_Syntax(sprintf('The filter "%s" does not exist', $name), $this->getLine()); + $filter = $compiler->getEnvironment()->getFilter($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'filter'); + $this->setAttribute('thing', $filter); + $this->setAttribute('needs_environment', $filter->needsEnvironment()); + $this->setAttribute('needs_context', $filter->needsContext()); + $this->setAttribute('arguments', $filter->getArguments()); + if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) { + $this->setAttribute('callable', $filter->getCallable()); } - $node = $this->getNode('node'); - - // The default filter is intercepted when the filtered value - // is a name (like obj) or an attribute (like obj.attr) - // In such a case, it's compiled to {{ obj is defined ? obj|default('bar') : 'bar' }} - if ('default' === $name && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { - $compiler - ->raw('((') - ->subcompile(new Twig_Node_Expression_Test($node, 'defined', new Twig_Node(), $this->getLine())) - ->raw(') ? (') - ; - - $this->compileFilter($compiler, $filter); - - $compiler->raw(') : ('); - - if ($this->getNode('arguments')->hasNode(0)) { - $compiler->subcompile($this->getNode('arguments')->getNode(0)); - } else { - $compiler->string(''); - } - - $compiler->raw('))'); - } else { - $this->compileFilter($compiler, $filter); - } - } - - protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) - { - $compiler - ->raw($filter->compile().'(') - ->raw($filter->needsEnvironment() ? '$this->env, ' : '') - ->raw($filter->needsContext() ? '$context, ' : '') - ->subcompile($this->getNode('node')) - ; - - foreach ($this->getNode('arguments') as $node) { - $compiler - ->raw(', ') - ->subcompile($node) - ; - } - - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/inc/lib/Twig/Node/Expression/Filter/Default.php b/inc/lib/Twig/Node/Expression/Filter/Default.php new file mode 100644 index 00000000..1827c888 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Filter/Default.php @@ -0,0 +1,43 @@ + + * {{ var.foo|default('foo item on var is not defined') }} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter +{ + public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) + { + $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine()); + + if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { + $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine()); + $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine()); + + $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine()); + } else { + $node = $default; + } + + parent::__construct($node, $filterName, $arguments, $lineno, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->subcompile($this->getNode('node')); + } +} diff --git a/inc/lib/Twig/Node/Expression/Function.php b/inc/lib/Twig/Node/Expression/Function.php index 3f457199..3e1f6b55 100644 --- a/inc/lib/Twig/Node/Expression/Function.php +++ b/inc/lib/Twig/Node/Expression/Function.php @@ -8,7 +8,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Function extends Twig_Node_Expression +class Twig_Node_Expression_Function extends Twig_Node_Expression_Call { public function __construct($name, Twig_NodeInterface $arguments, $lineno) { @@ -17,33 +17,19 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression public function compile(Twig_Compiler $compiler) { - $function = $compiler->getEnvironment()->getFunction($this->getAttribute('name')); - if (false === $function) { - throw new Twig_Error_Syntax(sprintf('The function "%s" does not exist', $this->getAttribute('name')), $this->getLine()); + $name = $this->getAttribute('name'); + $function = $compiler->getEnvironment()->getFunction($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'function'); + $this->setAttribute('thing', $function); + $this->setAttribute('needs_environment', $function->needsEnvironment()); + $this->setAttribute('needs_context', $function->needsContext()); + $this->setAttribute('arguments', $function->getArguments()); + if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) { + $this->setAttribute('callable', $function->getCallable()); } - $compiler - ->raw($function->compile().'(') - ->raw($function->needsEnvironment() ? '$this->env' : '') - ; - - if ($function->needsContext()) { - $compiler->raw($function->needsEnvironment() ? ', $context' : '$context'); - } - - $first = true; - foreach ($this->getNode('arguments') as $node) { - if (!$first) { - $compiler->raw(', '); - } else { - if ($function->needsEnvironment() || $function->needsContext()) { - $compiler->raw(', '); - } - $first = false; - } - $compiler->subcompile($node); - } - - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/inc/lib/Twig/Node/Expression/GetAttr.php b/inc/lib/Twig/Node/Expression/GetAttr.php index eb9e6050..81a9b137 100644 --- a/inc/lib/Twig/Node/Expression/GetAttr.php +++ b/inc/lib/Twig/Node/Expression/GetAttr.php @@ -11,43 +11,43 @@ */ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression { - public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_NodeInterface $arguments, $type, $lineno) + public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno) { - parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type), $lineno); + parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno); } public function compile(Twig_Compiler $compiler) { - $compiler->raw('$this->getAttribute('); - - if ($this->hasAttribute('is_defined_test') && $compiler->getEnvironment()->isStrictVariables()) { - $compiler->subcompile(new Twig_Node_Expression_Filter( - $this->getNode('node'), - new Twig_Node_Expression_Constant('default', $this->getLine()), - new Twig_Node(), - $this->getLine() - )); + if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) { + $compiler->raw('twig_template_get_attributes($this, '); } else { - $compiler->subcompile($this->getNode('node')); + $compiler->raw('$this->getAttribute('); } - $compiler - ->raw(', ') - ->subcompile($this->getNode('attribute')) - ->raw(', array(') - ; - - foreach ($this->getNode('arguments') as $node) { - $compiler - ->subcompile($node) - ->raw(', ') - ; + if ($this->getAttribute('ignore_strict_check')) { + $this->getNode('node')->setAttribute('ignore_strict_check', true); } - $compiler - ->raw('), ') - ->repr($this->getAttribute('type')) - ->raw($this->hasAttribute('is_defined_test') ? ', true' : ', false') - ->raw(')'); + $compiler->subcompile($this->getNode('node')); + + $compiler->raw(', ')->subcompile($this->getNode('attribute')); + + if (count($this->getNode('arguments')) || Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { + $compiler->raw(', ')->subcompile($this->getNode('arguments')); + + if (Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { + $compiler->raw(', ')->repr($this->getAttribute('type')); + } + + if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) { + $compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false')); + } + + if ($this->getAttribute('ignore_strict_check')) { + $compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false')); + } + } + + $compiler->raw(')'); } } diff --git a/inc/lib/Twig/Node/Expression/MethodCall.php b/inc/lib/Twig/Node/Expression/MethodCall.php new file mode 100644 index 00000000..620b02bf --- /dev/null +++ b/inc/lib/Twig/Node/Expression/MethodCall.php @@ -0,0 +1,41 @@ + $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno); + + if ($node instanceof Twig_Node_Expression_Name) { + $node->setAttribute('always_defined', true); + } + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->subcompile($this->getNode('node')) + ->raw('->') + ->raw($this->getAttribute('method')) + ->raw('(') + ; + $first = true; + foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + $compiler->subcompile($pair['value']); + } + $compiler->raw(')'); + } +} diff --git a/inc/lib/Twig/Node/Expression/Name.php b/inc/lib/Twig/Node/Expression/Name.php index fceda2b7..3b8fae01 100644 --- a/inc/lib/Twig/Node/Expression/Name.php +++ b/inc/lib/Twig/Node/Expression/Name.php @@ -11,31 +11,78 @@ */ class Twig_Node_Expression_Name extends Twig_Node_Expression { + protected $specialVars = array( + '_self' => '$this', + '_context' => '$context', + '_charset' => '$this->env->getCharset()', + ); + public function __construct($name, $lineno) { - parent::__construct(array(), array('name' => $name), $lineno); + parent::__construct(array(), array('name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false), $lineno); } public function compile(Twig_Compiler $compiler) { - static $specialVars = array( - '_self' => '$this', - '_context' => '$context', - '_charset' => '$this->env->getCharset()', - ); - $name = $this->getAttribute('name'); - if ($this->hasAttribute('is_defined_test')) { - if (isset($specialVars[$name])) { + if ($this->getAttribute('is_defined_test')) { + if ($this->isSpecial()) { $compiler->repr(true); } else { $compiler->raw('array_key_exists(')->repr($name)->raw(', $context)'); } - } elseif (isset($specialVars[$name])) { - $compiler->raw($specialVars[$name]); + } elseif ($this->isSpecial()) { + $compiler->raw($this->specialVars[$name]); + } elseif ($this->getAttribute('always_defined')) { + $compiler + ->raw('$context[') + ->string($name) + ->raw(']') + ; } else { - $compiler->raw(sprintf('$this->getContext($context, \'%s\')', $name)); + // remove the non-PHP 5.4 version when PHP 5.3 support is dropped + // as the non-optimized version is just a workaround for slow ternary operator + // when the context has a lot of variables + if (version_compare(phpversion(), '5.4.0RC1', '>=')) { + // PHP 5.4 ternary operator performance was optimized + $compiler + ->raw('(isset($context[') + ->string($name) + ->raw(']) ? $context[') + ->string($name) + ->raw('] : ') + ; + + if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) { + $compiler->raw('null)'); + } else { + $compiler->raw('$this->getContext($context, ')->string($name)->raw('))'); + } + } else { + $compiler + ->raw('$this->getContext($context, ') + ->string($name) + ; + + if ($this->getAttribute('ignore_strict_check')) { + $compiler->raw(', true'); + } + + $compiler + ->raw(')') + ; + } } } + + public function isSpecial() + { + return isset($this->specialVars[$this->getAttribute('name')]); + } + + public function isSimple() + { + return !$this->isSpecial() && !$this->getAttribute('is_defined_test'); + } } diff --git a/inc/lib/Twig/Node/Expression/Parent.php b/inc/lib/Twig/Node/Expression/Parent.php index 5689fe45..dcf618c0 100644 --- a/inc/lib/Twig/Node/Expression/Parent.php +++ b/inc/lib/Twig/Node/Expression/Parent.php @@ -13,14 +13,13 @@ /** * Represents a parent node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Expression_Parent extends Twig_Node_Expression { public function __construct($name, $lineno, $tag = null) { - parent::__construct(array(), array('name' => $name), $lineno, $tag); + parent::__construct(array(), array('output' => false, 'name' => $name), $lineno, $tag); } /** @@ -30,10 +29,19 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression */ public function compile(Twig_Compiler $compiler) { - $compiler - ->raw("\$this->renderParentBlock(") - ->string($this->getAttribute('name')) - ->raw(", \$context, \$blocks)") - ; + if ($this->getAttribute('output')) { + $compiler + ->addDebugInfo($this) + ->write("\$this->displayParentBlock(") + ->string($this->getAttribute('name')) + ->raw(", \$context, \$blocks);\n") + ; + } else { + $compiler + ->raw("\$this->renderParentBlock(") + ->string($this->getAttribute('name')) + ->raw(", \$context, \$blocks)") + ; + } } } diff --git a/inc/lib/Twig/Node/Expression/TempName.php b/inc/lib/Twig/Node/Expression/TempName.php new file mode 100644 index 00000000..e6b058e8 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/TempName.php @@ -0,0 +1,26 @@ + $name), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('$_') + ->raw($this->getAttribute('name')) + ->raw('_') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test.php b/inc/lib/Twig/Node/Expression/Test.php index ef35df6b..639f501a 100644 --- a/inc/lib/Twig/Node/Expression/Test.php +++ b/inc/lib/Twig/Node/Expression/Test.php @@ -8,7 +8,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -class Twig_Node_Expression_Test extends Twig_Node_Expression +class Twig_Node_Expression_Test extends Twig_Node_Expression_Call { public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) { @@ -17,44 +17,16 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression public function compile(Twig_Compiler $compiler) { - $testMap = $compiler->getEnvironment()->getTests(); - if (!isset($testMap[$this->getAttribute('name')])) { - throw new Twig_Error_Syntax(sprintf('The test "%s" does not exist', $this->getAttribute('name')), $this->getLine()); - } - $name = $this->getAttribute('name'); - $node = $this->getNode('node'); + $test = $compiler->getEnvironment()->getTest($name); - // defined is a special case - if ('defined' === $name) { - if ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr) { - $node->setAttribute('is_defined_test', true); - $compiler->subcompile($node); - $node->removeAttribute('is_defined_test'); - } else { - throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine()); - } - return; + $this->setAttribute('name', $name); + $this->setAttribute('type', 'test'); + $this->setAttribute('thing', $test); + if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) { + $this->setAttribute('callable', $test->getCallable()); } - $compiler - ->raw($testMap[$name]->compile().'(') - ->subcompile($node) - ; - - if (null !== $this->getNode('arguments')) { - $compiler->raw(', '); - - $max = count($this->getNode('arguments')) - 1; - foreach ($this->getNode('arguments') as $i => $arg) { - $compiler->subcompile($arg); - - if ($i != $max) { - $compiler->raw(', '); - } - } - } - - $compiler->raw(')'); + $this->compileCallable($compiler); } } diff --git a/inc/lib/Twig/Node/Expression/Test/Constant.php b/inc/lib/Twig/Node/Expression/Test/Constant.php new file mode 100644 index 00000000..de55f5f5 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Constant.php @@ -0,0 +1,46 @@ + + * {% if post.status is constant('Post::PUBLISHED') %} + * the status attribute is exactly the same as Post::PUBLISHED + * {% endif %} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' === constant(') + ; + + if ($this->getNode('arguments')->hasNode(1)) { + $compiler + ->raw('get_class(') + ->subcompile($this->getNode('arguments')->getNode(1)) + ->raw(')."::".') + ; + } + + $compiler + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw('))') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Defined.php b/inc/lib/Twig/Node/Expression/Test/Defined.php new file mode 100644 index 00000000..247b2e23 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Defined.php @@ -0,0 +1,54 @@ + + * {# defined works with variable names and variable attributes #} + * {% if foo is defined %} + * {# ... #} + * {% endif %} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test +{ + public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) + { + parent::__construct($node, $name, $arguments, $lineno); + + if ($node instanceof Twig_Node_Expression_Name) { + $node->setAttribute('is_defined_test', true); + } elseif ($node instanceof Twig_Node_Expression_GetAttr) { + $node->setAttribute('is_defined_test', true); + + $this->changeIgnoreStrictCheck($node); + } else { + throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine()); + } + } + + protected function changeIgnoreStrictCheck(Twig_Node_Expression_GetAttr $node) + { + $node->setAttribute('ignore_strict_check', true); + + if ($node->getNode('node') instanceof Twig_Node_Expression_GetAttr) { + $this->changeIgnoreStrictCheck($node->getNode('node')); + } + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->subcompile($this->getNode('node')); + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Divisibleby.php b/inc/lib/Twig/Node/Expression/Test/Divisibleby.php new file mode 100644 index 00000000..0aceb530 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Divisibleby.php @@ -0,0 +1,33 @@ + + * {% if loop.index is divisibleby(3) %} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(0 == ') + ->subcompile($this->getNode('node')) + ->raw(' % ') + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw(')') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Even.php b/inc/lib/Twig/Node/Expression/Test/Even.php new file mode 100644 index 00000000..d7853e89 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Even.php @@ -0,0 +1,32 @@ + + * {{ var is even }} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 == 0') + ->raw(')') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Null.php b/inc/lib/Twig/Node/Expression/Test/Null.php new file mode 100644 index 00000000..1c83825a --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Null.php @@ -0,0 +1,31 @@ + + * {{ var is none }} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(null === ') + ->subcompile($this->getNode('node')) + ->raw(')') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Odd.php b/inc/lib/Twig/Node/Expression/Test/Odd.php new file mode 100644 index 00000000..421c19e8 --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Odd.php @@ -0,0 +1,32 @@ + + * {{ var is odd }} + * + * + * @author Fabien Potencier + */ +class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 == 1') + ->raw(')') + ; + } +} diff --git a/inc/lib/Twig/Node/Expression/Test/Sameas.php b/inc/lib/Twig/Node/Expression/Test/Sameas.php new file mode 100644 index 00000000..b48905ee --- /dev/null +++ b/inc/lib/Twig/Node/Expression/Test/Sameas.php @@ -0,0 +1,29 @@ + + */ +class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test +{ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' === ') + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw(')') + ; + } +} diff --git a/inc/lib/Twig/Node/Flush.php b/inc/lib/Twig/Node/Flush.php new file mode 100644 index 00000000..0467ddce --- /dev/null +++ b/inc/lib/Twig/Node/Flush.php @@ -0,0 +1,36 @@ + + */ +class Twig_Node_Flush extends Twig_Node +{ + public function __construct($lineno, $tag) + { + parent::__construct(array(), array(), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write("flush();\n") + ; + } +} diff --git a/inc/lib/Twig/Node/For.php b/inc/lib/Twig/Node/For.php index eb204e28..d1ff371d 100644 --- a/inc/lib/Twig/Node/For.php +++ b/inc/lib/Twig/Node/For.php @@ -13,14 +13,21 @@ /** * Represents a for node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_For extends Twig_Node { + protected $loop; + public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Node_Expression_AssignName $valueTarget, Twig_Node_Expression $seq, Twig_Node_Expression $ifexpr = null, Twig_NodeInterface $body, Twig_NodeInterface $else = null, $lineno, $tag = null) { - parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'ifexpr' => $ifexpr, 'body' => $body, 'else' => $else), array('with_loop' => true), $lineno, $tag); + $body = new Twig_Node(array($body, $this->loop = new Twig_Node_ForLoop($lineno, $tag))); + + if (null !== $ifexpr) { + $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag); + } + + parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag); } /** @@ -53,7 +60,7 @@ class Twig_Node_For extends Twig_Node ->write(");\n") ; - if (null === $this->getNode('ifexpr')) { + if (!$this->getAttribute('ifexpr')) { $compiler ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) {\n") ->indent() @@ -68,6 +75,10 @@ class Twig_Node_For extends Twig_Node } } + $this->loop->setAttribute('else', null !== $this->getNode('else')); + $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop')); + $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr')); + $compiler ->write("foreach (\$context['_seq'] as ") ->subcompile($this->getNode('key_target')) @@ -75,47 +86,7 @@ class Twig_Node_For extends Twig_Node ->subcompile($this->getNode('value_target')) ->raw(") {\n") ->indent() - ; - - if (null !== $this->getNode('ifexpr')) { - $compiler - ->write("if (!(") - ->subcompile($this->getNode('ifexpr')) - ->raw(")) {\n") - ->indent() - ->write("continue;\n") - ->outdent() - ->write("}\n\n") - ; - } - - $compiler->subcompile($this->getNode('body')); - - if (null !== $this->getNode('else')) { - $compiler->write("\$context['_iterated'] = true;\n"); - } - - if ($this->getAttribute('with_loop')) { - $compiler - ->write("++\$context['loop']['index0'];\n") - ->write("++\$context['loop']['index'];\n") - ->write("\$context['loop']['first'] = false;\n") - ; - - if (null === $this->getNode('ifexpr')) { - $compiler - ->write("if (isset(\$context['loop']['length'])) {\n") - ->indent() - ->write("--\$context['loop']['revindex0'];\n") - ->write("--\$context['loop']['revindex'];\n") - ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") - ->outdent() - ->write("}\n") - ; - } - } - - $compiler + ->subcompile($this->getNode('body')) ->outdent() ->write("}\n") ; @@ -136,6 +107,6 @@ class Twig_Node_For extends Twig_Node $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n"); // keep the values set in the inner context for variables defined in the outer context - $compiler->write("\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent));\n"); + $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n"); } } diff --git a/inc/lib/Twig/Node/ForLoop.php b/inc/lib/Twig/Node/ForLoop.php new file mode 100644 index 00000000..b8841583 --- /dev/null +++ b/inc/lib/Twig/Node/ForLoop.php @@ -0,0 +1,55 @@ + + */ +class Twig_Node_ForLoop extends Twig_Node +{ + public function __construct($lineno, $tag = null) + { + parent::__construct(array(), array('with_loop' => false, 'ifexpr' => false, 'else' => false), $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Twig_Compiler A Twig_Compiler instance + */ + public function compile(Twig_Compiler $compiler) + { + if ($this->getAttribute('else')) { + $compiler->write("\$context['_iterated'] = true;\n"); + } + + if ($this->getAttribute('with_loop')) { + $compiler + ->write("++\$context['loop']['index0'];\n") + ->write("++\$context['loop']['index'];\n") + ->write("\$context['loop']['first'] = false;\n") + ; + + if (!$this->getAttribute('ifexpr')) { + $compiler + ->write("if (isset(\$context['loop']['length'])) {\n") + ->indent() + ->write("--\$context['loop']['revindex0'];\n") + ->write("--\$context['loop']['revindex'];\n") + ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") + ->outdent() + ->write("}\n") + ; + } + } + } +} diff --git a/inc/lib/Twig/Node/If.php b/inc/lib/Twig/Node/If.php index aa12efbe..4296a8d6 100644 --- a/inc/lib/Twig/Node/If.php +++ b/inc/lib/Twig/Node/If.php @@ -13,8 +13,7 @@ /** * Represents an if node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_If extends Twig_Node { diff --git a/inc/lib/Twig/Node/Import.php b/inc/lib/Twig/Node/Import.php index a327411d..99efc091 100644 --- a/inc/lib/Twig/Node/Import.php +++ b/inc/lib/Twig/Node/Import.php @@ -12,8 +12,7 @@ /** * Represents an import node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Import extends Twig_Node { diff --git a/inc/lib/Twig/Node/Include.php b/inc/lib/Twig/Node/Include.php index 467749b5..ed4a3751 100644 --- a/inc/lib/Twig/Node/Include.php +++ b/inc/lib/Twig/Node/Include.php @@ -13,8 +13,7 @@ /** * Represents an include node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface { @@ -39,21 +38,46 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface ; } + $this->addGetTemplate($compiler); + + $compiler->raw('->display('); + + $this->addTemplateArguments($compiler); + + $compiler->raw(");\n"); + + if ($this->getAttribute('ignore_missing')) { + $compiler + ->outdent() + ->write("} catch (Twig_Error_Loader \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n\n") + ; + } + } + + protected function addGetTemplate(Twig_Compiler $compiler) + { if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) { $compiler ->write("\$this->env->loadTemplate(") ->subcompile($this->getNode('expr')) - ->raw(")->display(") + ->raw(")") ; } else { $compiler ->write("\$template = \$this->env->resolveTemplate(") ->subcompile($this->getNode('expr')) ->raw(");\n") - ->write('$template->display(') + ->write('$template') ; } + } + protected function addTemplateArguments(Twig_Compiler $compiler) + { if (false === $this->getAttribute('only')) { if (null === $this->getNode('variables')) { $compiler->raw('$context'); @@ -71,18 +95,5 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface $compiler->subcompile($this->getNode('variables')); } } - - $compiler->raw(");\n"); - - if ($this->getAttribute('ignore_missing')) { - $compiler - ->outdent() - ->write("} catch (Twig_Error_Loader \$e) {\n") - ->indent() - ->write("// ignore missing template\n") - ->outdent() - ->write("}\n\n") - ; - } } } diff --git a/inc/lib/Twig/Node/Macro.php b/inc/lib/Twig/Node/Macro.php index 9f95570f..89910618 100644 --- a/inc/lib/Twig/Node/Macro.php +++ b/inc/lib/Twig/Node/Macro.php @@ -12,8 +12,7 @@ /** * Represents a macro node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Macro extends Twig_Node { @@ -29,43 +28,67 @@ class Twig_Node_Macro extends Twig_Node */ public function compile(Twig_Compiler $compiler) { - $arguments = array(); - foreach ($this->getNode('arguments') as $argument) { - $arguments[] = '$'.$argument->getAttribute('name').' = null'; + $compiler + ->addDebugInfo($this) + ->write(sprintf("public function get%s(", $this->getAttribute('name'))) + ; + + $count = count($this->getNode('arguments')); + $pos = 0; + foreach ($this->getNode('arguments') as $name => $default) { + $compiler + ->raw('$_'.$name.' = ') + ->subcompile($default) + ; + + if (++$pos < $count) { + $compiler->raw(', '); + } } $compiler - ->addDebugInfo($this) - ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n") - ->indent() - ->write("\$context = array_merge(\$this->env->getGlobals(), array(\n") + ->raw(")\n") + ->write("{\n") ->indent() ; - foreach ($this->getNode('arguments') as $argument) { + if (!count($this->getNode('arguments'))) { + $compiler->write("\$context = \$this->env->getGlobals();\n\n"); + } else { $compiler - ->write('') - ->string($argument->getAttribute('name')) - ->raw(' => $'.$argument->getAttribute('name')) - ->raw(",\n") + ->write("\$context = \$this->env->mergeGlobals(array(\n") + ->indent() + ; + + foreach ($this->getNode('arguments') as $name => $default) { + $compiler + ->write('') + ->string($name) + ->raw(' => $_'.$name) + ->raw(",\n") + ; + } + + $compiler + ->outdent() + ->write("));\n\n") ; } $compiler - ->outdent() - ->write("));\n\n") + ->write("\$blocks = array();\n\n") ->write("ob_start();\n") ->write("try {\n") ->indent() ->subcompile($this->getNode('body')) ->outdent() - ->write("} catch(Exception \$e) {\n") + ->write("} catch (Exception \$e) {\n") ->indent() ->write("ob_end_clean();\n\n") ->write("throw \$e;\n") ->outdent() ->write("}\n\n") - ->write("return ob_get_clean();\n") + ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n") ->outdent() ->write("}\n\n") ; diff --git a/inc/lib/Twig/Node/Module.php b/inc/lib/Twig/Node/Module.php index 9b8c55e3..585048b8 100644 --- a/inc/lib/Twig/Node/Module.php +++ b/inc/lib/Twig/Node/Module.php @@ -13,14 +13,19 @@ /** * Represents a module node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Module extends Twig_Node { - public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $filename) + public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename) { - parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename), 1); + // embedded templates are set as attributes so that they are only visited once by the visitors + parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1); + } + + public function setIndex($index) + { + $this->setAttribute('index', $index); } /** @@ -31,13 +36,21 @@ class Twig_Node_Module extends Twig_Node public function compile(Twig_Compiler $compiler) { $this->compileTemplate($compiler); + + foreach ($this->getAttribute('embedded_templates') as $template) { + $compiler->subcompile($template); + } } protected function compileTemplate(Twig_Compiler $compiler) { + if (!$this->getAttribute('index')) { + $compiler->write('compileClassHeader($compiler); - if (count($this->getNode('blocks')) || count($this->getNode('traits'))) { + if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) { $this->compileConstructor($compiler); } @@ -57,29 +70,31 @@ class Twig_Node_Module extends Twig_Node $this->compileIsTraitable($compiler); + $this->compileDebugInfo($compiler); + $this->compileClassFooter($compiler); } protected function compileGetParent(Twig_Compiler $compiler) { + if (null === $this->getNode('parent')) { + return; + } + $compiler ->write("protected function doGetParent(array \$context)\n", "{\n") ->indent() ->write("return ") ; - if (null === $this->getNode('parent')) { - $compiler->raw("false"); + if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + $compiler->subcompile($this->getNode('parent')); } else { - if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { - $compiler->subcompile($this->getNode('parent')); - } else { - $compiler - ->raw("\$this->env->resolveTemplate(") - ->subcompile($this->getNode('parent')) - ->raw(")") - ; - } + $compiler + ->raw("\$this->env->resolveTemplate(") + ->subcompile($this->getNode('parent')) + ->raw(")") + ; } $compiler @@ -91,21 +106,25 @@ class Twig_Node_Module extends Twig_Node protected function compileDisplayBody(Twig_Compiler $compiler) { - $compiler->write("\$context = array_merge(\$this->env->getGlobals(), \$context);\n\n"); $compiler->subcompile($this->getNode('body')); if (null !== $this->getNode('parent')) { - $compiler->write("\$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); + if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + $compiler->write("\$this->parent"); + } else { + $compiler->write("\$this->getParent(\$context)"); + } + $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); } } protected function compileClassHeader(Twig_Compiler $compiler) { $compiler - ->write("write("\n\n") // if the filename contains */, add a blank to avoid a PHP parse error ->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n") - ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'))) + ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index'))) ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass())) ->write("{\n") ->indent() @@ -120,6 +139,17 @@ class Twig_Node_Module extends Twig_Node ->write("parent::__construct(\$env);\n\n") ; + // parent + if (null === $this->getNode('parent')) { + $compiler->write("\$this->parent = false;\n\n"); + } elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) { + $compiler + ->write("\$this->parent = \$this->env->loadTemplate(") + ->subcompile($this->getNode('parent')) + ->raw(");\n\n") + ; + } + $countTraits = count($this->getNode('traits')); if ($countTraits) { // traits @@ -151,18 +181,32 @@ class Twig_Node_Module extends Twig_Node } } - $compiler - ->write("\$this->blocks = array_merge(\n") - ->indent() - ; - - for ($i = 0; $i < $countTraits; $i++) { + if ($countTraits > 1) { $compiler - ->write(sprintf("\$_trait_%s_blocks,\n", $i)) + ->write("\$this->traits = array_merge(\n") + ->indent() + ; + + for ($i = 0; $i < $countTraits; $i++) { + $compiler + ->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i)) + ; + } + + $compiler + ->outdent() + ->write(");\n\n") + ; + } else { + $compiler + ->write("\$this->traits = \$_trait_0_blocks;\n\n") ; } $compiler + ->write("\$this->blocks = array_merge(\n") + ->indent() + ->write("\$this->traits,\n") ->write("array(\n") ; } else { @@ -250,11 +294,21 @@ class Twig_Node_Module extends Twig_Node // only contains blocks and use statements. $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros')); if ($traitable) { - if (!count($nodes = $this->getNode('body'))) { - $nodes = new Twig_Node(array($this->getNode('body'))); + if ($this->getNode('body') instanceof Twig_Node_Body) { + $nodes = $this->getNode('body')->getNode(0); + } else { + $nodes = $this->getNode('body'); + } + + if (!count($nodes)) { + $nodes = new Twig_Node(array($nodes)); } foreach ($nodes as $node) { + if (!count($node)) { + continue; + } + if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { continue; } @@ -268,16 +322,31 @@ class Twig_Node_Module extends Twig_Node } } + if ($traitable) { + return; + } + $compiler ->write("public function isTraitable()\n", "{\n") ->indent() ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false')) ->outdent() + ->write("}\n\n") + ; + } + + protected function compileDebugInfo(Twig_Compiler $compiler) + { + $compiler + ->write("public function getDebugInfo()\n", "{\n") + ->indent() + ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true)))) + ->outdent() ->write("}\n") ; } - public function compileLoadTemplate(Twig_Compiler $compiler, $node, $var) + protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var) { if ($node instanceof Twig_Node_Expression_Constant) { $compiler diff --git a/inc/lib/Twig/Node/Print.php b/inc/lib/Twig/Node/Print.php index 766725ff..b0c41d1d 100644 --- a/inc/lib/Twig/Node/Print.php +++ b/inc/lib/Twig/Node/Print.php @@ -13,8 +13,7 @@ /** * Represents a node that outputs an expression. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface { diff --git a/inc/lib/Twig/Node/Sandbox.php b/inc/lib/Twig/Node/Sandbox.php index cbfcb411..8cf3ed44 100644 --- a/inc/lib/Twig/Node/Sandbox.php +++ b/inc/lib/Twig/Node/Sandbox.php @@ -12,8 +12,7 @@ /** * Represents a sandbox node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Sandbox extends Twig_Node { diff --git a/inc/lib/Twig/Node/SandboxedModule.php b/inc/lib/Twig/Node/SandboxedModule.php index 36d9f198..be1f5daa 100644 --- a/inc/lib/Twig/Node/SandboxedModule.php +++ b/inc/lib/Twig/Node/SandboxedModule.php @@ -13,8 +13,7 @@ /** * Represents a module node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_SandboxedModule extends Twig_Node_Module { @@ -24,7 +23,9 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions) { - parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); + parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('embedded_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag()); + + $this->setAttribute('index', $node->getAttribute('index')); $this->usedFilters = $usedFilters; $this->usedTags = $usedTags; @@ -33,9 +34,7 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module protected function compileDisplayBody(Twig_Compiler $compiler) { - if (null === $this->getNode('parent')) { - $compiler->write("\$this->checkSecurity();\n"); - } + $compiler->write("\$this->checkSecurity();\n"); parent::compileDisplayBody($compiler); } @@ -45,7 +44,7 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module parent::compileDisplayFooter($compiler); $compiler - ->write("protected function checkSecurity() {\n") + ->write("protected function checkSecurity()\n", "{\n") ->indent() ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") ->indent() @@ -54,16 +53,6 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module ->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n") ->outdent() ->write(");\n") - ; - - if (null !== $this->getNode('parent')) { - $compiler - ->raw("\n") - ->write("\$this->parent->checkSecurity();\n") - ; - } - - $compiler ->outdent() ->write("}\n\n") ; diff --git a/inc/lib/Twig/Node/SandboxedPrint.php b/inc/lib/Twig/Node/SandboxedPrint.php index 77730d8c..73dfaa96 100644 --- a/inc/lib/Twig/Node/SandboxedPrint.php +++ b/inc/lib/Twig/Node/SandboxedPrint.php @@ -17,8 +17,7 @@ * and if the sandbox is enabled, we need to check that the __toString() * method is allowed if 'article' is an object. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_SandboxedPrint extends Twig_Node_Print { diff --git a/inc/lib/Twig/Node/Set.php b/inc/lib/Twig/Node/Set.php index 9913664f..4c9c16ce 100644 --- a/inc/lib/Twig/Node/Set.php +++ b/inc/lib/Twig/Node/Set.php @@ -12,8 +12,7 @@ /** * Represents a set node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Set extends Twig_Node { @@ -67,7 +66,7 @@ class Twig_Node_Set extends Twig_Node $compiler->subcompile($this->getNode('names'), false); if ($this->getAttribute('capture')) { - $compiler->raw(" = new Twig_Markup(ob_get_clean())"); + $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())"); } } @@ -87,9 +86,9 @@ class Twig_Node_Set extends Twig_Node } else { if ($this->getAttribute('safe')) { $compiler - ->raw("new Twig_Markup(") + ->raw("('' === \$tmp = ") ->subcompile($this->getNode('values')) - ->raw(")") + ->raw(") ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset())") ; } else { $compiler->subcompile($this->getNode('values')); diff --git a/inc/lib/Twig/Node/SetTemp.php b/inc/lib/Twig/Node/SetTemp.php new file mode 100644 index 00000000..3bdd1cb7 --- /dev/null +++ b/inc/lib/Twig/Node/SetTemp.php @@ -0,0 +1,35 @@ + $name), $lineno); + } + + public function compile(Twig_Compiler $compiler) + { + $name = $this->getAttribute('name'); + $compiler + ->addDebugInfo($this) + ->write('if (isset($context[') + ->string($name) + ->raw('])) { $_') + ->raw($name) + ->raw('_ = $context[') + ->repr($name) + ->raw(']; } else { $_') + ->raw($name) + ->raw("_ = null; }\n") + ; + } +} diff --git a/inc/lib/Twig/Node/Spaceless.php b/inc/lib/Twig/Node/Spaceless.php index 46013466..7555fa0f 100644 --- a/inc/lib/Twig/Node/Spaceless.php +++ b/inc/lib/Twig/Node/Spaceless.php @@ -14,8 +14,7 @@ * * It removes spaces between HTML tags. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Spaceless extends Twig_Node { diff --git a/inc/lib/Twig/Node/Text.php b/inc/lib/Twig/Node/Text.php index 0c1c0928..21bdcea1 100644 --- a/inc/lib/Twig/Node/Text.php +++ b/inc/lib/Twig/Node/Text.php @@ -13,8 +13,7 @@ /** * Represents a text node. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface { diff --git a/inc/lib/Twig/NodeInterface.php b/inc/lib/Twig/NodeInterface.php index 165aed4d..f0ef7258 100644 --- a/inc/lib/Twig/NodeInterface.php +++ b/inc/lib/Twig/NodeInterface.php @@ -12,19 +12,19 @@ /** * Represents a node in the AST. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ -interface Twig_NodeInterface +interface Twig_NodeInterface extends Countable, IteratorAggregate { /** * Compiles the node to PHP. * * @param Twig_Compiler A Twig_Compiler instance */ - function compile(Twig_Compiler $compiler); + public function compile(Twig_Compiler $compiler); - function getLine(); + public function getLine(); - function getNodeTag(); + public function getNodeTag(); } diff --git a/inc/lib/Twig/NodeOutputInterface.php b/inc/lib/Twig/NodeOutputInterface.php index 71839569..22172c09 100644 --- a/inc/lib/Twig/NodeOutputInterface.php +++ b/inc/lib/Twig/NodeOutputInterface.php @@ -12,8 +12,7 @@ /** * Represents a displayable node in the AST. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_NodeOutputInterface { diff --git a/inc/lib/Twig/NodeTraverser.php b/inc/lib/Twig/NodeTraverser.php index 1e82b032..28cba1ad 100644 --- a/inc/lib/Twig/NodeTraverser.php +++ b/inc/lib/Twig/NodeTraverser.php @@ -14,8 +14,7 @@ * * It visits all nodes and their children and call the given visitor for each. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_NodeTraverser { diff --git a/inc/lib/Twig/NodeVisitor/Escaper.php b/inc/lib/Twig/NodeVisitor/Escaper.php index 049ce96a..cc4b3d71 100644 --- a/inc/lib/Twig/NodeVisitor/Escaper.php +++ b/inc/lib/Twig/NodeVisitor/Escaper.php @@ -12,18 +12,18 @@ /** * Twig_NodeVisitor_Escaper implements output escaping. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface { protected $statusStack = array(); protected $blocks = array(); - protected $safeAnalysis; protected $traverser; + protected $defaultStrategy = false; + protected $safeVars = array(); - function __construct() + public function __construct() { $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis(); } @@ -34,14 +34,21 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface The modified node */ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) { - if ($node instanceof Twig_Node_AutoEscape) { + if ($node instanceof Twig_Node_Module) { + if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) { + $this->defaultStrategy = $defaultStrategy; + } + $this->safeVars = array(); + } elseif ($node instanceof Twig_Node_AutoEscape) { $this->statusStack[] = $node->getAttribute('value'); } elseif ($node instanceof Twig_Node_Block) { $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env); + } elseif ($node instanceof Twig_Node_Import) { + $this->safeVars[] = $node->getNode('var')->getAttribute('name'); } return $node; @@ -53,11 +60,14 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface The modified node */ public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { - if ($node instanceof Twig_Node_Expression_Filter) { + if ($node instanceof Twig_Node_Module) { + $this->defaultStrategy = false; + $this->safeVars = array(); + } elseif ($node instanceof Twig_Node_Expression_Filter) { return $this->preEscapeFilterNode($node, $env); } elseif ($node instanceof Twig_Node_Print) { return $this->escapePrintNode($node, $env, $this->needEscaping($env)); @@ -96,22 +106,18 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface { $name = $filter->getNode('filter')->getAttribute('value'); - if (false !== $f = $env->getFilter($name)) { - $type = $f->getPreEscape(); - if (null === $type) { - return $filter; - } - - $node = $filter->getNode('node'); - if ($this->isSafeFor($type, $node, $env)) { - return $filter; - } - - $filter->setNode('node', $this->getEscaperFilter($type, $node)); - + $type = $env->getFilter($name)->getPreEscape(); + if (null === $type) { return $filter; } + $node = $filter->getNode('node'); + if ($this->isSafeFor($type, $node, $env)) { + return $filter; + } + + $filter->setNode('node', $this->getEscaperFilter($type, $node)); + return $filter; } @@ -123,6 +129,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface if (null === $this->traverser) { $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis)); } + + $this->safeAnalysis->setSafeVars($this->safeVars); + $this->traverser->traverse($expression); $safe = $this->safeAnalysis->getSafe($expression); } @@ -136,18 +145,15 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface return $this->statusStack[count($this->statusStack) - 1]; } - if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) { - return 'html'; - } - - return false; + return $this->defaultStrategy ? $this->defaultStrategy : false; } protected function getEscaperFilter($type, Twig_NodeInterface $node) { $line = $node->getLine(); $name = new Twig_Node_Expression_Constant('escape', $line); - $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line))); + $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line))); + return new Twig_Node_Expression_Filter($node, $name, $args, $line); } diff --git a/inc/lib/Twig/NodeVisitor/Optimizer.php b/inc/lib/Twig/NodeVisitor/Optimizer.php index 3679746e..a254def7 100644 --- a/inc/lib/Twig/NodeVisitor/Optimizer.php +++ b/inc/lib/Twig/NodeVisitor/Optimizer.php @@ -17,8 +17,7 @@ * You can configure which optimizations you want to activate via the * optimizer mode. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface { @@ -26,9 +25,12 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface const OPTIMIZE_NONE = 0; const OPTIMIZE_FOR = 2; const OPTIMIZE_RAW_FILTER = 4; + const OPTIMIZE_VAR_ACCESS = 8; protected $loops = array(); protected $optimizers; + protected $prependedNodes = array(); + protected $inABody = false; /** * Constructor. @@ -53,6 +55,20 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $this->enterOptimizeFor($node, $env); } + if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if ($this->inABody) { + if (!$node instanceof Twig_Node_Expression) { + if (get_class($node) !== 'Twig_Node') { + array_unshift($this->prependedNodes, array()); + } + } else { + $node = $this->optimizeVariables($node, $env); + } + } elseif ($node instanceof Twig_Node_Body) { + $this->inABody = true; + } + } + return $node; } @@ -61,6 +77,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface */ public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { + $expression = $node instanceof Twig_Node_Expression; + if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { $this->leaveOptimizeFor($node, $env); } @@ -69,20 +87,58 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $node = $this->optimizeRawFilter($node, $env); } - $node = $this->optimizeRenderBlock($node, $env); + $node = $this->optimizePrintNode($node, $env); + + if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if ($node instanceof Twig_Node_Body) { + $this->inABody = false; + } elseif ($this->inABody) { + if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) { + $nodes = array(); + foreach (array_unique($prependedNodes) as $name) { + $nodes[] = new Twig_Node_SetTemp($name, $node->getLine()); + } + + $nodes[] = $node; + $node = new Twig_Node($nodes); + } + } + } + + return $node; + } + + protected function optimizeVariables($node, $env) + { + if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) { + $this->prependedNodes[0][] = $node->getAttribute('name'); + + return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine()); + } return $node; } /** - * Replaces "echo $this->renderBlock()" with "$this->displayBlock()". + * Optimizes print nodes. + * + * It replaces: + * + * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()" * * @param Twig_NodeInterface $node A Node * @param Twig_Environment $env The current Twig environment */ - protected function optimizeRenderBlock($node, $env) + protected function optimizePrintNode($node, $env) { - if ($node instanceof Twig_Node_Print && $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference) { + if (!$node instanceof Twig_Node_Print) { + return $node; + } + + if ( + $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference || + $node->getNode('expr') instanceof Twig_Node_Expression_Parent + ) { $node->getNode('expr')->setAttribute('output', true); return $node->getNode('expr'); diff --git a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php index 5961ba29..c4bbd812 100644 --- a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -3,27 +3,33 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface { protected $data = array(); + protected $safeVars = array(); + + public function setSafeVars($safeVars) + { + $this->safeVars = $safeVars; + } public function getSafe(Twig_NodeInterface $node) { $hash = spl_object_hash($node); if (isset($this->data[$hash])) { - foreach($this->data[$hash] as $bucket) { + foreach ($this->data[$hash] as $bucket) { if ($bucket['key'] === $node) { return $bucket['value']; } } } - return null; } protected function setSafe(Twig_NodeInterface $node, array $safe) { $hash = spl_object_hash($node); if (isset($this->data[$hash])) { - foreach($this->data[$hash] as &$bucket) { + foreach ($this->data[$hash] as &$bucket) { if ($bucket['key'] === $node) { $bucket['value'] = $safe; + return; } } @@ -59,7 +65,11 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface $name = $node->getNode('filter')->getAttribute('value'); $args = $node->getNode('arguments'); if (false !== $filter = $env->getFilter($name)) { - $this->setSafe($node, $filter->getSafe($args)); + $safe = $filter->getSafe($args); + if (null === $safe) { + $safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety()); + } + $this->setSafe($node, $safe); } else { $this->setSafe($node, array()); } @@ -73,6 +83,20 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface } else { $this->setSafe($node, array()); } + } elseif ($node instanceof Twig_Node_Expression_MethodCall) { + if ($node->getAttribute('safe')) { + $this->setSafe($node, array('all')); + } else { + $this->setSafe($node, array()); + } + } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) { + $name = $node->getNode('node')->getAttribute('name'); + // attributes on template instances are safe + if ('_self' == $name || in_array($name, $this->safeVars)) { + $this->setSafe($node, array('all')); + } else { + $this->setSafe($node, array()); + } } else { $this->setSafe($node, array()); } diff --git a/inc/lib/Twig/NodeVisitor/Sandbox.php b/inc/lib/Twig/NodeVisitor/Sandbox.php index 356b661f..fb27045b 100644 --- a/inc/lib/Twig/NodeVisitor/Sandbox.php +++ b/inc/lib/Twig/NodeVisitor/Sandbox.php @@ -12,8 +12,7 @@ /** * Twig_NodeVisitor_Sandbox implements sandboxing. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface { @@ -28,7 +27,7 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface The modified node */ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) { @@ -70,7 +69,7 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface The modified node */ public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { diff --git a/inc/lib/Twig/NodeVisitorInterface.php b/inc/lib/Twig/NodeVisitorInterface.php index d44e510c..f33c13fc 100644 --- a/inc/lib/Twig/NodeVisitorInterface.php +++ b/inc/lib/Twig/NodeVisitorInterface.php @@ -12,8 +12,7 @@ /** * Twig_NodeVisitorInterface is the interface the all node visitor classes must implement. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_NodeVisitorInterface { @@ -23,9 +22,9 @@ interface Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface The modified node */ - function enterNode(Twig_NodeInterface $node, Twig_Environment $env); + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env); /** * Called after child nodes are visited. @@ -33,9 +32,9 @@ interface Twig_NodeVisitorInterface * @param Twig_NodeInterface $node The node to visit * @param Twig_Environment $env The Twig environment instance * - * @param Twig_NodeInterface The modified node + * @return Twig_NodeInterface|false The modified node or false if the node must be removed */ - function leaveNode(Twig_NodeInterface $node, Twig_Environment $env); + public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env); /** * Returns the priority for this visitor. @@ -44,5 +43,5 @@ interface Twig_NodeVisitorInterface * * @return integer The priority level */ - function getPriority(); + public function getPriority(); } diff --git a/inc/lib/Twig/Parser.php b/inc/lib/Twig/Parser.php index 8c982887..958e46b3 100644 --- a/inc/lib/Twig/Parser.php +++ b/inc/lib/Twig/Parser.php @@ -13,11 +13,11 @@ /** * Default parser implementation. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Parser implements Twig_ParserInterface { + protected $stack = array(); protected $stream; protected $parent; protected $handlers; @@ -28,9 +28,9 @@ class Twig_Parser implements Twig_ParserInterface protected $macros; protected $env; protected $reservedMacroNames; - protected $importedFunctions; - protected $tmpVarCount; + protected $importedSymbols; protected $traits; + protected $embeddedTemplates = array(); /** * Constructor. @@ -42,28 +42,45 @@ class Twig_Parser implements Twig_ParserInterface $this->env = $env; } + public function getEnvironment() + { + return $this->env; + } + public function getVarName() { - return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount); + return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false)); + } + + public function getFilename() + { + return $this->stream->getFilename(); } /** * Converts a token stream to a node tree. * - * @param Twig_TokenStream $stream A token stream instance + * @param Twig_TokenStream $stream A token stream instance * * @return Twig_Node_Module A node tree */ - public function parse(Twig_TokenStream $stream) + public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false) { - $this->tmpVarCount = 0; + // push all variables into the stack to keep the current state of the parser + $vars = get_object_vars($this); + unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']); + $this->stack[] = $vars; // tag handlers - $this->handlers = $this->env->getTokenParsers(); - $this->handlers->setParser($this); + if (null === $this->handlers) { + $this->handlers = $this->env->getTokenParsers(); + $this->handlers->setParser($this); + } // node visitors - $this->visitors = $this->env->getNodeVisitors(); + if (null === $this->visitors) { + $this->visitors = $this->env->getNodeVisitors(); + } if (null === $this->expressionParser) { $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators()); @@ -75,10 +92,11 @@ class Twig_Parser implements Twig_ParserInterface $this->macros = array(); $this->traits = array(); $this->blockStack = array(); - $this->importedFunctions = array(array()); + $this->importedSymbols = array(array()); + $this->embeddedTemplates = array(); try { - $body = $this->subparse(null); + $body = $this->subparse($test, $dropNeedle); if (null !== $this->parent) { if (null === $body = $this->filterBodyNodes($body)) { @@ -86,18 +104,29 @@ class Twig_Parser implements Twig_ParserInterface } } } catch (Twig_Error_Syntax $e) { - if (null === $e->getTemplateFile()) { - $e->setTemplateFile($this->stream->getFilename()); + if (!$e->getTemplateFile()) { + $e->setTemplateFile($this->getFilename()); + } + + if (!$e->getTemplateLine()) { + $e->setTemplateLine($this->stream->getCurrent()->getLine()); } throw $e; } - $node = new Twig_Node_Module($body, $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->stream->getFilename()); + $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename()); $traverser = new Twig_NodeTraverser($this->env, $this->visitors); - return $traverser->traverse($node); + $node = $traverser->traverse($node); + + // restore previous stack so previous parse() call can resume working + foreach (array_pop($this->stack) as $key => $val) { + $this->$key = $val; + } + + return $node; } public function subparse($test, $dropNeedle = false) @@ -123,7 +152,7 @@ class Twig_Parser implements Twig_ParserInterface $token = $this->getCurrentToken(); if ($token->getType() !== Twig_Token::NAME_TYPE) { - throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->stream->getFilename()); + throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename()); } if (null !== $test && call_user_func($test, $token)) { @@ -141,10 +170,20 @@ class Twig_Parser implements Twig_ParserInterface $subparser = $this->handlers->getTokenParser($token->getValue()); if (null === $subparser) { if (null !== $test) { - throw new Twig_Error_Syntax(sprintf('Unexpected tag name "%s" (expecting closing tag for the "%s" tag defined near line %s)', $token->getValue(), $test[0]->getTag(), $lineno), $token->getLine(), $this->stream->getFilename()); + $error = sprintf('Unexpected tag name "%s"', $token->getValue()); + if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) { + $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno); + } + + throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename()); } - throw new Twig_Error_Syntax(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine(), $this->stream->getFilename()); + $message = sprintf('Unknown tag name "%s"', $token->getValue()); + if ($alternatives = $this->env->computeAlternatives($token->getValue(), array_keys($this->env->getTags()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename()); } $this->stream->next(); @@ -156,7 +195,7 @@ class Twig_Parser implements Twig_ParserInterface break; default: - throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', -1, $this->stream->getFilename()); + throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename()); } } @@ -202,9 +241,14 @@ class Twig_Parser implements Twig_ParserInterface return isset($this->blocks[$name]); } + public function getBlock($name) + { + return $this->blocks[$name]; + } + public function setBlock($name, $value) { - $this->blocks[$name] = $value; + $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine()); } public function hasMacro($name) @@ -223,7 +267,7 @@ class Twig_Parser implements Twig_ParserInterface } if (in_array($name, $this->reservedMacroNames)) { - throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine()); + throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename()); } $this->macros[$name] = $node; @@ -234,33 +278,45 @@ class Twig_Parser implements Twig_ParserInterface $this->traits[] = $trait; } - public function addImportedFunction($alias, $name, Twig_Node_Expression $node) + public function hasTraits() { - $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node); + return count($this->traits) > 0; } - public function getImportedFunction($alias) + public function embedTemplate(Twig_Node_Module $template) { - foreach ($this->importedFunctions as $functions) { - if (isset($functions[$alias])) { - return $functions[$alias]; + $template->setIndex(mt_rand()); + + $this->embeddedTemplates[] = $template; + } + + public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null) + { + $this->importedSymbols[0][$type][$alias] = array('name' => $name, 'node' => $node); + } + + public function getImportedSymbol($type, $alias) + { + foreach ($this->importedSymbols as $functions) { + if (isset($functions[$type][$alias])) { + return $functions[$type][$alias]; } } } public function isMainScope() { - return 1 === count($this->importedFunctions); + return 1 === count($this->importedSymbols); } public function pushLocalScope() { - array_unshift($this->importedFunctions, array()); + array_unshift($this->importedSymbols, array()); } public function popLocalScope() { - array_shift($this->importedFunctions); + array_shift($this->importedSymbols); } /** @@ -311,7 +367,11 @@ class Twig_Parser implements Twig_ParserInterface || (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface) ) { - throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->stream->getFilename()); + if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) { + throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename()); + } + + throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename()); } // bypass "set" nodes as they "capture" the output diff --git a/inc/lib/Twig/ParserInterface.php b/inc/lib/Twig/ParserInterface.php index c7a34418..f0d79009 100644 --- a/inc/lib/Twig/ParserInterface.php +++ b/inc/lib/Twig/ParserInterface.php @@ -12,17 +12,17 @@ /** * Interface implemented by parser classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_ParserInterface { /** * Converts a token stream to a node tree. * - * @param Twig_TokenStream $stream A token stream instance + * @param Twig_TokenStream $stream A token stream instance * * @return Twig_Node_Module A node tree */ - function parse(Twig_TokenStream $code); + public function parse(Twig_TokenStream $stream); } diff --git a/inc/lib/Twig/Sandbox/SecurityError.php b/inc/lib/Twig/Sandbox/SecurityError.php index debabb79..015bfaea 100644 --- a/inc/lib/Twig/Sandbox/SecurityError.php +++ b/inc/lib/Twig/Sandbox/SecurityError.php @@ -12,8 +12,7 @@ /** * Exception thrown when a security error occurs at runtime. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Sandbox_SecurityError extends Twig_Error { diff --git a/inc/lib/Twig/Sandbox/SecurityPolicy.php b/inc/lib/Twig/Sandbox/SecurityPolicy.php index ba912ef4..66ee2332 100644 --- a/inc/lib/Twig/Sandbox/SecurityPolicy.php +++ b/inc/lib/Twig/Sandbox/SecurityPolicy.php @@ -12,8 +12,7 @@ /** * Represents a security policy which need to be enforced when sandbox mode is enabled. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface { diff --git a/inc/lib/Twig/Sandbox/SecurityPolicyInterface.php b/inc/lib/Twig/Sandbox/SecurityPolicyInterface.php index d5015aff..6ab48e3c 100644 --- a/inc/lib/Twig/Sandbox/SecurityPolicyInterface.php +++ b/inc/lib/Twig/Sandbox/SecurityPolicyInterface.php @@ -12,14 +12,13 @@ /** * Interfaces that all security policy classes must implements. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_Sandbox_SecurityPolicyInterface { - function checkSecurity($tags, $filters, $functions); + public function checkSecurity($tags, $filters, $functions); - function checkMethodAllowed($obj, $method); + public function checkMethodAllowed($obj, $method); - function checkPropertyAllowed($obj, $method); + public function checkPropertyAllowed($obj, $method); } diff --git a/inc/lib/Twig/SimpleFilter.php b/inc/lib/Twig/SimpleFilter.php new file mode 100644 index 00000000..d35c5633 --- /dev/null +++ b/inc/lib/Twig/SimpleFilter.php @@ -0,0 +1,94 @@ + + */ +class Twig_SimpleFilter +{ + protected $name; + protected $callable; + protected $options; + protected $arguments = array(); + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'needs_environment' => false, + 'needs_context' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'pre_escape' => null, + 'preserves_safety' => null, + 'node_class' => 'Twig_Node_Expression_Filter', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } + + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + + public function needsEnvironment() + { + return $this->options['needs_environment']; + } + + public function needsContext() + { + return $this->options['needs_context']; + } + + public function getSafe(Twig_Node $filterArgs) + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return call_user_func($this->options['is_safe_callback'], $filterArgs); + } + } + + public function getPreservesSafety() + { + return $this->options['preserves_safety']; + } + + public function getPreEscape() + { + return $this->options['pre_escape']; + } +} diff --git a/inc/lib/Twig/SimpleFunction.php b/inc/lib/Twig/SimpleFunction.php new file mode 100644 index 00000000..8ef6aca2 --- /dev/null +++ b/inc/lib/Twig/SimpleFunction.php @@ -0,0 +1,84 @@ + + */ +class Twig_SimpleFunction +{ + protected $name; + protected $callable; + protected $options; + protected $arguments = array(); + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'needs_environment' => false, + 'needs_context' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'node_class' => 'Twig_Node_Expression_Function', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } + + public function setArguments($arguments) + { + $this->arguments = $arguments; + } + + public function getArguments() + { + return $this->arguments; + } + + public function needsEnvironment() + { + return $this->options['needs_environment']; + } + + public function needsContext() + { + return $this->options['needs_context']; + } + + public function getSafe(Twig_Node $functionArgs) + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return call_user_func($this->options['is_safe_callback'], $functionArgs); + } + + return array(); + } +} diff --git a/inc/lib/Twig/SimpleTest.php b/inc/lib/Twig/SimpleTest.php new file mode 100644 index 00000000..225459c9 --- /dev/null +++ b/inc/lib/Twig/SimpleTest.php @@ -0,0 +1,46 @@ + + */ +class Twig_SimpleTest +{ + protected $name; + protected $callable; + protected $options; + + public function __construct($name, $callable, array $options = array()) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge(array( + 'node_class' => 'Twig_Node_Expression_Test', + ), $options); + } + + public function getName() + { + return $this->name; + } + + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass() + { + return $this->options['node_class']; + } +} diff --git a/inc/lib/Twig/Template.php b/inc/lib/Twig/Template.php index a129fd73..a001ca03 100644 --- a/inc/lib/Twig/Template.php +++ b/inc/lib/Twig/Template.php @@ -13,16 +13,17 @@ /** * Default base class for compiled templates. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ abstract class Twig_Template implements Twig_TemplateInterface { - static protected $cache = array(); + protected static $cache = array(); + protected $parent; protected $parents; protected $env; protected $blocks; + protected $traits; /** * Constructor. @@ -33,6 +34,7 @@ abstract class Twig_Template implements Twig_TemplateInterface { $this->env = $env; $this->blocks = array(); + $this->traits = array(); } /** @@ -43,9 +45,7 @@ abstract class Twig_Template implements Twig_TemplateInterface abstract public function getTemplateName(); /** - * Returns the Twig environment. - * - * @return Twig_Environment The Twig environment + * {@inheritdoc} */ public function getEnvironment() { @@ -55,10 +55,17 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns the parent template. * + * This method is for internal use only and should never be called + * directly. + * * @return Twig_TemplateInterface|false The parent template or false if there is no parent */ public function getParent(array $context) { + if (null !== $this->parent) { + return $this->parent; + } + $parent = $this->doGetParent($context); if (false === $parent) { return false; @@ -73,33 +80,53 @@ abstract class Twig_Template implements Twig_TemplateInterface return $this->parents[$parent]; } - abstract protected function doGetParent(array $context); + protected function doGetParent(array $context) + { + return false; + } + + public function isTraitable() + { + return true; + } /** * Displays a parent block. * + * This method is for internal use only and should never be called + * directly. + * * @param string $name The block name to display from the parent * @param array $context The context * @param array $blocks The current set of blocks */ public function displayParentBlock($name, array $context, array $blocks = array()) { - if (false !== $parent = $this->getParent($context)) { + $name = (string) $name; + + if (isset($this->traits[$name])) { + $this->traits[$name][0]->displayBlock($name, $context, $blocks); + } elseif (false !== $parent = $this->getParent($context)) { $parent->displayBlock($name, $context, $blocks); } else { - throw new Twig_Error_Runtime('This template has no parent', -1, $this->getTemplateName()); + throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName()); } } /** * Displays a block. * + * This method is for internal use only and should never be called + * directly. + * * @param string $name The block name to display * @param array $context The context * @param array $blocks The current set of blocks */ public function displayBlock($name, array $context, array $blocks = array()) { + $name = (string) $name; + if (isset($blocks[$name])) { $b = $blocks; unset($b[$name]); @@ -114,6 +141,9 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Renders a parent block. * + * This method is for internal use only and should never be called + * directly. + * * @param string $name The block name to render from the parent * @param array $context The context * @param array $blocks The current set of blocks @@ -131,6 +161,9 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Renders a block. * + * This method is for internal use only and should never be called + * directly. + * * @param string $name The block name to render * @param array $context The context * @param array $blocks The current set of blocks @@ -148,19 +181,34 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns whether a block exists or not. * + * This method is for internal use only and should never be called + * directly. + * + * This method does only return blocks defined in the current template + * or defined in "used" traits. + * + * It does not return blocks from parent templates as the parent + * template name can be dynamic, which is only known based on the + * current context. + * * @param string $name The block name * * @return Boolean true if the block exists, false otherwise */ public function hasBlock($name) { - return isset($this->blocks[$name]); + return isset($this->blocks[(string) $name]); } /** * Returns all block names. * + * This method is for internal use only and should never be called + * directly. + * * @return array An array of block names + * + * @see hasBlock */ public function getBlockNames() { @@ -170,7 +218,12 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns all blocks. * + * This method is for internal use only and should never be called + * directly. + * * @return array An array of blocks + * + * @see hasBlock */ public function getBlocks() { @@ -178,28 +231,15 @@ abstract class Twig_Template implements Twig_TemplateInterface } /** - * Displays the template with the given context. - * - * @param array $context An array of parameters to pass to the template - * @param array $blocks An array of blocks to pass to the template + * {@inheritdoc} */ public function display(array $context, array $blocks = array()) { - try { - $this->doDisplay($context, $blocks); - } catch (Twig_Error $e) { - throw $e; - } catch (Exception $e) { - throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e); - } + $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks); } /** - * Renders the template with the given context and returns it as string. - * - * @param array $context An array of parameters to pass to the template - * - * @return string The rendered template + * {@inheritdoc} */ public function render(array $context) { @@ -218,6 +258,28 @@ abstract class Twig_Template implements Twig_TemplateInterface return ob_get_clean(); } + protected function displayWithErrorHandling(array $context, array $blocks = array()) + { + try { + $this->doDisplay($context, $blocks); + } catch (Twig_Error $e) { + if (!$e->getTemplateFile()) { + $e->setTemplateFile($this->getTemplateName()); + } + + // this is mostly useful for Twig_Error_Loader exceptions + // see Twig_Error_Loader + if (false === $e->getTemplateLine()) { + $e->setTemplateLine(-1); + $e->guess(); + } + + throw $e; + } catch (Exception $e) { + throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e); + } + } + /** * Auto-generated method to display the template with the given context. * @@ -229,21 +291,30 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns a variable from the context. * - * @param array $context The context - * @param string $item The variable to return from the context + * This method is for internal use only and should never be called + * directly. + * + * This method should not be overridden in a sub-class as this is an + * implementation detail that has been introduced to optimize variable + * access for versions of PHP before 5.4. This is not a way to override + * the way to get a variable value. + * + * @param array $context The context + * @param string $item The variable to return from the context + * @param Boolean $ignoreStrictCheck Whether to ignore the strict variable check or not * * @return The content of the context variable * * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode */ - protected function getContext($context, $item) + final protected function getContext($context, $item, $ignoreStrictCheck = false) { if (!array_key_exists($item, $context)) { - if (!$this->env->isStrictVariables()) { + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return null; } - throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item)); + throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName()); } return $context[$item]; @@ -252,40 +323,50 @@ abstract class Twig_Template implements Twig_TemplateInterface /** * Returns the attribute value for a given array/object. * - * @param mixed $object The object or array from where to get the item - * @param mixed $item The item to get from the array or object - * @param array $arguments An array of arguments to pass if the item is an object method - * @param string $type The type of attribute (@see Twig_TemplateInterface) - * @param Boolean $isDefinedTest Whether this is only a defined check + * @param mixed $object The object or array from where to get the item + * @param mixed $item The item to get from the array or object + * @param array $arguments An array of arguments to pass if the item is an object method + * @param string $type The type of attribute (@see Twig_TemplateInterface) + * @param Boolean $isDefinedTest Whether this is only a defined check + * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not + * + * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true + * + * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false */ - protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false) + protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) { // array if (Twig_TemplateInterface::METHOD_CALL !== $type) { - if ((is_array($object) && array_key_exists($item, $object)) - || ($object instanceof ArrayAccess && isset($object[$item])) + $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item; + + if ((is_array($object) && array_key_exists($arrayItem, $object)) + || ($object instanceof ArrayAccess && isset($object[$arrayItem])) ) { if ($isDefinedTest) { return true; } - return $object[$item]; + return $object[$arrayItem]; } - if (Twig_TemplateInterface::ARRAY_CALL === $type) { + if (Twig_TemplateInterface::ARRAY_CALL === $type || !is_object($object)) { if ($isDefinedTest) { return false; } - if (!$this->env->isStrictVariables()) { + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return null; } if (is_object($object)) { - throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $item, get_class($object))); - // array + throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $arrayItem, get_class($object)), -1, $this->getTemplateName()); + } elseif (is_array($object)) { + throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))), -1, $this->getTemplateName()); + } elseif (Twig_TemplateInterface::ARRAY_CALL === $type) { + throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); } else { - throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object)))); + throw new Twig_Error_Runtime(sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); } } } @@ -295,32 +376,18 @@ abstract class Twig_Template implements Twig_TemplateInterface return false; } - if (!$this->env->isStrictVariables()) { + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return null; } - throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, $object)); + throw new Twig_Error_Runtime(sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName()); } - // get some information about the object $class = get_class($object); - if (!isset(self::$cache[$class])) { - $r = new ReflectionClass($class); - self::$cache[$class] = array('methods' => array(), 'properties' => array()); - foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - self::$cache[$class]['methods'][strtolower($method->getName())] = true; - } - - foreach ($r->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { - self::$cache[$class]['properties'][$property->getName()] = true; - } - } // object property if (Twig_TemplateInterface::METHOD_CALL !== $type) { - if (isset(self::$cache[$class]['properties'][$item]) - || isset($object->$item) || array_key_exists($item, $object) - ) { + if (isset($object->$item) || array_key_exists((string) $item, $object)) { if ($isDefinedTest) { return true; } @@ -334,25 +401,29 @@ abstract class Twig_Template implements Twig_TemplateInterface } // object method + if (!isset(self::$cache[$class]['methods'])) { + self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object))); + } + $lcItem = strtolower($item); if (isset(self::$cache[$class]['methods'][$lcItem])) { - $method = $item; + $method = (string) $item; } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) { $method = 'get'.$item; } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) { $method = 'is'.$item; } elseif (isset(self::$cache[$class]['methods']['__call'])) { - $method = $item; + $method = (string) $item; } else { if ($isDefinedTest) { return false; } - if (!$this->env->isStrictVariables()) { + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { return null; } - throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object))); + throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName()); } if ($isDefinedTest) { @@ -365,10 +436,20 @@ abstract class Twig_Template implements Twig_TemplateInterface $ret = call_user_func_array(array($object, $method), $arguments); + // useful when calling a template method from a template + // this is not supported but unfortunately heavily used in the Symfony profiler if ($object instanceof Twig_TemplateInterface) { - return new Twig_Markup($ret); + return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset()); } return $ret; } + + /** + * This method is only useful when testing Twig. Do not use it. + */ + public static function clearCache() + { + self::$cache = array(); + } } diff --git a/inc/lib/Twig/TemplateInterface.php b/inc/lib/Twig/TemplateInterface.php index 08da1163..879f503e 100644 --- a/inc/lib/Twig/TemplateInterface.php +++ b/inc/lib/Twig/TemplateInterface.php @@ -12,8 +12,8 @@ /** * Interface implemented by all compiled templates. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TemplateInterface { @@ -28,7 +28,7 @@ interface Twig_TemplateInterface * * @return string The rendered template */ - function render(array $context); + public function render(array $context); /** * Displays the template with the given context. @@ -36,12 +36,12 @@ interface Twig_TemplateInterface * @param array $context An array of parameters to pass to the template * @param array $blocks An array of blocks to pass to the template */ - function display(array $context, array $blocks = array()); + public function display(array $context, array $blocks = array()); /** * Returns the bound environment for this template. * * @return Twig_Environment The current environment */ - function getEnvironment(); + public function getEnvironment(); } diff --git a/inc/lib/Twig/Test.php b/inc/lib/Twig/Test.php new file mode 100644 index 00000000..3baff885 --- /dev/null +++ b/inc/lib/Twig/Test.php @@ -0,0 +1,34 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +abstract class Twig_Test implements Twig_TestInterface, Twig_TestCallableInterface +{ + protected $options; + protected $arguments = array(); + + public function __construct(array $options = array()) + { + $this->options = array_merge(array( + 'callable' => null, + ), $options); + } + + public function getCallable() + { + return $this->options['callable']; + } +} diff --git a/inc/lib/Twig/Test/Function.php b/inc/lib/Twig/Test/Function.php index 1240a0f1..4be6b9b9 100644 --- a/inc/lib/Twig/Test/Function.php +++ b/inc/lib/Twig/Test/Function.php @@ -12,15 +12,19 @@ /** * Represents a function template test. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ -class Twig_Test_Function implements Twig_TestInterface +class Twig_Test_Function extends Twig_Test { protected $function; - public function __construct($function) + public function __construct($function, array $options = array()) { + $options['callable'] = $function; + + parent::__construct($options); + $this->function = $function; } diff --git a/inc/lib/Twig/Test/IntegrationTestCase.php b/inc/lib/Twig/Test/IntegrationTestCase.php new file mode 100644 index 00000000..724f0941 --- /dev/null +++ b/inc/lib/Twig/Test/IntegrationTestCase.php @@ -0,0 +1,154 @@ + + * @author Karma Dordrak + */ +abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase +{ + abstract protected function getExtensions(); + abstract protected function getFixturesDir(); + + /** + * @dataProvider getTests + */ + public function testIntegration($file, $message, $condition, $templates, $exception, $outputs) + { + $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs); + } + + public function getTests() + { + $fixturesDir = realpath($this->getFixturesDir()); + $tests = array(); + + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if (!preg_match('/\.test$/', $file)) { + continue; + } + + $test = file_get_contents($file->getRealpath()); + + if (preg_match('/ + --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) { + $message = $match[1]; + $condition = $match[2]; + $templates = $this->parseTemplates($match[3]); + $exception = $match[5]; + $outputs = array(array(null, $match[4], null, '')); + } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) { + $message = $match[1]; + $condition = $match[2]; + $templates = $this->parseTemplates($match[3]); + $exception = false; + preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER); + } else { + throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file))); + } + + $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs); + } + + return $tests; + } + + protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs) + { + if ($condition) { + eval('$ret = '.$condition.';'); + if (!$ret) { + $this->markTestSkipped($condition); + } + } + + $loader = new Twig_Loader_Array($templates); + + foreach ($outputs as $match) { + $config = array_merge(array( + 'cache' => false, + 'strict_variables' => true, + ), $match[2] ? eval($match[2].';') : array()); + $twig = new Twig_Environment($loader, $config); + $twig->addGlobal('global', 'global'); + foreach ($this->getExtensions() as $extension) { + $twig->addExtension($extension); + } + + try { + $template = $twig->loadTemplate('index.twig'); + } catch (Exception $e) { + if (false !== $exception) { + $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage()))); + + return; + } + + if ($e instanceof Twig_Error_Syntax) { + $e->setTemplateFile($file); + + throw $e; + } + + throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); + } + + try { + $output = trim($template->render(eval($match[1].';')), "\n "); + } catch (Exception $e) { + if (false !== $exception) { + $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage()))); + + return; + } + + if ($e instanceof Twig_Error_Syntax) { + $e->setTemplateFile($file); + } else { + $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); + } + + $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage())); + } + + if (false !== $exception) { + list($class, ) = explode(':', $exception); + $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class)); + } + + $expected = trim($match[3], "\n "); + + if ($expected != $output) { + echo 'Compiled template that failed:'; + + foreach (array_keys($templates) as $name) { + echo "Template: $name\n"; + $source = $loader->getSource($name); + echo $twig->compile($twig->parse($twig->tokenize($source, $name))); + } + } + $this->assertEquals($expected, $output, $message.' (in '.$file.')'); + } + } + + protected static function parseTemplates($test) + { + $templates = array(); + preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2]; + } + + return $templates; + } +} diff --git a/inc/lib/Twig/Test/Method.php b/inc/lib/Twig/Test/Method.php index a3b39483..17c6c041 100644 --- a/inc/lib/Twig/Test/Method.php +++ b/inc/lib/Twig/Test/Method.php @@ -12,15 +12,20 @@ /** * Represents a method template test. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ -class Twig_Test_Method implements Twig_TestInterface +class Twig_Test_Method extends Twig_Test { - protected $extension, $method; + protected $extension; + protected $method; - public function __construct(Twig_ExtensionInterface $extension, $method) + public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array()) { + $options['callable'] = array($extension, $method); + + parent::__construct($options); + $this->extension = $extension; $this->method = $method; } diff --git a/inc/lib/Twig/Test/Node.php b/inc/lib/Twig/Test/Node.php new file mode 100644 index 00000000..c832a57b --- /dev/null +++ b/inc/lib/Twig/Test/Node.php @@ -0,0 +1,37 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +class Twig_Test_Node extends Twig_Test +{ + protected $class; + + public function __construct($class, array $options = array()) + { + parent::__construct($options); + + $this->class = $class; + } + + public function getClass() + { + return $this->class; + } + + public function compile() + { + } +} diff --git a/inc/lib/Twig/Test/NodeTestCase.php b/inc/lib/Twig/Test/NodeTestCase.php new file mode 100644 index 00000000..b15c85ff --- /dev/null +++ b/inc/lib/Twig/Test/NodeTestCase.php @@ -0,0 +1,58 @@ +assertNodeCompilation($source, $node, $environment); + } + + public function assertNodeCompilation($source, Twig_Node $node, Twig_Environment $environment = null) + { + $compiler = $this->getCompiler($environment); + $compiler->compile($node); + + $this->assertEquals($source, trim($compiler->getSource())); + } + + protected function getCompiler(Twig_Environment $environment = null) + { + return new Twig_Compiler(null === $environment ? $this->getEnvironment() : $environment); + } + + protected function getEnvironment() + { + return new Twig_Environment(); + } + + protected function getVariableGetter($name) + { + if (version_compare(phpversion(), '5.4.0RC1', '>=')) { + return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name); + } + + return sprintf('$this->getContext($context, "%s")', $name); + } + + protected function getAttributeGetter() + { + if (function_exists('twig_template_get_attributes')) { + return 'twig_template_get_attributes($this, '; + } + + return '$this->getAttribute('; + } +} diff --git a/inc/lib/Twig/TestCallableInterface.php b/inc/lib/Twig/TestCallableInterface.php new file mode 100644 index 00000000..0db43682 --- /dev/null +++ b/inc/lib/Twig/TestCallableInterface.php @@ -0,0 +1,21 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_TestCallableInterface +{ + public function getCallable(); +} diff --git a/inc/lib/Twig/TestInterface.php b/inc/lib/Twig/TestInterface.php index c2ff7258..30d8a2c4 100644 --- a/inc/lib/Twig/TestInterface.php +++ b/inc/lib/Twig/TestInterface.php @@ -12,8 +12,8 @@ /** * Represents a template test. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TestInterface { @@ -22,5 +22,5 @@ interface Twig_TestInterface * * @return string The PHP code for the test */ - function compile(); + public function compile(); } diff --git a/inc/lib/Twig/Token.php b/inc/lib/Twig/Token.php index 79a10030..bbca90db 100644 --- a/inc/lib/Twig/Token.php +++ b/inc/lib/Twig/Token.php @@ -13,8 +13,7 @@ /** * Represents a Token. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Token { @@ -22,17 +21,19 @@ class Twig_Token protected $type; protected $lineno; - const EOF_TYPE = -1; - const TEXT_TYPE = 0; - const BLOCK_START_TYPE = 1; - const VAR_START_TYPE = 2; - const BLOCK_END_TYPE = 3; - const VAR_END_TYPE = 4; - const NAME_TYPE = 5; - const NUMBER_TYPE = 6; - const STRING_TYPE = 7; - const OPERATOR_TYPE = 8; - const PUNCTUATION_TYPE = 9; + const EOF_TYPE = -1; + const TEXT_TYPE = 0; + const BLOCK_START_TYPE = 1; + const VAR_START_TYPE = 2; + const BLOCK_END_TYPE = 3; + const VAR_END_TYPE = 4; + const NAME_TYPE = 5; + const NUMBER_TYPE = 6; + const STRING_TYPE = 7; + const OPERATOR_TYPE = 8; + const PUNCTUATION_TYPE = 9; + const INTERPOLATION_START_TYPE = 10; + const INTERPOLATION_END_TYPE = 11; /** * Constructor. @@ -120,10 +121,11 @@ class Twig_Token * * @param integer $type The type as an integer * @param Boolean $short Whether to return a short representation or not + * @param integer $line The code line * * @return string The string representation */ - static public function typeToString($type, $short = false, $line = -1) + public static function typeToString($type, $short = false, $line = -1) { switch ($type) { case self::EOF_TYPE: @@ -159,8 +161,14 @@ class Twig_Token case self::PUNCTUATION_TYPE: $name = 'PUNCTUATION_TYPE'; break; + case self::INTERPOLATION_START_TYPE: + $name = 'INTERPOLATION_START_TYPE'; + break; + case self::INTERPOLATION_END_TYPE: + $name = 'INTERPOLATION_END_TYPE'; + break; default: - throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line); + throw new LogicException(sprintf('Token of type "%s" does not exist.', $type)); } return $short ? $name : 'Twig_Token::'.$name; @@ -169,12 +177,12 @@ class Twig_Token /** * Returns the english representation of a given type. * - * @param integer $type The type as an integer - * @param Boolean $short Whether to return a short representation or not + * @param integer $type The type as an integer + * @param integer $line The code line * * @return string The string representation */ - static public function typeToEnglish($type, $line = -1) + public static function typeToEnglish($type, $line = -1) { switch ($type) { case self::EOF_TYPE: @@ -199,8 +207,12 @@ class Twig_Token return 'operator'; case self::PUNCTUATION_TYPE: return 'punctuation'; + case self::INTERPOLATION_START_TYPE: + return 'begin of string interpolation'; + case self::INTERPOLATION_END_TYPE: + return 'end of string interpolation'; default: - throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line); + throw new LogicException(sprintf('Token of type "%s" does not exist.', $type)); } } } diff --git a/inc/lib/Twig/TokenParser.php b/inc/lib/Twig/TokenParser.php index 6c9e6935..decebd5e 100644 --- a/inc/lib/Twig/TokenParser.php +++ b/inc/lib/Twig/TokenParser.php @@ -12,11 +12,13 @@ /** * Base class for all token parsers. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ abstract class Twig_TokenParser implements Twig_TokenParserInterface { + /** + * @var Twig_Parser + */ protected $parser; /** diff --git a/inc/lib/Twig/TokenParser/AutoEscape.php b/inc/lib/Twig/TokenParser/AutoEscape.php index 3b4b96e3..27560288 100644 --- a/inc/lib/Twig/TokenParser/AutoEscape.php +++ b/inc/lib/Twig/TokenParser/AutoEscape.php @@ -39,23 +39,35 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser public function parse(Twig_Token $token) { $lineno = $token->getLine(); - $value = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); - if (!in_array($value, array('true', 'false'))) { - throw new Twig_Error_Syntax("Autoescape value must be 'true' or 'false'", $lineno); - } - $value = 'true' === $value ? 'html' : false; + $stream = $this->parser->getStream(); - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) { - if (false === $value) { - throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $lineno); + if ($stream->test(Twig_Token::BLOCK_END_TYPE)) { + $value = 'html'; + } else { + $expr = $this->parser->getExpressionParser()->parseExpression(); + if (!$expr instanceof Twig_Node_Expression_Constant) { + throw new Twig_Error_Syntax('An escaping strategy must be a string or a Boolean.', $stream->getCurrent()->getLine(), $stream->getFilename()); + } + $value = $expr->getAttribute('value'); + + $compat = true === $value || false === $value; + + if (true === $value) { + $value = 'html'; } - $value = $this->parser->getStream()->next()->getValue(); + if ($compat && $stream->test(Twig_Token::NAME_TYPE)) { + if (false === $value) { + throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename()); + } + + $value = $stream->next()->getValue(); + } } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag()); } @@ -68,7 +80,7 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Block.php b/inc/lib/Twig/TokenParser/Block.php index b31f7ed6..a2e017f3 100644 --- a/inc/lib/Twig/TokenParser/Block.php +++ b/inc/lib/Twig/TokenParser/Block.php @@ -35,8 +35,9 @@ class Twig_TokenParser_Block extends Twig_TokenParser $stream = $this->parser->getStream(); $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); if ($this->parser->hasBlock($name)) { - throw new Twig_Error_Syntax("The block '$name' has already been defined", $lineno); + throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename()); } + $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); $this->parser->pushLocalScope(); $this->parser->pushBlockStack($name); @@ -48,7 +49,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser $value = $stream->next()->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno); + throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); } } } else { @@ -58,8 +59,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser } $stream->expect(Twig_Token::BLOCK_END_TYPE); - $block = new Twig_Node_Block($name, $body, $lineno); - $this->parser->setBlock($name, $block); + $block->setNode('body', $body); $this->parser->popBlockStack(); $this->parser->popLocalScope(); @@ -74,7 +74,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Do.php b/inc/lib/Twig/TokenParser/Do.php new file mode 100644 index 00000000..f50939dd --- /dev/null +++ b/inc/lib/Twig/TokenParser/Do.php @@ -0,0 +1,42 @@ +parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_Do($expr, $token->getLine(), $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'do'; + } +} diff --git a/inc/lib/Twig/TokenParser/Embed.php b/inc/lib/Twig/TokenParser/Embed.php new file mode 100644 index 00000000..69cb5f35 --- /dev/null +++ b/inc/lib/Twig/TokenParser/Embed.php @@ -0,0 +1,66 @@ +parser->getStream(); + + $parent = $this->parser->getExpressionParser()->parseExpression(); + + list($variables, $only, $ignoreMissing) = $this->parseArguments(); + + // inject a fake parent to make the parent() function work + $stream->injectTokens(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()), + new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()), + new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()), + new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()), + )); + + $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true); + + // override the parent with the correct one + $module->setNode('parent', $parent); + + $this->parser->embedTemplate($module); + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + } + + public function decideBlockEnd(Twig_Token $token) + { + return $token->test('endembed'); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'embed'; + } +} diff --git a/inc/lib/Twig/TokenParser/Extends.php b/inc/lib/Twig/TokenParser/Extends.php index 67eacda0..f5ecee21 100644 --- a/inc/lib/Twig/TokenParser/Extends.php +++ b/inc/lib/Twig/TokenParser/Extends.php @@ -29,23 +29,21 @@ class Twig_TokenParser_Extends extends Twig_TokenParser public function parse(Twig_Token $token) { if (!$this->parser->isMainScope()) { - throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine()); + throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine(), $this->parser->getFilename()); } if (null !== $this->parser->getParent()) { - throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine()); + throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine(), $this->parser->getFilename()); } $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - - return null; } /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Filter.php b/inc/lib/Twig/TokenParser/Filter.php index 0969ab1e..2b97475a 100644 --- a/inc/lib/Twig/TokenParser/Filter.php +++ b/inc/lib/Twig/TokenParser/Filter.php @@ -52,7 +52,7 @@ class Twig_TokenParser_Filter extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Flush.php b/inc/lib/Twig/TokenParser/Flush.php new file mode 100644 index 00000000..4e15e785 --- /dev/null +++ b/inc/lib/Twig/TokenParser/Flush.php @@ -0,0 +1,42 @@ +parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_Flush($token->getLine(), $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag() + { + return 'flush'; + } +} diff --git a/inc/lib/Twig/TokenParser/For.php b/inc/lib/Twig/TokenParser/For.php index 5ce82979..98a6d079 100644 --- a/inc/lib/Twig/TokenParser/For.php +++ b/inc/lib/Twig/TokenParser/For.php @@ -33,32 +33,41 @@ class Twig_TokenParser_For extends Twig_TokenParser public function parse(Twig_Token $token) { $lineno = $token->getLine(); + $stream = $this->parser->getStream(); $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); - $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in'); + $stream->expect(Twig_Token::OPERATOR_TYPE, 'in'); $seq = $this->parser->getExpressionParser()->parseExpression(); $ifexpr = null; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) { - $this->parser->getStream()->next(); + if ($stream->test(Twig_Token::NAME_TYPE, 'if')) { + $stream->next(); $ifexpr = $this->parser->getExpressionParser()->parseExpression(); } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideForFork')); - if ($this->parser->getStream()->next()->getValue() == 'else') { - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + if ($stream->next()->getValue() == 'else') { + $stream->expect(Twig_Token::BLOCK_END_TYPE); $else = $this->parser->subparse(array($this, 'decideForEnd'), true); } else { $else = null; } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); if (count($targets) > 1) { $keyTarget = $targets->getNode(0); + $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine()); $valueTarget = $targets->getNode(1); + $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); } else { $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno); $valueTarget = $targets->getNode(0); + $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); + } + + if ($ifexpr) { + $this->checkLoopUsageCondition($stream, $ifexpr); + $this->checkLoopUsageBody($stream, $body); } return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag()); @@ -74,10 +83,51 @@ class Twig_TokenParser_For extends Twig_TokenParser return $token->test('endfor'); } + // the loop variable cannot be used in the condition + protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node) + { + if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { + throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename()); + } + + foreach ($node as $n) { + if (!$n) { + continue; + } + + $this->checkLoopUsageCondition($stream, $n); + } + } + + // check usage of non-defined loop-items + // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include) + protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node) + { + if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { + $attribute = $node->getNode('attribute'); + if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { + throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); + } + } + + // should check for parent.loop.XXX usage + if ($node instanceof Twig_Node_For) { + return; + } + + foreach ($node as $n) { + if (!$n) { + continue; + } + + $this->checkLoopUsageBody($stream, $n); + } + } + /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/From.php b/inc/lib/Twig/TokenParser/From.php index 87aceb4d..a54054db 100644 --- a/inc/lib/Twig/TokenParser/From.php +++ b/inc/lib/Twig/TokenParser/From.php @@ -55,8 +55,8 @@ class Twig_TokenParser_From extends Twig_TokenParser $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag()); - foreach($targets as $name => $alias) { - $this->parser->addImportedFunction($alias, $name, $node->getNode('var')); + foreach ($targets as $name => $alias) { + $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); } return $node; @@ -65,7 +65,7 @@ class Twig_TokenParser_From extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/If.php b/inc/lib/Twig/TokenParser/If.php index 65a1a8b2..3d7d1f51 100644 --- a/inc/lib/Twig/TokenParser/If.php +++ b/inc/lib/Twig/TokenParser/If.php @@ -36,22 +36,23 @@ class Twig_TokenParser_If extends Twig_TokenParser { $lineno = $token->getLine(); $expr = $this->parser->getExpressionParser()->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream = $this->parser->getStream(); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideIfFork')); $tests = array($expr, $body); $else = null; $end = false; while (!$end) { - switch ($this->parser->getStream()->next()->getValue()) { + switch ($stream->next()->getValue()) { case 'else': - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $else = $this->parser->subparse(array($this, 'decideIfEnd')); break; case 'elseif': $expr = $this->parser->getExpressionParser()->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideIfFork')); $tests[] = $expr; $tests[] = $body; @@ -62,11 +63,11 @@ class Twig_TokenParser_If extends Twig_TokenParser break; default: - throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), -1); + throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename()); } } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag()); } @@ -84,7 +85,7 @@ class Twig_TokenParser_If extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Import.php b/inc/lib/Twig/TokenParser/Import.php index d0a88cde..e7050c70 100644 --- a/inc/lib/Twig/TokenParser/Import.php +++ b/inc/lib/Twig/TokenParser/Import.php @@ -32,13 +32,15 @@ class Twig_TokenParser_Import extends Twig_TokenParser $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine()); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $this->parser->addImportedSymbol('template', $var->getAttribute('name')); + return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag()); } /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Include.php b/inc/lib/Twig/TokenParser/Include.php index 54154559..4a317868 100644 --- a/inc/lib/Twig/TokenParser/Include.php +++ b/inc/lib/Twig/TokenParser/Include.php @@ -32,37 +32,46 @@ class Twig_TokenParser_Include extends Twig_TokenParser { $expr = $this->parser->getExpressionParser()->parseExpression(); + list($variables, $only, $ignoreMissing) = $this->parseArguments(); + + return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + } + + protected function parseArguments() + { + $stream = $this->parser->getStream(); + $ignoreMissing = false; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'ignore')) { - $this->parser->getStream()->next(); - $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, 'missing'); + if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { + $stream->next(); + $stream->expect(Twig_Token::NAME_TYPE, 'missing'); $ignoreMissing = true; } $variables = null; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'with')) { - $this->parser->getStream()->next(); + if ($stream->test(Twig_Token::NAME_TYPE, 'with')) { + $stream->next(); $variables = $this->parser->getExpressionParser()->parseExpression(); } $only = false; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'only')) { - $this->parser->getStream()->next(); + if ($stream->test(Twig_Token::NAME_TYPE, 'only')) { + $stream->next(); $only = true; } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + return array($variables, $only, $ignoreMissing); } /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Macro.php b/inc/lib/Twig/TokenParser/Macro.php index da1ac55c..82b4fa6d 100644 --- a/inc/lib/Twig/TokenParser/Macro.php +++ b/inc/lib/Twig/TokenParser/Macro.php @@ -30,26 +30,25 @@ class Twig_TokenParser_Macro extends Twig_TokenParser public function parse(Twig_Token $token) { $lineno = $token->getLine(); - $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); + $stream = $this->parser->getStream(); + $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); - $arguments = $this->parser->getExpressionParser()->parseArguments(); + $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $this->parser->pushLocalScope(); $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) { - $value = $this->parser->getStream()->next()->getValue(); + if ($stream->test(Twig_Token::NAME_TYPE)) { + $value = $stream->next()->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $lineno); + throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename()); } } $this->parser->popLocalScope(); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); - $this->parser->setMacro($name, new Twig_Node_Macro($name, $body, $arguments, $lineno, $this->getTag())); - - return null; + $this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag())); } public function decideBlockEnd(Twig_Token $token) @@ -60,7 +59,7 @@ class Twig_TokenParser_Macro extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Sandbox.php b/inc/lib/Twig/TokenParser/Sandbox.php index 62e7f8f7..9457325a 100644 --- a/inc/lib/Twig/TokenParser/Sandbox.php +++ b/inc/lib/Twig/TokenParser/Sandbox.php @@ -35,6 +35,19 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + // in a sandbox tag, only include tags are allowed + if (!$body instanceof Twig_Node_Include) { + foreach ($body as $node) { + if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) { + continue; + } + + if (!$node instanceof Twig_Node_Include) { + throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $node->getLine(), $this->parser->getFilename()); + } + } + } + return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag()); } @@ -46,7 +59,7 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Set.php b/inc/lib/Twig/TokenParser/Set.php index 489e1d30..70e0b41b 100644 --- a/inc/lib/Twig/TokenParser/Set.php +++ b/inc/lib/Twig/TokenParser/Set.php @@ -49,13 +49,13 @@ class Twig_TokenParser_Set extends Twig_TokenParser $stream->expect(Twig_Token::BLOCK_END_TYPE); if (count($names) !== count($values)) { - throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignements.", $lineno); + throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignments.", $stream->getCurrent()->getLine(), $stream->getFilename()); } } else { $capture = true; if (count($names) > 1) { - throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $lineno); + throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename()); } $stream->expect(Twig_Token::BLOCK_END_TYPE); @@ -75,7 +75,7 @@ class Twig_TokenParser_Set extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Spaceless.php b/inc/lib/Twig/TokenParser/Spaceless.php index aa7ffbc4..1e3fa8f3 100644 --- a/inc/lib/Twig/TokenParser/Spaceless.php +++ b/inc/lib/Twig/TokenParser/Spaceless.php @@ -50,7 +50,7 @@ class Twig_TokenParser_Spaceless extends Twig_TokenParser /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParser/Use.php b/inc/lib/Twig/TokenParser/Use.php index 16c47e3e..bc0e09ef 100644 --- a/inc/lib/Twig/TokenParser/Use.php +++ b/inc/lib/Twig/TokenParser/Use.php @@ -35,13 +35,12 @@ class Twig_TokenParser_Use extends Twig_TokenParser public function parse(Twig_Token $token) { $template = $this->parser->getExpressionParser()->parseExpression(); + $stream = $this->parser->getStream(); if (!$template instanceof Twig_Node_Expression_Constant) { - throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $token->getLine()); + throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename()); } - $stream = $this->parser->getStream(); - $targets = array(); if ($stream->test('with')) { $stream->next(); @@ -69,14 +68,12 @@ class Twig_TokenParser_Use extends Twig_TokenParser $stream->expect(Twig_Token::BLOCK_END_TYPE); $this->parser->addTrait(new Twig_Node(array('template' => $template, 'targets' => new Twig_Node($targets)))); - - return null; } /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ public function getTag() { diff --git a/inc/lib/Twig/TokenParserBroker.php b/inc/lib/Twig/TokenParserBroker.php index 34fcdfbf..ec3fba67 100644 --- a/inc/lib/Twig/TokenParserBroker.php +++ b/inc/lib/Twig/TokenParserBroker.php @@ -13,8 +13,8 @@ /** * Default implementation of a token parser broker. * - * @package twig - * @author Arnaud Le Blanc + * @author Arnaud Le Blanc + * @deprecated since 1.12 (to be removed in 2.0) */ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface { @@ -32,13 +32,13 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface { foreach ($parsers as $parser) { if (!$parser instanceof Twig_TokenParserInterface) { - throw new Twig_Error('$parsers must a an array of Twig_TokenParserInterface'); + throw new LogicException('$parsers must a an array of Twig_TokenParserInterface'); } $this->parsers[$parser->getTag()] = $parser; } foreach ($brokers as $broker) { if (!$broker instanceof Twig_TokenParserBrokerInterface) { - throw new Twig_Error('$brokers must a an array of Twig_TokenParserBrokerInterface'); + throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface'); } $this->brokers[] = $broker; } @@ -54,6 +54,19 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface $this->parsers[$parser->getTag()] = $parser; } + /** + * Removes a TokenParser. + * + * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance + */ + public function removeTokenParser(Twig_TokenParserInterface $parser) + { + $name = $parser->getTag(); + if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) { + unset($this->parsers[$name]); + } + } + /** * Adds a TokenParserBroker. * @@ -64,6 +77,18 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface $this->brokers[] = $broker; } + /** + * Removes a TokenParserBroker. + * + * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance + */ + public function removeTokenParserBroker(Twig_TokenParserBroker $broker) + { + if (false !== $pos = array_search($broker, $this->brokers)) { + unset($this->brokers[$pos]); + } + } + /** * Gets a suitable TokenParser for a tag. * @@ -86,7 +111,11 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface } $broker = prev($this->brokers); } - return null; + } + + public function getParsers() + { + return $this->parsers; } public function getParser() diff --git a/inc/lib/Twig/TokenParserBrokerInterface.php b/inc/lib/Twig/TokenParserBrokerInterface.php index 3ce8ca26..3f006e33 100644 --- a/inc/lib/Twig/TokenParserBrokerInterface.php +++ b/inc/lib/Twig/TokenParserBrokerInterface.php @@ -15,31 +15,31 @@ * * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name. * - * @package twig - * @author Arnaud Le Blanc + * @author Arnaud Le Blanc + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_TokenParserBrokerInterface { /** * Gets a TokenParser suitable for a tag. * - * @param string $tag A tag name + * @param string $tag A tag name * * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found */ - function getTokenParser($tag); + public function getTokenParser($tag); /** * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of. * * @param Twig_ParserInterface $parser A Twig_ParserInterface interface */ - function setParser(Twig_ParserInterface $parser); + public function setParser(Twig_ParserInterface $parser); /** * Gets the Twig_ParserInterface. * - * @return null|Twig_ParserInterface A Twig_ParserInterface instance of null + * @return null|Twig_ParserInterface A Twig_ParserInterface instance or null */ - function getParser(); + public function getParser(); } diff --git a/inc/lib/Twig/TokenParserInterface.php b/inc/lib/Twig/TokenParserInterface.php index 114a939e..bbde7714 100644 --- a/inc/lib/Twig/TokenParserInterface.php +++ b/inc/lib/Twig/TokenParserInterface.php @@ -12,8 +12,7 @@ /** * Interface implemented by token parsers. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ interface Twig_TokenParserInterface { @@ -22,7 +21,7 @@ interface Twig_TokenParserInterface * * @param $parser A Twig_Parser instance */ - function setParser(Twig_Parser $parser); + public function setParser(Twig_Parser $parser); /** * Parses a token and returns a node. @@ -31,12 +30,12 @@ interface Twig_TokenParserInterface * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - function parse(Twig_Token $token); + public function parse(Twig_Token $token); /** * Gets the tag name associated with this token parser. * - * @param string The tag name + * @return string The tag name */ - function getTag(); + public function getTag(); } diff --git a/inc/lib/Twig/TokenStream.php b/inc/lib/Twig/TokenStream.php index a2002b42..a78189f6 100644 --- a/inc/lib/Twig/TokenStream.php +++ b/inc/lib/Twig/TokenStream.php @@ -13,8 +13,7 @@ /** * Represents a token stream. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_TokenStream { @@ -45,6 +44,11 @@ class Twig_TokenStream return implode("\n", $this->tokens); } + public function injectTokens(array $tokens) + { + $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current)); + } + /** * Sets the pointer to the next token and returns the old one. * @@ -53,7 +57,7 @@ class Twig_TokenStream public function next() { if (!isset($this->tokens[++$this->current])) { - throw new Twig_Error_Syntax('Unexpected end of template', -1, $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current - 1]->getLine(), $this->filename); } return $this->tokens[$this->current - 1]; @@ -92,7 +96,7 @@ class Twig_TokenStream public function look($number = 1) { if (!isset($this->tokens[$this->current + $number])) { - throw new Twig_Error_Syntax('Unexpected end of template', -1, $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename); } return $this->tokens[$this->current + $number]; From 6b6f32949df7be58c7a9125711aeab2c34cd1d54 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 15:20:25 -0400 Subject: [PATCH 197/289] 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' %} From 157dcf9fb13f83d3d7ec8e2ab6cd566e92efea97 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 15:55:28 -0400 Subject: [PATCH 198/289] Continue upgrading Twig --- inc/lib/Twig/Extensions/Extension/I18n.php | 2 +- .../Twig/Extensions/Extension/Tinyboard.php | 46 +++++++++---------- inc/lib/Twig/Extensions/Node/Trans.php | 11 +++-- inc/lib/Twig/Extensions/TokenParser/Trans.php | 6 +-- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/inc/lib/Twig/Extensions/Extension/I18n.php b/inc/lib/Twig/Extensions/Extension/I18n.php index 1f795490..bc6a05bd 100644 --- a/inc/lib/Twig/Extensions/Extension/I18n.php +++ b/inc/lib/Twig/Extensions/Extension/I18n.php @@ -28,7 +28,7 @@ class Twig_Extensions_Extension_I18n extends Twig_Extension public function getFilters() { return array( - 'trans' => new Twig_Filter_Function('gettext'), + new Twig_SimpleFilter('trans', 'gettext'), ); } diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 8c8d9456..727d5d2c 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -9,23 +9,23 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension */ public function getFilters() { - return Array( - 'filesize' => new Twig_Filter_Function('format_bytes'), - 'truncate' => new Twig_Filter_Function('twig_truncate_filter'), - 'truncate_body' => new Twig_Filter_Function('truncate'), - 'extension' => new Twig_Filter_Function('twig_extension_filter'), - 'sprintf' => new Twig_Filter_Function('sprintf'), - 'capcode' => new Twig_Filter_Function('capcode'), - 'hasPermission' => new Twig_Filter_Function('twig_hasPermission_filter'), - 'date' => new Twig_Filter_Function('twig_date_filter'), - 'poster_id' => new Twig_Filter_Function('poster_id'), - 'remove_whitespace' => new Twig_Filter_Function('twig_remove_whitespace_filter'), - 'count' => new Twig_Filter_Function('count'), - 'ago' => new Twig_Filter_Function('ago'), - 'until' => new Twig_Filter_Function('until'), - 'push' => new Twig_Filter_Function('twig_push_filter'), - 'bidi_cleanup' => new Twig_Filter_Function('bidi_cleanup'), - 'addslashes' => new Twig_Filter_Function('addslashes') + return array( + new Twig_SimpleFilter('filesize', 'format_bytes'), + new Twig_SimpleFilter('truncate', 'twig_truncate_filter'), + new Twig_SimpleFilter('truncate_body', 'truncate'), + new Twig_SimpleFilter('extension', 'twig_extension_filter'), + new Twig_SimpleFilter('sprintf', 'sprintf'), + new Twig_SimpleFilter('capcode', 'capcode'), + new Twig_SimpleFilter('hasPermission', 'twig_hasPermission_filter'), + new Twig_SimpleFilter('date', 'twig_date_filter'), + new Twig_SimpleFilter('poster_id', 'poster_id'), + new Twig_SimpleFilter('remove_whitespace', 'twig_remove_whitespace_filter'), + new Twig_SimpleFilter('count', 'count'), + new Twig_SimpleFilter('ago', 'ago'), + new Twig_SimpleFilter('until', 'until'), + new Twig_SimpleFilter('push', 'twig_push_filter'), + new Twig_SimpleFilter('bidi_cleanup', 'bidi_cleanup'), + new Twig_SimpleFilter('addslashes', 'addslashes') ); } @@ -36,12 +36,12 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension */ public function getFunctions() { - return Array( - 'time' => new Twig_Filter_Function('time'), - 'floor' => new Twig_Filter_Function('floor'), - 'timezone' => new Twig_Filter_Function('twig_timezone_function'), - 'hiddenInputs' => new Twig_Filter_Function('hiddenInputs'), - 'hiddenInputsHash' => new Twig_Filter_Function('hiddenInputsHash'), + return array( + new Twig_SimpleFunction('time', 'time'), + new Twig_SimpleFunction('floor', 'floor'), + new Twig_SimpleFunction('timezone', 'twig_timezone_function'), + new Twig_SimpleFunction('hiddenInputs', 'hiddenInputs'), + new Twig_SimpleFunction('hiddenInputsHash', 'hiddenInputsHash'), ); } diff --git a/inc/lib/Twig/Extensions/Node/Trans.php b/inc/lib/Twig/Extensions/Node/Trans.php index 18087e77..e7dc1ca8 100644 --- a/inc/lib/Twig/Extensions/Node/Trans.php +++ b/inc/lib/Twig/Extensions/Node/Trans.php @@ -94,22 +94,25 @@ class Twig_Extensions_Node_Trans extends Twig_Node ; } - $compiler->raw(');'); + $compiler->raw(");\n"); } } protected function compileString(Twig_NodeInterface $body) { - if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant) { + if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) { return array($body, array()); } $vars = array(); - if (count($body)) { $msg = ''; foreach ($body as $node) { + if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) { + $node = $node->getNode(1); + } + if ($node instanceof Twig_Node_Print) { $n = $node->getNode('expr'); while ($n instanceof Twig_Node_Expression_Filter) { @@ -127,4 +130,4 @@ class Twig_Extensions_Node_Trans extends Twig_Node return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getLine()))), $vars); } -} +} \ No newline at end of file diff --git a/inc/lib/Twig/Extensions/TokenParser/Trans.php b/inc/lib/Twig/Extensions/TokenParser/Trans.php index 5b2d93b6..4a0fad41 100644 --- a/inc/lib/Twig/Extensions/TokenParser/Trans.php +++ b/inc/lib/Twig/Extensions/TokenParser/Trans.php @@ -43,12 +43,12 @@ class Twig_Extensions_TokenParser_Trans extends Twig_TokenParser return new Twig_Extensions_Node_Trans($body, $plural, $count, $lineno, $this->getTag()); } - public function decideForFork($token) + public function decideForFork(Twig_Token $token) { return $token->test(array('plural', 'endtrans')); } - public function decideForEnd($token) + public function decideForEnd(Twig_Token $token) { return $token->test('endtrans'); } @@ -77,4 +77,4 @@ class Twig_Extensions_TokenParser_Trans extends Twig_TokenParser throw new Twig_Error_Syntax(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno); } } -} +} \ No newline at end of file From 5a44c50811ba9a927add4d54604307692492df8a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 17:18:10 -0400 Subject: [PATCH 199/289] 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 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) %}
      {% endif %} - {% if mod|hasPermission(config.mod.show_config) %} + {% if mod|hasPermission(config.mod.edit_config) %}
    1. {% trans 'Configuration' %}
    2. {% 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 %} - + From cf0a20a5645e1e82a48ad00f9381813af3b4e658 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 19:21:15 -0400 Subject: [PATCH 200/289] js/style-select.js: Changes the stylesheet chooser links to a + * + * Released under the MIT license + * Copyright (c) 2013 Michael Save + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/style-select.js'; + * + */ + +onready(function(){ + var stylesDiv = $('div.styles'); + var stylesSelect = $(''); + + var i = 1; + stylesDiv.children().each(function() { + stylesSelect.append( + $('') + .text(this.innerText.replace(/(^\[|\]$)/g, '')) + .val(i) + ); + $(this).attr('id', 'style-select-' + i); + i++; + }); + + stylesSelect.change(function() { + $('#style-select-' + $(this).val()).click(); + }); + + stylesDiv.hide(); + + stylesDiv.after( + $('
      ') + .text(_('Style: ')) + .append(stylesSelect) + ); +}); + From 2fd60c6d2599d991c8d05ad101844ea840bc1528 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 19:26:09 -0400 Subject: [PATCH 201/289] Select chosen stylesheet on load --- js/style-select.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/js/style-select.js b/js/style-select.js index ac17c7ce..33c1308b 100644 --- a/js/style-select.js +++ b/js/style-select.js @@ -19,11 +19,12 @@ onready(function(){ var i = 1; stylesDiv.children().each(function() { - stylesSelect.append( - $('') - .text(this.innerText.replace(/(^\[|\]$)/g, '')) - .val(i) - ); + var opt = $('') + .text(this.innerText.replace(/(^\[|\]$)/g, '')) + .val(i); + if ($(this).hasClass('selected')) + opt.attr('selected', true); + stylesSelect.append(opt); $(this).attr('id', 'style-select-' + i); i++; }); From 6c4103737797f1573070c7b00af3dfcbb5b96367 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 19:44:22 -0400 Subject: [PATCH 202/289] Add two stylesheets --- stylesheets/ferus.css | 155 ++++++++++++++++++++++++ stylesheets/ricechan.css | 249 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 404 insertions(+) create mode 100644 stylesheets/ferus.css create mode 100644 stylesheets/ricechan.css diff --git a/stylesheets/ferus.css b/stylesheets/ferus.css new file mode 100644 index 00000000..6a1dfb59 --- /dev/null +++ b/stylesheets/ferus.css @@ -0,0 +1,155 @@ +@font-face { + font-family: Matrix; + src: url(data:application/x-font-tff;base64,AAEAAAAOAIAAAwBgRkZUTTHZQ8IAALw8AAAAHE9TLzKQGR/2AAABaAAAAFZjbWFw5AjWjgAACJAAAAMaY3Z0IA0AJ3gAABNsAAABoGZwZ23UiPsUAAALrAAABRhnbHlm1ZlQ+QAAGJgAAJbMaGVhZOxJsogAAADsAAAANmhoZWEN1gd9AAABJAAAACRobXR4Go/MGQAAAcAAAAbQbG9jYflSH7IAABUMAAADjG1heHADwQX3AAABSAAAACBuYW1lMsi/8gAAr2QAAAKLcG9zdHFsGbAAALHwAAAKSXByZXA+daKoAAAQxAAAAqUAAQAAAAEAAIHcJmpfDzz1AB8IAAAAAADDEDQMAAAAAMMQNAz/9v6WBwAG3QAAAAgAAgAAAAAAAAABAAAG3f6WAAAIAP/2/0MHAAABAAAAAAAAAAAAAAAAAAABowABAAABxQBTAAQAWgAEAAIAEAAvADgAAAGoBRgAAwABAAEETAGQAAUACAWaBTMAAACyBZoFMwAAAeMAfQISCA8CAQUJAgECAQMDgAAArxAAIEgAAAAAAAAAAE1PTk8AQAAA8AMFMf6YAfYG3QFqoAAAk43UAAAAAAgAAQAAAAAABNUAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAfQETADLBEwAzwRMAM0ETADLBEwA0QRMAc8ETAHNBEwBgwRMAOcETADLBEwBdwRMAM8ETAHJBEwA4wRMAMsETADJBEwAxwRMAMkETAD6BEwA4QRMAM8ETADLBEwAyQRMANEETAHNBEwBcQRMAM8ETADLBEwA5QRMAOUETADPBEwAzwRMAMsETADTBEwAywRMAM8ETADPBEwAywRMAMsETADNBEwBIQRMAM0ETADPBEwAywRMAM8ETADNBEwAzwRMAM0ETADRBEwAzQRMAM0ETADNBEwA0QRMAM0ETADbBEwA0QRMAM0ETADPBEwA5QRMAM0ETADfBEz/9gRMAYcETADLBEwA0wRMANAETADJBEwAzQRMAPoETADNBEwAzQRMASEETAEfBEwAzwRMASMETAC6BEwAzwRMAM0ETADPBEwAzwRMAM8ETADNBEwAzQRMANIETADNBEwAuARMANsETADNBEwAzwRMANEETAIXBEwA0QRMAPYETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwB9ARMANAETADHBEwAyQRMAMsETAIXBEwAzQRMAMsETACqBEwAywRMAM8ETADBBEwAzwRMAKoETP/2BEwA9gRMAMEETAGLBEwB3wRMAYcETADRBEwAugRMAckETAF3BEwB3QRMAM0ETADZBEwAFARMABQETAAUBEwAuARMAM8ETADPBEwAzwRMAM8ETADLBEwAzwRMANUETADTBEwAzwRMAM8ETADPBEwAywRMAM0ETADNBEwAzQRMAMsETADLBEwAzwRMAM0ETADNBEwAzQRMAM0ETADLBEwBEARMAN8ETADNBEwAzQRMAM0ETADLBEwA0QRMAM8ETADNBEwAywRMAMsETADLBEwAywRMAMsETADLBEwATARMANAETADNBEwAzQRMAM0ETADLBEwBDARMASEETACRBEwAZARMAM0ETADPBEwAzQRMAM0ETADNBEwAzQRMAMsETADBBEwAzQRMANIETADSBEwA0gRMAMsETADNBEwAzwRMAMsETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwBIQRMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMABkETAEjBEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAzQRMAEwETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETADNBEwAzQRMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETADLBEwAAARMAAAETAAABEwAAARMAM0ETADPBEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMAAAETAAABEwAAARMATsETAAABEwAAATVAO4E1QDuBNUBHQTVAOUE1QIXBNUBrATVAWIE1QD2BNUBOwRMAEwE1QE1AAABYgF3AXcA5QCgAKAAwQDBARkAeQDLAc0B1wBcAM0AzQDRACMAzwDBABQBLwC0AM8A9gDLAM8AyQCwARkAIwAjAYsAAAADAAAAAwAAABwAAQAAAAABEAADAAEAAAAcAAQA9AAAADgAIAAEABgBlALHAskC3QPAIBQgGiAeICIgJiAwIDohIiEmIgIiBiIPIhIiFSIaIh4iKyJIImAiZSXK8AP//wAAAAACxgLJAtgDwCATIBggHCAgICYgMCA5ISIhJiICIgYiDyIRIhUiGSIeIisiSCJgImQlyvAA//8AA/7S/tH+w/3h4Y/hjOGL4Yrhh+F+4Xbgj+CM37Hfrt+m36XfowAA35zfkN90313fWtv2EcEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAALoBuQAGAgoAAAAAAQAAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkAGUAZgBnAGgAaQBqAGsAbABtAG4AbwBwAHEAcgBz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AT8BQAFBAUIBQwFEAUUAowCEAIUAvQCWAOgAhgCOAIsAnQCpAKQBRgCKAUcAgwCTAPIA8wCNAJcAiADDAN4A8QCeAKoA9QD0APYAogCtAMkAxwCuAGIAYwCQAGQAywBlAMgAygDPAMwAzQDOAOkAZgDTANAA0QCvAGcA8ACRANYA1ADVAGgA6wDtAIkAagBpAGsAbQBsAG4AoABvAHEAcAByAHMAdQB0AHYAdwDqAHgAegB5AHsAfQB8ALgAoQB/AH4AgACBAOwA7gC6AUgBSQFKAUsBTAFNAP0A/gFOAU8BUAFRAP8BAAFSAVMBVAEBAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAPgA+QFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAPoA1wFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwDiAOMBgAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4AsACxAY8BkAGRAZIBkwGUAZUBlgGXAZgA+wD8AOQA5QGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGoAakBqgGrAawBrQGuALsBrwGwAbEBsgDmAOcBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQCmAcYBxwDYAOEA2gDbANwA3QDgANkA3wCbALIAswC2ALcAxAC0ALUAxQCCAMIAhwCrAMYAvgC/AIwAnwCYAKgAmgCZAO8AvAClAJIAnACnAI8AlACVALkA0gDAAMEByAZnbHlwaDEGZ2x5cGgyB3VuaTAwMDAHdW5pMDAwMQd1bmkwMDAyB3VuaTAwMDMHdW5pMDAwNAd1bmkwMDA1B3VuaTAwMDYHdW5pMDAwNwd1bmkwMDA4B3VuaTAwMDkHdW5pMDAwQQd1bmkwMDBCB3VuaTAwMEMHdW5pMDAwRAd1bmkwMDBFB3VuaTAwMEYHdW5pMDAxMAd1bmkwMDExB3VuaTAwMTIHdW5pMDAxMwd1bmkwMDE0B3VuaTAwMTUHdW5pMDAxNgd1bmkwMDE3B3VuaTAwMTgHdW5pMDAxOQd1bmkwMDFBB3VuaTAwMUIHdW5pMDAxQwd1bmkwMDFEB3VuaTAwMUUHdW5pMDAxRgd1bmkwMDdGB3VuaTAwODAHdW5pMDA4MQd1bmkwMDgyB3VuaTAwODMHdW5pMDA4NAd1bmkwMDg1B3VuaTAwODYHdW5pMDA4Nwd1bmkwMDg4B3VuaTAwODkHdW5pMDA4QQd1bmkwMDhCB3VuaTAwOEMHdW5pMDA4RAd1bmkwMDhFB3VuaTAwOEYHdW5pMDA5MAd1bmkwMDkxB3VuaTAwOTIHdW5pMDA5Mwd1bmkwMDk0B3VuaTAwOTUHdW5pMDA5Ngd1bmkwMDk3B3VuaTAwOTgHdW5pMDA5OQd1bmkwMDlBB3VuaTAwOUIHdW5pMDA5Qwd1bmkwMDlEB3VuaTAwOUUHdW5pMDA5RgduYnNwYWNlCXNmdGh5cGhlbglvdmVyc2NvcmUHQW1hY3JvbgdhbWFjcm9uBkFicmV2ZQZhYnJldmUHQW9nb25lawdhb2dvbmVrC0NjaXJjdW1mbGV4C2NjaXJjdW1mbGV4CkNkb3RhY2NlbnQKY2RvdGFjY2VudAZEY2Fyb24GZGNhcm9uBkRjcm9hdAdFbWFjcm9uB2VtYWNyb24GRWJyZXZlBmVicmV2ZQpFZG90YWNjZW50CmVkb3RhY2NlbnQHRW9nb25lawdlb2dvbmVrBkVjYXJvbgZlY2Fyb24LR2NpcmN1bWZsZXgLZ2NpcmN1bWZsZXgKR2RvdGFjY2VudApnZG90YWNjZW50DEdjb21tYWFjY2VudAxnY29tbWFhY2NlbnQLSGNpcmN1bWZsZXgLaGNpcmN1bWZsZXgESGJhcgRoYmFyBkl0aWxkZQZpdGlsZGUHSW1hY3JvbgdpbWFjcm9uBklicmV2ZQZpYnJldmUHSW9nb25lawdpb2dvbmVrAklKAmlqC0pjaXJjdW1mbGV4C2pjaXJjdW1mbGV4DEtjb21tYWFjY2VudAxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBkxhY3V0ZQZsYWN1dGUMTGNvbW1hYWNjZW50DGxjb21tYWFjY2VudAZMY2Fyb24GbGNhcm9uBExkb3QEbGRvdAZOYWN1dGUGbmFjdXRlDE5jb21tYWFjY2VudAxuY29tbWFhY2NlbnQGTmNhcm9uBm5jYXJvbgtuYXBvc3Ryb3BoZQNFbmcDZW5nB09tYWNyb24Hb21hY3JvbgZPYnJldmUGb2JyZXZlDU9odW5nYXJ1bWxhdXQNb2h1bmdhcnVtbGF1dAZSYWN1dGUGcmFjdXRlDFJjb21tYWFjY2VudAxyY29tbWFhY2NlbnQGUmNhcm9uBnJjYXJvbgZTYWN1dGUGc2FjdXRlC1NjaXJjdW1mbGV4C3NjaXJjdW1mbGV4DFRjb21tYWFjY2VudAx0Y29tbWFhY2NlbnQGVGNhcm9uBnRjYXJvbgRUYmFyBHRiYXIGVXRpbGRlBnV0aWxkZQdVbWFjcm9uB3VtYWNyb24GVWJyZXZlBnVicmV2ZQVVcmluZwV1cmluZw1VaHVuZ2FydW1sYXV0DXVodW5nYXJ1bWxhdXQHVW9nb25lawd1b2dvbmVrC1djaXJjdW1mbGV4C3djaXJjdW1mbGV4C1ljaXJjdW1mbGV4C3ljaXJjdW1mbGV4BlphY3V0ZQZ6YWN1dGUKWmRvdGFjY2VudAp6ZG90YWNjZW50BWxvbmdzB3VuaTAxODAHdW5pMDE4MQd1bmkwMTgyB3VuaTAxODMHdW5pMDE4NAd1bmkwMTg1B3VuaTAxODYHdW5pMDE4Nwd1bmkwMTg4B3VuaTAxODkHdW5pMDE4QQd1bmkwMThCB3VuaTAxOEMHdW5pMDE4RAd1bmkwMThFB3VuaTAxOEYHdW5pMDE5MAd1bmkwMTkxB3VuaTAxOTMHdW5pMDE5NAxmb3Vyc3VwZXJpb3IAAAAAAAABAAAAAML+SiAAAAAAq8rFpAAAAADDEDP9); +} + +body { + background: #050505; + color: #00FF00; + font-family: Matrix; + font-size: 13.3px; +} +h1 { + font-size: 20pt; + text-align: center; + letter-spacing: 0px; +} +div.title, h1 { + color: #00FF00; + font-family: Arial, Helvetica, sans-serif; +} +div.title p { + font-size: 13px; +} +a:link, a:visited, p.intro a.email span.name { + color: #16C816; + text-decoration: underline; + font-family: Matrix; +} +a:link:hover, a:visited:hover { + color: #003C00; + font-family: Matrix;; + text-decoration: underline overline; +} +a.post_no { + color: #464646; + text-decoration: none; +} +a.post_no:hover { + color: maroon; + text-decoration: underline overline; +} +div.post.reply { + background: #0E0E0E; + border: #414141 2px solid; +} +.de-pview { + background: rgba(14, 14, 14, 0.84) !important; +} +div.post.reply.highlighted { + background: transparent; + border: #414141 2px solid; +} +div.post.reply div.body a:link, div.post.reply div.body a:visited { + color: #646464; +} +div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { + color: #00FF00; +} +p.intro span.subject { + font-size: 12px; + font-family: Matrix; + color: #446655; + font-weight: 800; +} +p.intro span.name { + color: #008200; + font-weight: 900; +} +p.intro a.capcode, p.intro a.nametag { + color: magenta; + margin-left: 0; +} +p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { + color: #00CC64; + font-family: Matrix; +} +input[type="text"], textarea, select { + background: #333333; + color: #CCCCCC; + border: #666666 1px solid; + padding-left: 5px; + padding-right: -5px; + font-family: Matrix; + font-size: 10pt; +} +input[type="password"] { + background: #333333; + color: #8B8B8B; + border: #666666 1px solid; +} +form table tr th { + background: #333333; + color: #828282; + font-weight: 800; + text-align: left; + padding: 0; +} +div.banner { + background: #00AA00; + color: #646464; + text-align: center; + width: 250px; + padding: 4px; + padding-left: 12px; + padding-right: 12px; + margin-left: auto; + margin-right: auto; + font-size: 12px; +} +input[type="submit"] { + background: #333333; + border: #888888 1px solid; + color: #A0A0A0; +} +input[type="submit"]:hover { + background: #555555; + border: #888888 1px solid; + color: #00FF00; +} +p.fileinfo a:hover { + text-decoration: underline; +} +span.trip { + color: #AAAAAA; +} +div.pages { + color: #AAAAAA; + background: #333333; + border: #666666 1px solid; + font-family: sans-serif; + font-size: 10pt; +} +div.pages a.selected { + color: #8C8C8C; +} +hr { + height: 1px; + border: #333333 1px solid; +} +div.boardlist { + color: #999999; +} +div.ban { + background-color: transparent; + border: transparent 0px solid; +} +div.ban h2 { + background: transparent; + color: lime; + font-size: 12px; +} +table.modlog tr th { + background: #00FF00; + color: #AAAAAA; +} \ No newline at end of file diff --git a/stylesheets/ricechan.css b/stylesheets/ricechan.css new file mode 100644 index 00000000..b8549726 --- /dev/null +++ b/stylesheets/ricechan.css @@ -0,0 +1,249 @@ +/* http://userstyles.org/styles/37014/4chan-ricechan-alpha */ + +.rules, +.logo+hr, +.logo+hr+div, +.logo+hr+div+hr, +hr+script+center>a, +hr+script+center+hr, +#recaptcha_logo, +#recaptcha_tagline, +table+br+hr+center>a, +table+br+hr+center+hr, +.postarea>form>div[style]>a[target], +.doubledash {display:none !important} + +* { + border: none !important; + background: none !important; + color: inherit !important; +} +html { + color: #555 !important; + background: #222 !important; +} +#navtop { + position: absolute; + top:0;left:0;right:0; + color: #666 !important; + background: #111 !important; + border-bottom: 1px solid #282828 !important; + text-align: center; + margin: -4px; + padding: 3px; +} +#navtop a { + color: #9f0 !important; +} +hr { + border-bottom: 1px solid rgba(0,0,0,0.5) !important; + border-top: 1px solid rgba(255,255,255,0.1) !important; +} +h1 { + color: #AF2020 !important; +} +a>img { + box-shadow: 0 0 6px #000; + -moz-box-shadow: 0 0 6px #000; + -webkit-box-shadow: 0 0 6px #000; +} +.logo b { + color: #fff !important; +} +div.boardlist a { + text-decoration: none; + color: #615A5A !important; +} +div.boardlist a:hover { + color: #C08E8E !important; +} +.postarea { + color: #fff !important; + position: fixed; + top:0; right:0; +} +.postblock { + color: #999 !important; +} +.postarea form { + padding-left: 12px; + opacity: .1; + width: 0; +} +.postarea form:hover { + width: auto; + opacity: 1; + background: rgba(0,0,0,0.8) !important; + border-radius: 0 0 0 32px; + -moz-border-radius: 0 0 0 32px; + -webkit-border-radius: 0 0 0 32px; + box-shadow: 0 0 32px #000; + -moz-box-shadow: 0 0 32px #000; + -webkit-box-shadow: 0 0 32px #000; +} +tr>th>font { /*POSTINGMODE*/ + position: fixed; + top:-2px; right:0; + font-size: 0; +} +tr>th>font:after { + color: #f00 !important; + content: 'REPLY'; + font-size: 48px; +} +form table tr th { + background: #7E3737 !important; + color: #B99B9B !important; +} +input[type="text"], input[type="password"], textarea { + border: 2px solid rgba(94, 50, 50, 0.56) !important; + background: #7C7373 !important; + color: #311313 !important; +} +a:hover { + color: #8E748F !important; +} +a { + color: #7C7E7C !important; +} +form>table { + padding: 4px !important; +} +.reply, .replyhl { + background: rgba(0,0,0,0.25) !important; + border: 1px solid #161616 !important; + margin: 8px !important; + border-radius: 12px; + -moz-border-radius: 12px; + -webkit-border-radius: 12px; + box-shadow: 0 0 6px rgba(0,0,0,0.5); + -moz-box-shadow: 0 0 6px rgba(0,0,0,0.5); + -webkit-box-shadow: 0 0 6px rgba(0,0,0,0.5); +} +h1 { + color: #962B22 !important; + letter-spacing: 1px; +} +.replyhl { + border: 1px solid #9f0 !important; + border-width: 4px 0 !important; +} +.post.reply.highlighted { + background: rgba(18, 21, 22, 0.6) !important; +} +.omitted { + font-style: italic; +} +#de-menu { + rgba(0, 0, 0, 0.85) !important; +} +#de-alert { + rgba(0, 0, 0, 0.85) !important; +} +.de-pview { + background: rgba(0,0,0,0.86) !important; + border: 1px solid #161616 !important; + margin: 8px !important; + border-radius: 12px; + -moz-border-radius: 12px; + -webkit-border-radius: 12px; + box-shadow: 0 0 6px rgba(0,0,0,0.5); + -moz-box-shadow: 0 0 6px rgba(0,0,0,0.5); + -webkit-box-shadow: 0 0 6px rgba(0,0,0,0.5); +} +.name,.commentpostername { + color: #999 !important; +} +.trip { + color: #644 !important; +} +.capcode { + color: #BB1212!important; +} +.de-ppanel-cnt:after { + color: #3A5252 !important; +} +.public_ban { + color: #E62C2C !important; +} +blockquote { + color: #fff !important; +} +.quotejs { + color: #999 !important; +} +.quotelink { + color: #9f0 !important; +} +.unkfunc { + color: #6c6 !important; +} +.de-refmap:before { + color: #707A86 !important; +} +.de-refmap { + color: #4C505E !important; +} +p.intro a.email span.name { + text-decoration: underline; +} +.quote { + color: #82A259 !important; +} +.delete { + color: #857979 !important; +} + +.commentpostername>span[style] { + color: #f0c !important; + font-size: 1.1em; +} +a[href="mailto:sage"] { + text-decoration: none !important; +} +a[href="mailto:sage"]:before { + color: #f90; + content: '「SAGE」'; + text-shadow: 0 -1px 1px #f00; +} +.heading { + color: #B41818 !important; + font-size: 13pt !important; + text-shadow: 0 0 0.55em #522121 !important +} +strong { + color: #706E6E !important; +} +.subject { + color: #819173 !important; +} +.spoiler { + background: #D3CABC !important; + color: #D3CABC !important; +} +.spoiler:hover { + color: #3F3535 !important; +} +.filesize span { + font-size: .01em; + letter-spacing: -5em; +} +.filesize span:before { + font-size: 100em; + letter-spacing: 0; + content: attr(title); +} + +.spoiler { + color: #161515 !important; + background: #141313 !important; +} +span.spoiler:hover { + color: #858585 !important; + background: #2C2929 !important; +} +br+br+b[style] { + color: #f00 !important; +} + +} \ No newline at end of file From 40ab2e0c1728fab613bc16a19ab8fcb3fa78c1d4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 1 Aug 2013 21:28:16 -0400 Subject: [PATCH 203/289] Don't redraw image again after correcting image orientation; Correct image orientation with convert+gifsicle too --- inc/image.php | 4 ++-- post.php | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/inc/image.php b/inc/image.php index 5910cb85..51db2f83 100644 --- a/inc/image.php +++ b/inc/image.php @@ -251,9 +251,9 @@ class ImageConvert extends ImageBase { if (!$this->temp) { if ($config['strip_exif']) { - shell_exec('convert ' . escapeshellarg($this->src) . ' -strip ' . escapeshellarg($src)); + shell_exec('convert ' . escapeshellarg($this->src) . ' -auto-orient -strip ' . escapeshellarg($src)); } else { - shell_exec('convert ' . escapeshellarg($this->src) . ' ' . escapeshellarg($src)); + shell_exec('convert ' . escapeshellarg($this->src) . ' -auto-orient ' . escapeshellarg($src)); } } else { rename($this->temp, $src); diff --git a/post.php b/post.php index 22782ca7..5031830f 100644 --- a/post.php +++ b/post.php @@ -450,10 +450,12 @@ if (isset($_POST['delete'])) { if ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg') { // The following code corrects the image orientation. // Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered. - if ($config['thumb_method'] == 'convert') { - $exif = exif_read_data($upload); - if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { - shell_exec('convert ' . escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload)); + if (!($config['redraw_image'] || ($config['strip_exif'] && ($post['extension'] == 'jpg' || $post['extension'] == 'jpeg')))) { + if ($config['thumb_method'] == 'convert' || $config['thumb_method'] == 'convert+gifsicle') { + $exif = exif_read_data($upload); + if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { + shell_exec('convert ' . escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload)); + } } } } From dc84ccc6a8e0b6fd3fc626eb1f321e4cf2d05511 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 23:31:35 -0400 Subject: [PATCH 204/289] 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(-) 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() }} From f06978659b4ff4e18e9547ebd4af514d56123cfb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 00:08:37 -0400 Subject: [PATCH 205/289] Installer: Nicer pre-installation test --- inc/config.php | 19 +- install.php | 183 +++++++++++++++----- templates/installer/check-requirements.html | 54 ++++++ 3 files changed, 207 insertions(+), 49 deletions(-) create mode 100644 templates/installer/check-requirements.html 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'] = ''; + $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; - function rheader($item) { - global $page, $config; - - $page['body'] .= ''; + if (!defined('PHP_VERSION_ID')) { + $version = explode('.', PHP_VERSION); + define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } - function row($item, $result) { - global $page, $config, $__is_error; - if (!$result) - $__is_error = true; - $page['body'] .= ''; - } - - // Required extensions - rheader('PHP extensions'); - row('PDO', extension_loaded('pdo')); - row('GD', extension_loaded('gd')); + $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 + ) + ); - // GD tests - rheader('GD tests'); - row('JPEG', function_exists('imagecreatefromjpeg')); - row('PNG', function_exists('imagecreatefrompng')); - row('GIF', function_exists('imagecreatefromgif')); + $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.' + ) + ); - // Database drivers - $drivers = PDO::getAvailableDrivers(); + $config['font_awesome'] = true; - 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); + 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 %} +
      From 5710575d1dc9fbd39bd90f9e5f4f9e33ef3f5a73 Mon Sep 17 00:00:00 2001 From: czaks Date: Thu, 1 Aug 2013 23:31:35 -0400 Subject: [PATCH 206/289] 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(-) 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() }} From 0d64ae0472d65d33f6f6de3b3ea1476f1cefc25b Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 00:18:02 -0400 Subject: [PATCH 207/289] style-select.js: fix on firefox --- js/style-select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/style-select.js b/js/style-select.js index 33c1308b..c0272d98 100644 --- a/js/style-select.js +++ b/js/style-select.js @@ -20,7 +20,7 @@ onready(function(){ var i = 1; stylesDiv.children().each(function() { var opt = $('') - .text(this.innerText.replace(/(^\[|\]$)/g, '')) + .html(this.innerHTML.replace(/(^\[|\]$)/g, '')) .val(i); if ($(this).hasClass('selected')) opt.attr('selected', true); From 22cecf9de789d600b68af2796dba026628196e31 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 00:21:41 -0400 Subject: [PATCH 208/289] style-select.js: add id for a styling ability --- js/style-select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/style-select.js b/js/style-select.js index c0272d98..6dcb11e4 100644 --- a/js/style-select.js +++ b/js/style-select.js @@ -36,7 +36,7 @@ onready(function(){ stylesDiv.hide(); stylesDiv.after( - $('
      ') + $('
      ') .text(_('Style: ')) .append(stylesSelect) ); From be8c84a2ab6090c310c16cdf6668c13243f82975 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 00:18:02 -0400 Subject: [PATCH 209/289] style-select.js: fix on firefox --- js/style-select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/style-select.js b/js/style-select.js index 33c1308b..c0272d98 100644 --- a/js/style-select.js +++ b/js/style-select.js @@ -20,7 +20,7 @@ onready(function(){ var i = 1; stylesDiv.children().each(function() { var opt = $('') - .text(this.innerText.replace(/(^\[|\]$)/g, '')) + .html(this.innerHTML.replace(/(^\[|\]$)/g, '')) .val(i); if ($(this).hasClass('selected')) opt.attr('selected', true); From 3b259aab14599d5ec639cab20cdfcd7ae1dd27e1 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 00:21:41 -0400 Subject: [PATCH 210/289] style-select.js: add id for a styling ability --- js/style-select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/style-select.js b/js/style-select.js index c0272d98..6dcb11e4 100644 --- a/js/style-select.js +++ b/js/style-select.js @@ -36,7 +36,7 @@ onready(function(){ stylesDiv.hide(); stylesDiv.after( - $('
      ') + $('
      ') .text(_('Style: ')) .append(stylesSelect) ); From e5d4ba58ac7dc666983159272947172ed4e25733 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 01:01:02 -0400 Subject: [PATCH 211/289] These files are no longer used --- static/error.png | Bin 1358 -> 0 bytes static/ok.png | Bin 1483 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 static/error.png delete mode 100644 static/ok.png diff --git a/static/error.png b/static/error.png deleted file mode 100644 index f1ff27a87395a90af58530eca70cc99eac2f6c34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1358 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFe_w+M3hAM`dB6B=jtVb)aX^@7BGN-jeSKyVsdtB zi9%9pdS;%j()-=}l@u~lY?Z=IeGPmIoKrJ0J*tXQgRA^PlB=?lEmM^2?G$V(tSWK~ za#KqZ6)JLb@`|l0Y?Z*~TICg6frRyy6u?SKvTcwn`Gtf;oFf&jv zGt@IQHZeCh*HJJsFf`CNFw!?P(ls=+T7#d8;`MLTPi3R$GdIlgbLHwFq;OmQDX>KlDb#X~h zD#E>34K5C;EJ)Q4N-fSWElN%eN=;J+xv9X)xhOTUB)=#mKR*W+iUAqcv%y)OC5rManjB{01y2)&j#^@0)tC@`#CQj0RnQd8WD@^cly z9=6KF?G`hf=0WwQ;C72SPQChe3O4$nXhn)@R

      xqT2Z_7bkWQT?={=a`&d#N z7o;z?%uP7sYc%mhO2+=n3z-vMzvx)DvHI!dXF@Ss=am{a7Z@!J+;5++Bz1~gy!-yF z_Xlf)XJ^^2o~2MxwP>|d;}3re58IQE{}%2Guv@~}mbE?pO50g6?My#6-!JRWFY%O` obFKdVPYaGa#kc!9_OnVbtm9|Dc*Qu?3RJ>*y85}Sb4q9e0LC8byZ`_I diff --git a/static/ok.png b/static/ok.png deleted file mode 100644 index cbe92c77d5530267db00ab5c4bc9dd1ebfc62aea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1483 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFe_w+M3hAM`dB6B=jtVb)aX^@7BGN-jeSKyVsdtB zi9%9pdS;%j()-=}l@u~lY?Z=IeGPmIoKrJ0J*tXQgRA^PlB=?lEmM^2?G$V(tSWK~ za#KqZ6)JLb@`|l0Y?Z*~TICg6frRyy6u?SKvTcwn`Gtf;oFf&jv zGt@IQHZeCh*HJJsFf`CNFw!?P(ls=+T7#d8;`MLTPi3R$GdIlgbLHwFq;OmQDX>KlDb#X~h zD#E>34K5C;EJ)Q4N-fSWElN%eN=;J+xv9X)xhOTUB)=#mKR*W+iUAqY&aS4e<_2zthAwW7 zZpKC~CZ@)w#+ELQCT2!3y)OC5rManjB{01y2)$-F^@0)tC@`#CQj0RnQd8WD@^cly z9=6KF?G|I4=0WwQ;C71%PQChe3O4$nXhn)`FD~=V z?lIi)A$jKAzvs`qdlT_ooPS|jiBO@ETZ?wKX3``Nq4TTwrJ1>9cL>g6IP18Hy_4mk z^WQ|_?VW~~mTYbQ_x){F*duKh{eSs))ZOylR!-e!@qC3#o<`YH?vpVQ%fv4!SMdr* zM#-7|N?Y{mT)*@ZUd@;d@0r|Z{hsjr^o&iD4feL}I%hb!P)xms<<&zAzEiAi|K2XP z*qP0-GvCr++4m`Gc@qVHm)~Rft$0z?<3Ymd#JyKier!p;Y%oPKnD5Y4rm5?+UzFOu zy614B>ru$-1^3R~@;+gCGoEjOY>V$)zTlNcQ*ziFKk@ar$sGv)vUtvO3+bIc7j0&o zKBHiGuhV?BzM{(US$?St>^x_8-P*WPdit$(nFl{Uuw1ffz2Kc4!rV6_W9GbQyb;in zC^ezR_W6|MPhBqOX+B|8R22(odOuA=rBY7nz1zX4#_Ryi)-}&2 zu5y~RVP`_YUK#)WcMczzyjbJ2(4T#0cl`RpWb{Y4<#e`oiuT&{?CD Date: Fri, 2 Aug 2013 01:05:29 -0400 Subject: [PATCH 212/289] inline-expanding-filename.js: expand images also by clicking a link and not image --- js/inline-expanding-filename.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 js/inline-expanding-filename.js diff --git a/js/inline-expanding-filename.js b/js/inline-expanding-filename.js new file mode 100644 index 00000000..048a0e1a --- /dev/null +++ b/js/inline-expanding-filename.js @@ -0,0 +1,33 @@ +/* + * inline-expanding-filename.js + * Binds image filename link to expanding, to make kusaba x users somewhat more accustomed. + * https://github.com/vichan-devel/Tinyboard/blob/master/js/inline-expanding.js + * + * Released under the MIT license + * Copyright (c) 2012-2013 Marcin Łabanowski + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/inline-expanding.js'; + * $config['additional_javascript'][] = 'js/inline-expanding-filename.js'; + * + */ + +onready(function(){ + var inline_expanding_filename = function() { + $(this).find(".fileinfo > a").click(function(){ + var imagelink = $(this).parent().parent().find('a[target="_blank"]:first'); + if(imagelink.length > 0) { + imagelink.click(); + return false; + } + }); + }; + + $('div[id^="thread_"]').each(inline_expanding_filename); + + // allow to work with auto-reload.js, etc. + $(document).bind('new_post', function(e, post) { + inline_expanding_filename.call(post); + }); +}); From 6f6a20af8eb779f4b8dd703e3d87e72ad9b67908 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 03:16:34 -0400 Subject: [PATCH 213/289] ukko: javascript major refactor --- templates/themes/ukko/ukko.js | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) 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; } } }); }); + +})(); From 73b5cf5a08c395e706e8bc3ac8032bfbc810376f Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 04:20:57 -0400 Subject: [PATCH 214/289] ukko: implement ukko hide --- templates/themes/ukko/ukko.js | 65 +++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) 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(); } From 3922677968cd4228be0e37943de131282b9eb1e4 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 2 Aug 2013 04:36:08 -0400 Subject: [PATCH 215/289] ukko: bugfixes --- templates/themes/ukko/ukko.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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); From d0a6ffcb0c5a73f5ea5b8cccf81dd5cbd5aabab6 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 15:53:32 -0400 Subject: [PATCH 216/289] Whoops --- install.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.php b/install.php index fa41ad2d..b1395d3e 100644 --- a/install.php +++ b/install.php @@ -451,7 +451,7 @@ if ($step == 0) { array( 'category' => 'Database', 'name' => 'MySQL PDO driver installed', - 'result' => extension_loaded('pdo') && in_array('mysql1', PDO::getAvailableDrivers()), + 'result' => extension_loaded('pdo') && in_array('mysql', PDO::getAvailableDrivers()), 'required' => true, 'message' => 'The required PDO MySQL driver is not installed.', ), @@ -486,7 +486,7 @@ if ($step == 0) { array( 'category' => 'Image processing', 'name' => 'Imagick extension installed', - 'result' => extension_loaded('imagick1'), + 'result' => extension_loaded('imagick'), 'required' => false, 'message' => '(Optional) The PHP Imagick (ImageMagick) extension is not installed. You may not use Imagick for better (and faster) image processing.', ), @@ -507,7 +507,7 @@ if ($step == 0) { array( 'category' => 'Image processing', 'name' => '`gifsicle` (command-line animted GIF thumbnailing)', - 'result' => $can_exec && shell_exec('which gifsicle1'), + 'result' => $can_exec && shell_exec('which gifsicle'), 'required' => false, 'message' => '(Optional) `gifsicle` was not found or executable; you may not use `convert+gifsicle` for better animated GIF thumbnailing.', ), From 9e7fbf927c67797269062a3b5f827a92ac822e12 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 16:19:20 -0400 Subject: [PATCH 217/289] Installer improvements --- install.php | 176 ++------------------ templates/installer/check-requirements.html | 10 +- 2 files changed, 21 insertions(+), 165 deletions(-) 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)); - } + $config['cookies']['salt'] = substr(base64_encode(sha1(rand())), 0, 30); + $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30); - $page['body'] = ' - -
      - Database - - - - - - - - - - - - - - - - - -
      -

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

      -
      - Cookies - - - - - -
      - -
      - Flood control - - - - - - - - - - - - - - - - - -
      - -
      - Images - - - - - - - - - - - - - - -
      - -
      - Display - - - - - - - - -
      - -
      - 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%}
    3. {% if test.required %} - Error: + Error: {% else %} - Warning: + Warning: {% endif %} {{ test.message }}
    4. From 4fce9b63aee89c04ea0d833992e72ab75585f630 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 20:52:58 -0400 Subject: [PATCH 218/289] 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(-) 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 %}
      From 169dc7493806997aa6498875914f5d682a073310 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 20:56:30 -0400 Subject: [PATCH 219/289] Fix last commit --- inc/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/image.php b/inc/image.php index bfb77d30..94267db2 100644 --- a/inc/image.php +++ b/inc/image.php @@ -294,7 +294,7 @@ class ImageConvert extends ImageBase { error('Failed to resize image!'); } } else { - if (shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . + if (shell_exec('convert -flatten ' . sprintf($config['convert_args'], $this->width, $this->height) . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) error('Failed to resize image!'); } From 934c00f488dffa602bf6362de5ac9e1e625d2124 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 21:01:04 -0400 Subject: [PATCH 220/289] $config['dir']['static'] doesn't exist. --- inc/config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/config.php b/inc/config.php index c181c0c5..ca6f7b69 100644 --- a/inc/config.php +++ b/inc/config.php @@ -530,7 +530,7 @@ // Location of thumbnail to use for spoiler images. $config['spoiler_image'] = 'static/spoiler.png'; // Location of thumbnail to use for deleted images. - $config['image_deleted'] = $config['dir']['static'] . 'deleted.png'; + $config['image_deleted'] = '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. @@ -876,9 +876,9 @@ // 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'. + // $config['image_sticky'] = 'static/sticky.gif'; + // $config['image_locked'] = 'static/locked.gif'; + // $config['image_bumplocked'] = '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 From 1d7de12281f983cc8135abf9fcb00d9cd7e4972a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 21:23:18 -0400 Subject: [PATCH 221/289] Fix bug --- inc/image.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/inc/image.php b/inc/image.php index 94267db2..34e8404f 100644 --- a/inc/image.php +++ b/inc/image.php @@ -284,18 +284,18 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { - if (shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . + if (trim(shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . - escapeshellarg($this->temp)) || !file_exists($this->temp)) + escapeshellarg($this->temp) . ';echo $?' !== '0') || !file_exists($this->temp)) error('Failed to resize image!'); } else { - if (shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . - escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) + if (trim(shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . + escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) . ';echo $?') !== '0' || !file_exists($this->temp)) error('Failed to resize image!'); } } else { - if (shell_exec('convert -flatten ' . sprintf($config['convert_args'], $this->width, $this->height) . - escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) + if (trim(shell_exec('convert -flatten ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . + escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp) . ';echo $?')) !== '0' || !file_exists($this->temp)) error('Failed to resize image!'); } } From ce21a772de33b956bd12ca0b42c04fde74cffef7 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 21:28:15 -0400 Subject: [PATCH 222/289] gentoochan.css fix: .post-hover hard to read with low opacity --- stylesheets/gentoochan.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/stylesheets/gentoochan.css b/stylesheets/gentoochan.css index 8213eb26..eb3d6471 100644 --- a/stylesheets/gentoochan.css +++ b/stylesheets/gentoochan.css @@ -19,9 +19,12 @@ a.post_no { color: #ccc; } div.post.reply, input, textarea { - background: rgba(0, 0, 0, 0.1)!important; - border: 1px solid rgba(0, 0, 0, 0.2)!important; - border-radius: 2px !important; + background: rgba(0, 0, 0, 0.1); + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 2px; +} +div.post.reply.post-hover { + background: rgba(200, 200, 200, 0.85); } div.post.reply.highlighted { background: #f0c0b0; From e1aeccce5ed220498b09009ad0961640093777ae Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 21:32:18 -0400 Subject: [PATCH 223/289] ricechan.css: Make + + + + + + + + + + + + + +

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

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

      + +

      + From 62f8ea4813092b42a2cd390a8358ce798d103f40 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 2 Aug 2013 23:18:25 -0400 Subject: [PATCH 227/289] Better command-line ImageMagick image processing --- inc/config.php | 6 +++--- inc/image.php | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/inc/config.php b/inc/config.php index ca6f7b69..337d92cb 100644 --- a/inc/config.php +++ b/inc/config.php @@ -492,9 +492,9 @@ $config['thumb_method'] = 'gd'; // $config['thumb_method'] = 'convert'; - // 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'; + // Command-line options passed to ImageMagick when using `convert` for thumbnailing. Don't touch the + // placement of "%s" and "%d". + $config['convert_args'] = '-background transparent %s -strip -thumbnail %dx%d -quality 65'; // Strip EXIF metadata from JPEG files. $config['strip_exif'] = false; diff --git a/inc/image.php b/inc/image.php index e30c6919..141973ee 100644 --- a/inc/image.php +++ b/inc/image.php @@ -284,19 +284,19 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { - if (trim(shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . + 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) . ';echo $?') !== '0') || !file_exists($this->temp)) - error('Failed to resize image!'); + escapeshellarg($this->temp) . '2>&1 &&echo $?') !== '0') || !file_exists($this->temp)) + error($error); } else { - if (trim(shell_exec('convert ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . - escapeshellarg($this->src . '') . " " . escapeshellarg($this->temp)) . ';echo $?') !== '0' || !file_exists($this->temp)) - error('Failed to resize image!'); + if (trim($error = shell_exec('convert ' . sprintf($config['convert_args'], '', $this->width, $this->height) . ' ' . + escapeshellarg($this->src) . ' ' . escapeshellarg($this->temp) . ' 2>&1 &&echo $?')) !== '0' || !file_exists($this->temp)) + error($error); } } else { - if (trim(shell_exec('convert -flatten ' . sprintf($config['convert_args'], $this->width, $this->height) . ' ' . - escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp) . ';echo $?')) !== '0' || !file_exists($this->temp)) - error('Failed to resize image!'); + if (trim($error = shell_exec('convert ' . 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); } } } From 1d37e81adeea9b2a1bc1028f2bf45b47ac045ec4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 00:22:28 -0400 Subject: [PATCH 228/289] 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 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 From 784c3ffadbc28b7f6d6a1808a1f1d71e957cb089 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 00:28:54 -0400 Subject: [PATCH 229/289] Accidentally commit'd debug stuff/errors --- inc/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/image.php b/inc/image.php index 4fc9d018..88f735dd 100644 --- a/inc/image.php +++ b/inc/image.php @@ -289,12 +289,12 @@ class ImageConvert extends ImageBase { escapeshellarg($this->temp) . '2>&1 &&echo $?') !== '0') || !file_exists($this->temp)) error('Failed to resize image!', null, $error); } else { - if (trim($error = shell_exec('aconvert ' . sprintf($config['convert_args'], '', $this->width, $this->height) . ' ' . + if (trim($error = shell_exec('convert ' . sprintf($config['convert_args'], '', $this->width, $this->height) . ' ' . escapeshellarg($this->src) . ' ' . escapeshellarg($this->temp) . ' 2>&1 &&echo $?')) !== '0' || !file_exists($this->temp)) error('Failed to resize image!', null, $error); } } else { - if (trim($error = shell_exec('aconvert ' . sprintf($config['convert_args'], '-flatten', $this->width, $this->height) . ' ' . + if (trim($error = shell_exec('convert ' . 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('Failed to resize image!', null, $error); } From 056a6001aceddcf707974577d3566b1a166f01ec Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 02:01:52 -0400 Subject: [PATCH 230/289] Erorr handling update --- inc/database.php | 12 ++++++------ inc/display.php | 6 +++++- inc/functions.php | 25 +++++++++++++------------ mod.php | 2 +- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/inc/database.php b/inc/database.php index 95dfc775..24959d0c 100644 --- a/inc/database.php +++ b/inc/database.php @@ -121,14 +121,14 @@ function query($query) { return $pdo->query($query); } -function db_error($PDOStatement=null) { - global $pdo; +function db_error($PDOStatement = null) { + global $pdo, $db_error; if (isset($PDOStatement)) { - $err = $PDOStatement->errorInfo(); - return $err[2]; + $db_error = $PDOStatement->errorInfo(); + return $db_error[2]; } - $err = $pdo->errorInfo(); - return $err[2]; + $db_error = $pdo->errorInfo(); + return $db_error[2]; } diff --git a/inc/display.php b/inc/display.php index 4972d563..dddb6559 100644 --- a/inc/display.php +++ b/inc/display.php @@ -58,7 +58,7 @@ function createBoardlist($mod=false) { } function error($message, $priority = true, $debug_stuff = false) { - global $board, $mod, $config; + global $board, $mod, $config, $db_error; if ($config['syslog'] && $priority !== false) { // Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant. @@ -70,6 +70,10 @@ function error($message, $priority = true, $debug_stuff = false) { die('Error: ' . $message . "\n"); } + if ($config['debug'] && isset($db_error)) { + $debug_stuff = array_combine(array('SQLSTATE', 'Error code', 'Error message'), $db_error); + } + die(Element('page.html', array( 'config' => $config, 'title' => _('Error'), diff --git a/inc/functions.php b/inc/functions.php index b6bdd809..6c903663 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -155,19 +155,9 @@ 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) - )); - }); + set_error_handler('verbose_error_handler'); error_reporting(E_ALL); - ini_set('display_errors', true); + ini_set('display_errors', false); ini_set('html_errors', false); } @@ -244,6 +234,17 @@ function _syslog($priority, $message) { } } +function verbose_error_handler($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 . ':' . $errline, + 'errno' => $errno, + 'error' => $errstr, + 'backtrace' => array_slice(debug_backtrace(), 1) + )); +} + function create_antibot($board, $thread = null) { require_once dirname(__FILE__) . '/anti-bot.php'; diff --git a/mod.php b/mod.php index ee05c349..bdc89b87 100644 --- a/mod.php +++ b/mod.php @@ -23,7 +23,7 @@ $query = isset($_SERVER['QUERY_STRING']) ? urldecode($_SERVER['QUERY_STRING']) : $pages = array( '' => ':?/', // redirect to dashboard '/' => 'dashboard', // dashboard - '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work) + '/confir(m/(.+)' => 'confirm', // confirm action (if javascript didn't work) '/logout' => 'logout', // logout '/users' => 'users', // manage users From 68403f613e441894f22aa9087e3e535d2712511f Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 02:03:44 -0400 Subject: [PATCH 231/289] Didn't mean to commit that --- mod.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.php b/mod.php index bdc89b87..ee05c349 100644 --- a/mod.php +++ b/mod.php @@ -23,7 +23,7 @@ $query = isset($_SERVER['QUERY_STRING']) ? urldecode($_SERVER['QUERY_STRING']) : $pages = array( '' => ':?/', // redirect to dashboard '/' => 'dashboard', // dashboard - '/confir(m/(.+)' => 'confirm', // confirm action (if javascript didn't work) + '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work) '/logout' => 'logout', // logout '/users' => 'users', // manage users From ea1fe528a44d066e82d1bbb07f6ecefc52ec4e18 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 02:06:58 -0400 Subject: [PATCH 232/289] Fix ordering of notes and bans --- inc/mod/pages.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 615e85c7..5b74cc1c 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -800,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 ORDER BY `set` DESC"); $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 ORDER BY `time` DESC"); $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 50"); $query->bindValue(':search', '%' . $ip . '%'); $query->execute() or error(db_error($query)); $args['logs'] = $query->fetchAll(PDO::FETCH_ASSOC); From e35467e3b998ea2fd8800dd3722a1e9508b0ce2e Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 02:11:16 -0400 Subject: [PATCH 233/289] Fix install for MySQL < 5.5.3 --- install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.php b/install.php index 82ba5b8b..81b2e136 100644 --- a/install.php +++ b/install.php @@ -619,7 +619,7 @@ if ($step == 0) { sql_open(); if (mysql_version() < 50503) - $sql = str_replace('utf8', 'utf8mb4', $sql); + $sql = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $sql); // This code is probably horrible, but what I'm trying // to do is find all of the SQL queires and put them From 3ed15565b079680aa3c042cf0b7db0d2508c0838 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 03:36:20 -0400 Subject: [PATCH 234/289] Why is this escaped? --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 6c903663..4ca98dd6 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1769,7 +1769,7 @@ function generate_tripcode($name) { // generate salt $salt = substr($trip . 'H..', 1, 2); - $salt = preg_replace('/[^\.-z]/', '.', $salt); + $salt = preg_replace('/[^.-z]/', '.', $salt); $salt = strtr($salt, ':;<=>?@[\]^_`', 'ABCDEFGabcdef'); if ($secure) { From c9684fc0001ceaa521e80a50d353ecbfe3fafe9b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 05:21:02 -0400 Subject: [PATCH 235/289] Better/working web config editor --- inc/config.php | 9 +++++--- inc/functions.php | 2 +- inc/mod/config-editor.php | 47 ++++++++++++++++++++++++++++----------- inc/mod/pages.php | 2 +- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/inc/config.php b/inc/config.php index 8d1c05d7..2c164ef5 100644 --- a/inc/config.php +++ b/inc/config.php @@ -355,8 +355,9 @@ // 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". + // Example: Custom tripcodes. The below example makes a tripcode of "#test123" evaluate to "!HelloWorld". // $config['custom_tripcode']['#test123'] = '!HelloWorld'; + // Example: Custom secure tripcode. // $config['custom_tripcode']['##securetrip'] = '!!somethingelse'; // Allow users to mark their image as a "spoiler" when posting. The thumbnail will be replaced with a @@ -523,6 +524,7 @@ // Thumbnail to use for the non-image file uploads. $config['file_icons']['default'] = 'file.png'; $config['file_icons']['zip'] = 'zip.png'; + // Example: Custom thumbnail for certain file extension. // $config['file_icons']['extension'] = 'some_file.png'; // Location of above images. @@ -1199,7 +1201,8 @@ // array('127.0.0.1', 80) // array('127.0.0.1', 80, 'example.org') // ); - // Connection timeout, in seconds. + + // Connection timeout for $config['purge'], in seconds. $config['purge_timeout'] = 3; // Additional mod.php?/ pages. Look in inc/mod/pages.php for help. @@ -1210,7 +1213,7 @@ // // ... // }; - // Add links to dashboard (will all be in a new "Other" category). + // Example: Add links to dashboard (will all be in a new "Other" category). // $config['mod']['dashboard_links']['Something'] = '?/something'; // Remote servers. I'm not even sure if this code works anymore. It might. Haven't tried it in a while. diff --git a/inc/functions.php b/inc/functions.php index 4ca98dd6..dc814a2f 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -157,7 +157,7 @@ function loadConfig() { if ($config['verbose_errors']) { set_error_handler('verbose_error_handler'); error_reporting(E_ALL); - ini_set('display_errors', false); + ini_set('display_errors', true); ini_set('html_errors', false); } diff --git a/inc/mod/config-editor.php b/inc/mod/config-editor.php index 484bd908..d6cad8f0 100644 --- a/inc/mod/config-editor.php +++ b/inc/mod/config-editor.php @@ -13,13 +13,14 @@ function config_vars() { 'default_temp' => false ); $temp_comment = false; + $line_no = 0; foreach ($config_file as $line) { if ($temp_comment) { $var['comment'][] = $temp_comment; $temp_comment = false; } - if (preg_match('!^\s*// (.*)$!', $line, $matches)) { + if (preg_match('!^\s*// ([^$].*)$!', $line, $matches)) { if ($var['default'] !== false) { $line = ''; $temp_comment = $matches[1]; @@ -28,7 +29,10 @@ function config_vars() { } } else if ($var['default_temp'] !== false) { $var['default_temp'] .= "\n" . $line; - } elseif (preg_match('!^\s*\$config\[(.+?)\] = (.+?)(;( //.+)?)?$!', $line, $matches)) { + } elseif (preg_match('!^[\s/]*\$config\[(.+?)\] = (.+?)(;( //.+)?)?$!', $line, $matches)) { + if (preg_match('!^\s*//\s*!', $line)) { + $var['commented'] = true; + } $var['name'] = explode('][', $matches[1]); if (count($var['name']) == 1) { $var['name'] = preg_replace('/^\'(.*)\'$/', '$1', end($var['name'])); @@ -43,20 +47,30 @@ function config_vars() { $var['default_temp'] = $matches[2]; } - if (trim($line) === '') { - if ($var['name'] !== false) { - if ($var['default_temp']) - $var['default'] = $var['default_temp']; - - $temp = eval('return ' . $var['default'] . ';'); - if (!isset($temp)) + if ($var['name'] !== false) { + if ($var['default_temp']) + $var['default'] = $var['default_temp']; + if ($var['default'][0] == '&') + continue; // This is just an alias. + if (!preg_match('/^array|\[\]|function/', $var['default']) && !preg_match('/^Example: /', trim(implode(' ', $var['comment'])))) { + $syntax_error = true; + $temp = eval('$syntax_error = false;return ' . $var['default'] . ';'); + if ($syntax_error && $temp === false) { + error('Error parsing config.php (line ' . $line_no . ')!', null, $var); + } elseif (!isset($temp)) { $var['type'] = 'unknown'; - else + } else { $var['type'] = gettype($temp); - + } unset($var['default_temp']); - if (!is_array($var['name']) || (end($var['name']) != '' && !in_array(reset($var['name']), array('stylesheets')))) { + $already_exists = false; + foreach ($conf as $_var) { + if ($var['name'] == $_var['name']) + $already_exists = true; + + } + if (!$already_exists) $conf[] = $var; } } @@ -65,9 +79,16 @@ function config_vars() { 'name' => false, 'comment' => array(), 'default' => false, - 'default_temp' => false + 'default_temp' => false, + 'commented' => false ); } + + if (trim($line) === '') { + $var['comment'] = array(); + } + + $line_no++; } return $conf; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 5b74cc1c..6c46a84f 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1975,7 +1975,7 @@ function mod_config() { foreach ($var['name'] as $n) $c = &$c[$n]; } else { - $c = $config[$var['name']]; + $c = @$config[$var['name']]; } $var['value'] = $c; From d4ad874e09f026de2ade18f49797dcac4e65f67b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 05:25:41 -0400 Subject: [PATCH 236/289] no --- inc/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/config.php b/inc/config.php index 2c164ef5..e8422a75 100644 --- a/inc/config.php +++ b/inc/config.php @@ -281,7 +281,7 @@ // 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; + $config['force_body_op'] = true; // Require an image for threads? $config['force_image_op'] = true; From 0d1bfa47f1f459b4893426e752ce2d3e9b2de030 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 05:41:01 -0400 Subject: [PATCH 237/289] 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(-) 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 not readonly %}{% 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 %} +
    5. {% trans 'Rebuild' %}
    6. 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