From d2429e05d1e9f79c98a386e771b66e2af3999b0e Mon Sep 17 00:00:00 2001 From: Benjamin Southall Date: Sun, 3 Sep 2017 23:39:43 +0900 Subject: [PATCH] Add warning without ban, joke capcode support, SC editor support, home link support, table for calender theme / extension, removing boardalias duplicate citations in markup and other features --- inc/config.php | 28 +++- inc/functions.php | 40 ++--- inc/mod/pages.php | 235 +++++++++++++++++++++++------- install.sql | 15 +- mod.php | 1 + post.php | 105 +++++++++++-- templates/header.html | 1 + templates/index.html | 7 + templates/post/post_controls.html | 3 + templates/post_reply.html | 3 + templates/post_thread.html | 3 + templates/thread.html | 3 + 12 files changed, 341 insertions(+), 103 deletions(-) diff --git a/inc/config.php b/inc/config.php index 72ac4984..227f4c32 100644 --- a/inc/config.php +++ b/inc/config.php @@ -198,9 +198,6 @@ // of the strong anonymity associated with it. $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); - // Replacement for sectoor.de - // $config['dnsbl'][] = 'torexit.dan.me.uk'; - // http://www.sorbs.net/using.shtml // $config['dnsbl'][] = array('dnsbl.sorbs.net', array(2, 3, 4, 5, 6, 7, 8, 9)); @@ -538,7 +535,6 @@ $config['early_404_page'] = 3; $config['early_404_replies'] = 5; - $config['early_404_staged'] = false; // 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. @@ -679,7 +675,7 @@ */ // Maximum number of images allowed. Increasing this number enabled multi image. // If you make it more than 1, make sure to enable the below script for the post form to change. - // $config['additional_javascript'][] = 'js/multi-image.js'; + // $config['additional_javascript'][] = 'js/multi_image.js'; $config['max_images'] = 1; // Method to use for determing the max filesize. @@ -1325,6 +1321,7 @@ // Mod links (full HTML). $config['mod']['link_delete'] = '[D]'; $config['mod']['link_ban'] = '[B]'; + $config['mod']['link_warning'] = '[W]'; $config['mod']['link_bandelete'] = '[B&D]'; $config['mod']['link_deletefile'] = '[F]'; $config['mod']['link_spoilerimage'] = '[S]'; @@ -1394,9 +1391,11 @@ // 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_warning_message'] = _('USER WAS WARNED FOR THIS POST'); // $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)'; + $config['mod']['warning_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 @@ -1448,7 +1447,7 @@ // Capcode permissions. $config['mod']['capcode'] = array( - // JANITOR => array('Janitor'), + JANITOR => array('Janitor'), MOD => array('Mod'), ADMIN => true ); @@ -1468,6 +1467,8 @@ $config['mod']['show_ip'] = MOD; // Delete a post $config['mod']['delete'] = JANITOR; + // Publicly warn a user for a post + $config['mod']['warning'] = JANITOR; // Ban a user for a post $config['mod']['ban'] = MOD; // Ban and delete (one click; instant) @@ -1855,7 +1856,13 @@ // Allowed HTML tags in ?/edit_pages. $config['allowed_html'] = 'a[href|title],p,br,li,ol,ul,strong,em,u,h2,b,i,tt,div,img[src|alt|title],hr'; - //Enable posting from overboards + // Allow joke capcode + $config['joke_capcode'] = false; + + // Show "Home" link in page navigation. Use with the Catalog theme. Set to false to disable. + $config['home_link'] = false; + + // Enable posting from overboards $config['overboard_post_form'] = false; // Enable auto IP note generation of moderator deleted posts @@ -1863,3 +1870,10 @@ // Enable PDF file thumbnail generation $config['pdf_file_thumbnail'] = false; + + // Enable SCeditor WYSIWIG and CSS + $config['sc_editor'] = false; + $config['sc_editor_theme'] = 'transparent.min'; + + // Show "Home" link in page navigation. Use with the Catalog theme. Set to false to disable. + $config['home_link'] = true; diff --git a/inc/functions.php b/inc/functions.php index 9283c3ae..0b4ddaee 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -997,7 +997,7 @@ function insertFloodPost(array $post) { } function post(array $post) { - global $pdo, $board; + global $pdo, $board,$config; $query = prepare(sprintf("INSERT INTO ``posts_%s`` VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :files, :num_files, :filehash, :password, :ip, :sticky, :locked, :cycle, 0, :embed, :slug)", $board['uri'])); // Basic stuff @@ -1047,7 +1047,12 @@ function post(array $post) { if ($post['mod'] && isset($post['capcode']) && $post['capcode']) { $query->bindValue(':capcode', $post['capcode'], PDO::PARAM_INT); } else { - $query->bindValue(':capcode', null, PDO::PARAM_NULL); + if ($config['joke_capcode'] && isset($post['capcode']) && $post['capcode'] === 'joke') { + $query->bindValue(':capcode', $post['capcode'], PDO::PARAM_INT); + } + else { + $query->bindValue(':capcode', null, PDO::PARAM_NULL); + } } if (!empty($post['embed'])) { @@ -1279,28 +1284,11 @@ function clean($pid = false) { $query->bindValue(':offset', $offset, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - if ($config['early_404_staged']) { - $page = $config['early_404_page']; - $iter = 0; - } - else { - $page = 1; - } - while ($post = $query->fetch(PDO::FETCH_ASSOC)) { - if ($post['reply_count'] < $page*$config['early_404_replies']) { + if ($post['reply_count'] < $config['early_404_replies']) { deletePost($post['thread_id'], false, false); if ($pid) modLog("Automatically deleting thread #{$post['thread_id']} due to new thread #{$pid} (early 404 is set, #{$post['thread_id']} had {$post['reply_count']} replies)"); } - - if ($config['early_404_staged']) { - $iter++; - - if ($iter == $config['threads_per_page']) { - $page++; - $iter = 0; - } - } } } } @@ -1327,7 +1315,6 @@ function index($page, $mod=false, $brief = 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']) $board['thread_count'] = $query->rowCount(); @@ -2090,14 +2077,13 @@ function markup(&$body, $track_cites = false, $op = false) { $clauses = array_unique($clauses); if ($board['uri'] != $_board) { - if (!openBoard($_board)) - { + if (!openBoard($_board)){ if (in_array($_board,array_keys($config['boards_alias']))){ - $_board = $config['boards_alias'][$_board]; - openBoard($_board); - } - + //$_board = $config['boards_alias'][$_board]; + //openBoard($_board); + } continue; // Unknown board + } } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index b822f48c..a1bc7767 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -760,7 +760,6 @@ function mod_view_board($boardName, $page_no = 1) { $overboard->settings['include'] = $config['overboards'][$boardName]['include']; } $overboard->settings['boards'] = listBoards(); - echo $overboard->build($mod); return; } @@ -939,6 +938,23 @@ function mod_ban() { header('Location: ?/', true, $config['redirect_http']); } +function mod_warning() { + global $config; + + if (!hasPermission($config['mod']['warning'])) + error($config['error']['noaccess']); + + if (!isset( $_POST['board'])) { + mod_page(_('New warning'), 'mod/warning_form.html', array('token' => make_secure_link_token('ban'))); + return; + } + + if (isset($_POST['redirect'])) + header('Location: ' . $_POST['redirect'], true, $config['redirect_http']); + else + header('Location: ?/', true, $config['redirect_http']); +} + function mod_bans() { global $config; global $mod; @@ -1338,7 +1354,7 @@ function mod_move($originBoard, $postID) { $query->execute() or error(db_error($query)); $replies = array(); - + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['mod'] = true; $post['thread'] = $newID; @@ -1474,31 +1490,32 @@ function mod_move($originBoard, $postID) { function mod_merge($originBoard, $postID) { global $board, $config, $mod, $pdo; - + if (!openBoard($originBoard)) error($config['error']['noboard']); - + if (!hasPermission($config['mod']['merge'], $originBoard)) error($config['error']['noaccess']); - + $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)) error($config['error']['404']); - $sourceOp = ""; + $sourceOp = ""; if ($post['thread']){ - $sourceOp = $post['thread']; + $sourceOp = $post['thread']; } else{ - $sourceOp = $post['id']; - } - $newpost = ""; + $sourceOp = $post['id']; + } + $newpost = ""; $boards = listBoards(); - + if (isset($_POST['board'])) { $targetBoard = $_POST['board']; - $targetOp = ""; + $shadow = isset($_POST['shadow']); + $targetOp = ""; if ($_POST['target_thread']) { $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id', $targetBoard)); $query->bindValue(':id', $_POST['target_thread']); @@ -1509,14 +1526,14 @@ function mod_merge($originBoard, $postID) { else { if ($newpost['thread']){ - $targetOp = $newpost['thread']; + $targetOp = $newpost['thread']; } else{ - $targetOp = $newpost['id']; - } + $targetOp = $newpost['id']; + } } } - + if ($targetBoard === $originBoard){ // Just update the thread id for all posts in the original thread to new op $query = prepare(sprintf('UPDATE ``posts_%s`` SET `thread` = :newthread WHERE `id` = :oldthread OR `thread` = :oldthread', $originBoard)); @@ -1524,11 +1541,17 @@ function mod_merge($originBoard, $postID) { $query->bindValue(':oldthread', $sourceOp, PDO::PARAM_INT); $query->execute() or error(db_error($query)); // build index + // Delete thread HTML page + file_unlink($board['dir'] . $config['dir']['res'] . link_for($post) ); + file_unlink($board['dir'] . $config['dir']['res'] . link_for($post, true) ); // noko50 + file_unlink($board['dir'] . $config['dir']['res'] . sprintf('%d.json', $post['id'])); + //deletePost($postID); + //modLog("Deleted post #{$postID}"); buildIndex(); // build new thread buildThread($targetOp); - + // trigger themes rebuildThemes('post', $targetBoard); modLog("Merged thread with #${sourceOp} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${targetOp})", $originBoard); @@ -1537,17 +1560,17 @@ function mod_merge($originBoard, $postID) { header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($newpost) . '#' . $targetOp, true, $config['redirect_http']); } else { - // Move thread to new board without shadow thread and then update the thread id for all posts in that thread to new op + // Move thread to new board without shadow thread and then update the thread id for all posts in that thread to new op // indicate that the post is a thread if (count($boards) <= 1) error(_('Impossible to merge thread to different board; there is only one board.')); $post['op'] = true; - + if ($post['files']) { $post['files'] = json_decode($post['files'], TRUE); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { - if ($file['file'] === 'deleted') + if ($file['file'] === 'deleted') continue; $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; $file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']; @@ -1555,42 +1578,44 @@ function mod_merge($originBoard, $postID) { } else { $post['has_file'] = false; } - + // allow thread to keep its same traits (stickied, locked, etc.) $post['mod'] = true; - + if (!openBoard($targetBoard)) error($config['error']['noboard']); - + // create the new thread $newID = post($post); - + $op = $post; $op['id'] = $newID; - + + $clone = $shadow ? 'copy' : 'rename'; + if ($post['has_file']) { // copy image foreach ($post['files'] as $i => &$file) { - if ($file['file'] !== 'deleted') + if ($file['file'] !== 'deleted') $clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); if (isset($file['thumb']) && !in_array($file['thumb'], array('spoiler', 'deleted', 'file'))) $clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } - + // 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->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - + $replies = array(); - + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['mod'] = true; $post['thread'] = $newID; - + if ($post['files']) { $post['files'] = json_decode($post['files'], TRUE); $post['has_file'] = true; @@ -1601,20 +1626,20 @@ function mod_merge($originBoard, $postID) { } else { $post['has_file'] = false; } - + $replies[] = $post; } - + $newIDs = array($postID => $newID); - + openBoard($targetBoard); - + foreach ($replies as &$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($query)); - + // correct >>X links while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if (isset($newIDs[$cite['target']])) { @@ -1622,16 +1647,16 @@ function mod_merge($originBoard, $postID) { '/(>>(>\/' . preg_quote($originBoard, '/') . '\/)?)' . preg_quote($cite['target'], '/') . '/', '>>' . $newIDs[$cite['target']], $post['body_nomarkup']); - + $post['body'] = $post['body_nomarkup']; } } - + $post['body'] = $post['body_nomarkup']; - + $post['op'] = false; $post['tracked_cites'] = markup($post['body'], true); - + if ($post['has_file']) { // copy image foreach ($post['files'] as $i => &$file) { @@ -1641,7 +1666,8 @@ function mod_merge($originBoard, $postID) { } // insert reply $newIDs[$post['id']] = $newPostID = post($post); - + + if (!empty($post['tracked_cites'])) { $insert_rows = array(); foreach ($post['tracked_cites'] as $cite) { @@ -1652,26 +1678,27 @@ function mod_merge($originBoard, $postID) { query('INSERT INTO ``cites`` VALUES ' . implode(', ', $insert_rows)) or error(db_error()); } } - + modLog("Moved thread #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); - + // build new thread buildThread($newID); - + clean(); buildIndex(); - + // trigger themes rebuildThemes('post', $targetBoard); - + $newboard = $board; // return to original board openBoard($originBoard); - + deletePost($postID); + modLog("Deleted post #{$postID}"); buildIndex(); - + openBoard($targetBoard); // Just update the thread id for all posts in the original thread to new op $query = prepare(sprintf('UPDATE ``posts_%s`` SET `thread` = :newthread WHERE `id` = :oldthread OR `thread` = :oldthread', $targetBoard)); @@ -1683,18 +1710,18 @@ function mod_merge($originBoard, $postID) { // build new thread buildThread($targetOp); - + // trigger themes rebuildThemes('post', $targetBoard); modLog("Merged thread with #${newID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${targetOp})", $targetBoard); // redirect header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($newpost) . '#' . $targetOp, true, $config['redirect_http']); - } + } } - + $security_token = make_secure_link_token($originBoard . '/merge/' . $postID); - + mod_page(_('Merge thread'), 'mod/merge.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); } @@ -1820,6 +1847,106 @@ function mod_ban_post($board, $delete, $post, $token = false) { mod_page(_('New ban'), 'mod/ban_form.html', $args); } +function mod_warning_post($board,$post, $token = false) { + global $config, $mod; + + if (!openBoard($board)) + error($config['error']['noboard']); + + $security_token = make_secure_link_token($board . '/warning/' . $post); + + $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)) + error($config['error']['404']); + + $thread = $_post['thread']; + $ip = $_post['ip']; + + if (isset($_POST['new_warning'])) { + if (isset($_POST['ip'])) + $ip = $_POST['ip']; + + if (isset($_POST['public_message'], $_POST['message'])) { + // public warning message + $_POST['message'] = preg_replace('/[\r\n]/', '', $_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", utf8tohtml($_POST['message']))); + $query->execute() or error(db_error($query)); + rebuildPost($post); + + modLog("Attached a public warning message to post #{$post}: " . utf8tohtml($_POST['message'])); + buildThread($thread ? $thread : $post); + buildIndex(); + + if ($config['autotagging']){ + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE id = :id", $board)); + $query->bindValue(':id', $post ); + $query->execute() or error(db_error($query)); + $ip = ""; + $time = ""; + $filename = ""; + $filehash = ""; + $subject = ""; + $name = ""; + $body = ""; + while ($mypost = $query->fetch(PDO::FETCH_ASSOC)) { + $time = $mypost["time"]; + $ip = $mypost["ip"]; + $body = $mypost["body_nomarkup"]; + $name = $mypost["name"]; + $subject = $mypost["subject"]; + $filehash = $mypost["filehash"]; + $mypost['files'] = $mypost['files'] ? json_decode($mypost['files']) : array(); + // For each file append file name + for ($file_count = 0; $file_count < $mypost["num_files"];$file_count++){ + $filename .= $mypost['files'][$file_count]->name . "\r\n"; + } + } + if ($time !== ''){ + $dt = new DateTime("@$time"); + $autotag = "Post warned\r\n"; + $autotag .= $name . " " . $subject . " " . $dt->format('Y-m-d H:i:s') . " No.". $post . "\r\n"; + $autotag .= "/${board}/" . " " . $filehash . " " . $filename ."\r\n"; + $autotag .= $body . "\r\n"; + $autotag = escape_markup_modifiers($autotag); + markup($autotag); + $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()); + $query->bindValue(':body', $autotag); + $query->execute() or error(db_error($query)); + modLog("Added a note for {$ip}"); + } + } + } + if(isset($_POST['thread'])) { + // Redirect to thread + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], $config['file_page']), true, $config['redirect_http']); + } else { + // Redirect to board index. + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); + } + } + $args = array( + 'ip' => $ip, + 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), + 'post' => $post, + 'board' => $board, + 'token' => $security_token + ); + + if($_GET['thread']) { + $args['thread'] = $_GET['thread']; + } + + mod_page(_('New warning'), 'mod/warning_form.html', $args); +} + function mod_edit_post($board, $edit_raw_html, $postID) { global $config, $mod; @@ -2709,7 +2836,7 @@ function mod_report_dismiss($id, $all = false) { function mod_recent_posts($lim,$board_list = false,$json=false) { global $config, $mod, $pdo; - + if (!hasPermission($config['mod']['recent'])) error($config['error']['noaccess']); @@ -2746,7 +2873,7 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { $mod_boards[] = $board; } } - } + } // Manually build an SQL query $query = 'SELECT * FROM ('; diff --git a/install.sql b/install.sql index c7f1b021..c1b3827d 100644 --- a/install.sql +++ b/install.sql @@ -305,8 +305,8 @@ CREATE TABLE IF NOT EXISTS `ban_appeals` ( CREATE TABLE `pages` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `board` varchar(58) CHARACTER SET utf8 DEFAULT NULL, - `name` varchar(255) CHARACTER SET utf8 NOT NULL, + `board` varchar(125) DEFAULT NULL, + `name` varchar(125) NOT NULL, `title` varchar(255) DEFAULT NULL, `type` varchar(255) DEFAULT NULL, `content` text, @@ -321,7 +321,7 @@ CREATE TABLE `pages` ( -- CREATE TABLE `nntp_references` ( - `board` varchar(30) NOT NULL, + `board` varchar(60) NOT NULL, `id` int(11) unsigned NOT NULL, `message_id` varchar(255) CHARACTER SET ascii NOT NULL, `message_id_digest` varchar(40) CHARACTER SET ascii NOT NULL, @@ -333,6 +333,15 @@ CREATE TABLE `nntp_references` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; +CREATE TABLE IF NOT EXISTS `calendar_events` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `start` datetime NOT NULL, + `end` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; + /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/mod.php b/mod.php index 69694425..d754df72 100644 --- a/mod.php +++ b/mod.php @@ -80,6 +80,7 @@ $pages = array( '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search + '/(\%b)/warning/(\d+)' => 'secure_POST warning_post', // warn poster '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread '/(\%b)/move_reply/(\d+)' => 'secure_POST move_reply', // move reply diff --git a/post.php b/post.php index 875bc12a..e6310e16 100644 --- a/post.php +++ b/post.php @@ -222,7 +222,7 @@ if (isset($_POST['delete'])) { error($config['error']['nodelete']); foreach ($delete as &$id) { - $query = prepare(sprintf("SELECT `id`,`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)); @@ -254,7 +254,7 @@ if (isset($_POST['delete'])) { } _syslog(LOG_INFO, 'Deleted 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'], $post['thread'] ? $post['thread'] : $id) . ($post['thread'] ? '#' . $id : '') ); } } @@ -330,12 +330,6 @@ if (isset($_POST['delete'])) { $thread = $query->fetch(PDO::FETCH_ASSOC); - $error = event('report', array('ip' => $_SERVER['REMOTE_ADDR'], 'board' => $board['uri'], 'post' => $post, 'reason' => $reason,'link' => link_for($post))); - - if ($error) { - error($error); - } - if ($config['syslog']) _syslog(LOG_INFO, 'Reported post: ' . '/' . $board['dir'] . $config['dir']['res'] . link_for($post) . ($thread['thread'] ? '#' . $id : '') . @@ -625,11 +619,14 @@ if (isset($_POST['delete'])) { error($config['error']['locked']); $numposts = numPosts($post['thread']); - - if ($config['reply_hard_limit'] != 0 && $config['reply_hard_limit'] <= $numposts['replies']) + + $replythreshold = isset($thread['cycle']) && $thread['cycle'] ? $numposts['replies'] - 1 : $numposts['replies']; + $imagethreshold = isset($thread['cycle']) && $thread['cycle'] ? $numposts['images'] - 1 : $numposts['images']; + + if ($config['reply_hard_limit'] != 0 && $config['reply_hard_limit'] <= $replythreshold) error($config['error']['reply_hard_limit']); - if ($post['has_file'] && $config['image_hard_limit'] != 0 && $config['image_hard_limit'] <= $numposts['images']) + if ($post['has_file'] && $config['image_hard_limit'] != 0 && $config['image_hard_limit'] <= $imagethreshold) error($config['error']['image_hard_limit']); } } @@ -692,6 +689,18 @@ if (isset($_POST['delete'])) { } } } + else if ($config['joke_capcode']) { + if (strtolower($post['email']) == 'joke') { + if (isset($config['joke_capcode_default'])){ + $cap = $config['joke_capcode_default']; + } + else { + $cap = "joke"; + } + $post['capcode'] = utf8tohtml($cap); + $post['email'] = ''; + } + } $trip = generate_tripcode($post['name']); $post['name'] = $trip[0]; @@ -1011,7 +1020,8 @@ if (isset($_POST['delete'])) { } $image->destroy(); } else { - if ($file['extension'] == "pdf" && $config['pdf_file_thumbnail']){ + if (($file['extension'] == "pdf" && $config['pdf_file_thumbnail']) || + ($file['extension'] == "djvu" && $config['djvu_file_thumbnail']) ){ $path = $file['thumb']; $error = shell_exec_error( 'convert -thumbnail x300 -background white -alpha remove ' . escapeshellarg($file['tmp_name']. '[0]') . ' ' . @@ -1028,6 +1038,77 @@ if (isset($_POST['delete'])) { $file['width'] = $size[0]; $file['height'] = $size[1]; } + /*if (($file['extension'] == "epub" && $config['epub_file_thumbnail'])){ + $path = $file['thumb']; + // Open epub + // Get file list + // Check if cover file exists according to regex if it does use it + // Otherwise check if metadata file exists, and if does get rootfile and search for manifest for cover file name + // Otherwise Check if other image files exist and use them, based on criteria to pick the best one. + // Once we have filename extract said file from epub to file['thumb'] location. + $zip = new ZipArchive(); + if(@$zip->open($path)){ + $filename = ""; + // Go looking for a file name, current implementation just uses regex but should fallback to + // getting all images and then choosing one. + for( $i = 0; $i < $zip->numFiles; $i++ ){ + $stat = $zip->statIndex( $i ); + $matches = array(); + if (preg_match('/.*cover.*\.(jpg|jpeg|png)/', $stat['name'], $matches)) { + $filename = $matches[0]; + break; + } + } + // We have a cover filename to extract. + if (strlen($filename) > 0){ + //$zip->extractTo(dirname($file['thumb']), array($filename)); + } + else { + $error = 1; + } + + } + else { + $error = 1; + } + + if ($error){ + $path = sprintf($config['file_thumb'],isset($config['file_icons'][$file['extension']]) ? $config['file_icons'][$file['extension']] : $config['file_icons']['default']); + } + + $file['thumb'] = basename($file['thumb']); + $size = @getimagesize($path); + $file['thumbwidth'] = $size[0]; + $file['thumbheight'] = $size[1]; + $file['width'] = $size[0]; + $file['height'] = $size[1]; + }*/ + else if ($file['extension'] == "txt" && $config['txt_file_thumbnail']){ + $path = $file['thumb']; + $error = shell_exec_error( 'convert -thumbnail x300 xc:white -font "FreeMono" -pointsize 12 -fill black -annotate +15+15 ' . + escapeshellarg( '@' . $file['tmp_name']) . ' ' . + escapeshellarg($file['thumb'])); + + if ($error){ + $path = sprintf($config['file_thumb'],isset($config['file_icons'][$file['extension']]) ? $config['file_icons'][$file['extension']] : $config['file_icons']['default']); + } + + $file['thumb'] = basename($file['thumb']); + $size = @getimagesize($path); + $file['thumbwidth'] = $size[0]; + $file['thumbheight'] = $size[1]; + $file['width'] = $size[0]; + $file['height'] = $size[1]; + } + else if ($file['extension'] == "svg"){ + // Copy, because there's nothing to resize + $file['thumb'] = substr_replace($file['thumb'] , $file['extension'], strrpos($file['thumb'] , '.') +1); + copy($file['tmp_name'], $file['thumb']); + $file['thumbwidth'] = $config['thumb_width']; + $file['thumbheight'] = $config['thumb_height']; + $file['thumb'] = basename($file['thumb']); + + } else { // not an image //copy($config['file_thumb'], $post['thumb']); diff --git a/templates/header.html b/templates/header.html index 06bc95d9..aecff50b 100644 --- a/templates/header.html +++ b/templates/header.html @@ -7,6 +7,7 @@ {% if config.default_code_stylesheet.1 != '' %}{% endif %} {% if config.font_awesome %}{% endif %} {% if config.country_flags_condensed %}{% endif %} + {% if config.sc_editor %} {% endif %}