diff --git a/inc/display.php b/inc/display.php index 0c846cf9..6de187a3 100644 --- a/inc/display.php +++ b/inc/display.php @@ -56,31 +56,21 @@ function doBoardListPart($list, $root, &$boards) { return $body; } -function createBoardlist($mod=false) { +function createForeignBoardListSection($configKey){ global $config; - - if (!isset($config['boards'])) return array('top'=>'','bottom'=>''); - - $xboards = listBoards(); - $boards = array(); - foreach ($xboards as $val) { - $boards[$val['uri']] = $val['title']; - } - - $body = doBoardListPart($config['boards'], $mod?'?/':$config['root'], $boards); - - if (isset($config['foreign_boards'])) { + $body = ''; - $body .= ' ['; + if (isset($config[$configKey])){ + $body .= ' ['; // Append links to foreign boards $i = 0; - foreach ($config['foreign_boards'] as $fboardname => $fboardurl) { + foreach ($config[$configKey] as $fboardname => $fboardurl) { $i++; $body .= ' ' . $fboardname . ''; // only put slash in between elements - if ($i != count($config['foreign_boards'])) { + if ($i != count($config[$configKey])) { $body .= ' /'; } } @@ -88,6 +78,24 @@ function createBoardlist($mod=false) { $body .= '] '; } + return $body; +} + +function createBoardlist($mod=false) { + global $config; + + if (!isset($config['boards'])) return array('top'=>'','bottom'=>''); + + $xboards = listBoards(); + $boards = array(); + foreach ($xboards as $val) { + $boards[$val['uri']] = $val['title']; + } + $body = ''; + $body .= createForeignBoardListSection('prepended_foreign_boards'); + $body .= doBoardListPart($config['boards'], $mod?'?/':$config['root'], $boards); + $body .= createForeignBoardListSection('foreign_boards'); + if ($config['boardlist_wrap_bracket'] && !preg_match('/\] $/', $body)) $body = '[' . $body . ']'; diff --git a/inc/instance-config.php b/inc/instance-config.php index 98f6a327..083c499e 100644 --- a/inc/instance-config.php +++ b/inc/instance-config.php @@ -23,6 +23,11 @@ $config['boards'] = array( ) , array('meta') ); + +$config['prepended_foreign_boards'] = array( + 'overboard' => '/overboard/', +); + $config['foreign_boards'] = array( 'GET' => 'https://getchan.net/GET/', 'ref' => 'https://getchan.net/ref/' diff --git a/templates/themes/catalog/info.php b/templates/themes/catalog/info.php index 0e7581f0..67999c88 100644 --- a/templates/themes/catalog/info.php +++ b/templates/themes/catalog/info.php @@ -83,6 +83,27 @@ 'default' => true, 'comment' => 'Check this if you wish to show a nice tooltip with info about the thread on mouse over.' ); + $theme['config'][] = Array( + 'title' => 'Build overboard catalog', + 'name' => 'has_overboard', + 'type' => 'checkbox', + 'default' => false, + 'comment' => 'Check this if you wish to create a catalog for the overboard.' + ); + $theme['config'][] = Array( + 'title' => 'Overboard location (default \'overboard\')', + 'name' => 'overboard_location', + 'type' => 'text', + 'default' => 'overboard', + 'comment' => 'Fill in the location of the overboard directory. Default is \'overboard\' which corresponds to ./overboard' + ); + $theme['config'][] = Array( + 'title' => 'Max posts in catalog overboard', + 'name' => 'overboard_limit', + 'type' => 'text', + 'default' => '350', + 'comment' => 'The maximum number of thread that will appear in the overboard catalog' + ); // Unique function name for building everything $theme['build_function'] = 'catalog_build'; diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index 75ba3a72..561df2b1 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -17,8 +17,6 @@ // - post-thread (a thread has been made) if ($action === 'all') { foreach ($boards as $board) { - $b = new Catalog($settings); - $action = generation_strategy("sb_catalog", array($board)); if ($action == 'delete') { file_unlink($config['dir']['home'] . $board . '/catalog.html'); @@ -29,6 +27,17 @@ $b->build($settings, $board); } } + if($settings['has_overboard']) { + $board = $settings['overboard_location']; + $action = generation_strategy("sb_catalog", array($board)); + if ($action == 'delete') { + file_unlink($config['dir']['home'] . $board . '/catalog.html'); + file_unlink($config['dir']['home'] . $board . '/index.rss'); + } + elseif ($action == 'rebuild') { + $b->buildOverboardCatalog($settings, $boards); + } + } } elseif ($action == 'post-thread' || ($settings['update_on_posts'] && $action == 'post') || ($settings['update_on_posts'] && $action == 'post-delete') || $action == 'sticky' || ($action == 'lock' && in_array($board, $boards))) { $b = new Catalog($settings); @@ -41,6 +50,9 @@ elseif ($action == 'rebuild') { print_err("catalog_build calling Catalog.build 2"); $b->build($settings, $board); + if($settings['has_overboard']) { + $b->buildOverboardCatalog($settings, $boards); + } } } // FIXME: Check that Ukko is actually enabled @@ -332,6 +344,35 @@ return $sql; } + /** + * Build and save the HTML of the catalog for the overboard + */ + public function buildOverboardCatalog($settings, $boards) { + $board_name = $settings['overboard_location']; + + if (array_key_exists($board_name, $this->threadsCache)) { + $threads = $this->threadsCache[$board_name]; + } else { + $sql = ''; + foreach ($boards as $board) { + $sql .= '('. $this->buildThreadsQuery($board) . ')'; + $sql .= " UNION ALL "; + } + $sql = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC LIMIT :limit', $sql); + $query = prepare($sql); + $query->bindValue(':limit', $settings['overboard_limit'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + $threads = $query->fetchAll(PDO::FETCH_ASSOC); + // Save for posterity + $this->threadsCache[$board_name] = $threads; + } + // Generate data for the template + $recent_posts = $this->generateRecentPosts($threads); + + $this->saveForBoard($board_name, $recent_posts, '/' . $settings['overboard_location']); + } + private function generateRecentPosts($threads) { global $config, $board; diff --git a/templates/themes/semirand/theme.php b/templates/themes/semirand/theme.php index e8d3e56c..cd670a52 100644 --- a/templates/themes/semirand/theme.php +++ b/templates/themes/semirand/theme.php @@ -3,7 +3,7 @@ require 'info.php'; /** - * Generate the board's HTML and move it and its JavaScript in place, whence + * Generate the board's HTML and move it and its JavaScript in place, whence * it's served */ function semirand_build($action, $settings) { @@ -64,7 +64,7 @@ } /** - * Obtain list of all threads from all non-excluded boards + * Obtain list of all threads from all non-excluded boards */ private function fetchThreads() { $query = ''; @@ -87,9 +87,11 @@ /** * Retrieve all replies to a given thread */ - private function fetchReplies($board, $thread_id) { - $query = prepare("SELECT * FROM ``posts_$board`` WHERE `thread` = :id"); + private function fetchReplies($board, $thread_id, $preview_count) { + $query = prepare("SELECT * FROM (SELECT * FROM ``posts_$board`` WHERE `thread` = :id ORDER BY `time` DESC LIMIT :limit) as + t ORDER BY t.time ASC"); $query->bindValue(':id', $thread_id, PDO::PARAM_INT); + $query->bindValue(':limit', $preview_count, PDO::PARAM_INT); $query->execute() or error(db_error($query)); return $query->fetchAll(PDO::FETCH_ASSOC); @@ -131,13 +133,13 @@ openBoard($post['board']); $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod); - $replies = $this->fetchReplies($post['board'], $post['id']); // Number of replies to a thread that are displayed beneath it $preview_count = $post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']; + $replies = $this->fetchReplies($post['board'], $post['id'], $preview_count); // Chomp the last few replies - $disp_replies = array_splice($replies, 0, $preview_count); + $disp_replies = $replies; $disp_img_count = 0; foreach ($disp_replies as $reply) { if ($reply['files'] !== '') @@ -182,7 +184,7 @@ // Fetch threads from all boards and chomp the first 'n' posts, depending // on the setting - $threads = $this->shuffleThreads($this->fetchThreads()); + $threads = $this->fetchThreads(); $total_count = count($threads); // Top threads displayed on load $top_threads = array_splice($threads, 0, $this->settings['thread_limit']);