The version of vichan running on lainchan.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.9KB

  1. <?php
  2. require_once("inc/functions.php");
  3. if (!$config['smart_build']) {
  4. die('You need to enable $config["smart_build"]');
  5. }
  6. $config['smart_build'] = false; // Let's disable it, so we can build the page for real
  7. function after_open_board() { global $config;
  8. $config['smart_build'] = false;
  9. };
  10. function sb_board($b, $page = 1) { global $config, $build_pages; $page = (int)$page;
  11. if ($page < 1) return false;
  12. if (!openBoard($b)) return false;
  13. if ($page > $config['max_pages']) return false;
  14. $config['try_smarter'] = true;
  15. $build_pages = array($page);
  16. buildIndex("skip");
  17. return true;
  18. }
  19. function sb_api_board($b, $page = 0) { $page = (int)$page;
  20. return sb_board($b, $page + 1);
  21. }
  22. function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = (int)$thread;
  23. if ($thread < 1) return false;
  24. if (!preg_match('/^'.$config['board_regex'].'$/u', $b)) return false;
  25. if (Cache::get("thread_exists_".$b."_".$thread) == "no") return false;
  26. $query = prepare(sprintf("SELECT MAX(`id`) AS `max` FROM ``posts_%s``", $b));
  27. if (!$query->execute()) return false;
  28. $s = $query->fetch(PDO::FETCH_ASSOC);
  29. $max = $s['max'];
  30. if ($thread > $max) return false;
  31. $query = prepare(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL", $b));
  32. $query->bindValue(':id', $thread);
  33. if (!$query->execute() || !$query->fetch(PDO::FETCH_ASSOC) ) {
  34. Cache::set("thread_exists_".$b."_".$thread, "no");
  35. return false;
  36. }
  37. if ($slugcheck && $config['slugify']) {
  38. global $request;
  39. $link = link_for(array("id" => $thread), $slugcheck === 50, array("uri" => $b));
  40. $link = "/".$b."/".$config['dir']['res'].$link;
  41. if ($link != $request) {
  42. header("Location: $link", true, 301);
  43. die();
  44. }
  45. }
  46. if ($slugcheck == 50) { // Should we really generate +50 page? Maybe there are not enough posts anyway
  47. global $request;
  48. $r = str_replace("+50", "", $request);
  49. $r = substr($r, 1); // Cut the slash
  50. if (file_exists($r)) return false;
  51. }
  52. if (!openBoard($b)) return false;
  53. buildThread($thread);
  54. return true;
  55. }
  56. function sb_thread_slugcheck($b, $thread) {
  57. return sb_thread($b, $thread, true);
  58. }
  59. function sb_thread_slugcheck50($b, $thread) {
  60. return sb_thread($b, $thread, 50);
  61. }
  62. function sb_api($b) { global $config, $build_pages;
  63. if (!openBoard($b)) return false;
  64. $config['try_smarter'] = true;
  65. $build_pages = array(-1);
  66. buildIndex();
  67. return true;
  68. }
  69. function sb_ukko() {
  70. rebuildTheme("ukko", "post-thread");
  71. return true;
  72. }
  73. function sb_catalog($b) {
  74. if (!openBoard($b)) return false;
  75. rebuildTheme("catalog", "post-thread", $b);
  76. return true;
  77. }
  78. function sb_recent() {
  79. rebuildTheme("recent", "post-thread");
  80. return true;
  81. }
  82. function sb_sitemap() {
  83. rebuildTheme("sitemap", "all");
  84. return true;
  85. }
  86. $entrypoints = array();
  87. $entrypoints['/%b/'] = 'sb_board';
  88. $entrypoints['/%b/'.$config['file_index']] = 'sb_board';
  89. $entrypoints['/%b/'.$config['file_page']] = 'sb_board';
  90. $entrypoints['/%b/%d.json'] = 'sb_api_board';
  91. if ($config['api']['enabled']) {
  92. $entrypoints['/%b/threads.json'] = 'sb_api';
  93. $entrypoints['/%b/catalog.json'] = 'sb_api';
  94. }
  95. $entrypoints['/%b/'.$config['dir']['res'].$config['file_page']] = 'sb_thread_slugcheck';
  96. $entrypoints['/%b/'.$config['dir']['res'].$config['file_page50']] = 'sb_thread_slugcheck50';
  97. if ($config['slugify']) {
  98. $entrypoints['/%b/'.$config['dir']['res'].$config['file_page_slug']] = 'sb_thread_slugcheck';
  99. $entrypoints['/%b/'.$config['dir']['res'].$config['file_page50_slug']] = 'sb_thread_slugcheck50';
  100. }
  101. if ($config['api']['enabled']) {
  102. $entrypoints['/%b/'.$config['dir']['res'].'%d.json'] = 'sb_thread';
  103. }
  104. $entrypoints['/*/'] = 'sb_ukko';
  105. $entrypoints['/*/index.html'] = 'sb_ukko';
  106. $entrypoints['/recent.html'] = 'sb_recent';
  107. $entrypoints['/%b/catalog.html'] = 'sb_catalog';
  108. $entrypoints['/sitemap.xml'] = 'sb_sitemap';
  109. $reached = false;
  110. $request = $_SERVER['REQUEST_URI'];
  111. list($request) = explode('?', $request);
  112. foreach ($entrypoints as $id => $fun) {
  113. $id = '@^' . preg_quote($id, '@') . '$@u';
  114. $id = str_replace('%b', '('.$config['board_regex'].')', $id);
  115. $id = str_replace('%d', '([0-9]+)', $id);
  116. $id = str_replace('%s', '[a-zA-Z0-9-]+', $id);
  117. $matches = null;
  118. if (preg_match ($id, $request, $matches)) {
  119. array_shift($matches);
  120. $reached = call_user_func_array($fun, $matches);
  121. break;
  122. }
  123. }
  124. function die_404() { global $config;
  125. if (!$config['page_404']) {
  126. header("HTTP/1.1 404 Not Found");
  127. header("Status: 404 Not Found");
  128. echo "<h1>404 Not Found</h1><p>Page doesn't exist<hr><address>vichan</address>";
  129. }
  130. else {
  131. header("Location: ".$config['page_404']);
  132. }
  133. header("X-Accel-Expires: 120");
  134. die();
  135. }
  136. if ($reached) {
  137. if ($request[strlen($request)-1] == '/') {
  138. $request .= 'index.html';
  139. }
  140. $request = '.'.$request;
  141. if (!file_exists($request)) {
  142. die_404();
  143. }
  144. header("HTTP/1.1 200 OK");
  145. header("Status: 200 OK");
  146. if (preg_match('/\.json$/', $request)) {
  147. header("Content-Type", "application/json");
  148. }
  149. elseif (preg_match('/\.js$/', $request)) {
  150. header("Content-Type", "text/javascript; charset=utf-8");
  151. }
  152. elseif (preg_match('/\.xml$/', $request)) {
  153. header("Content-Type", "application/xml");
  154. }
  155. else {
  156. header("Content-Type", "text/html; charset=utf-8");
  157. }
  158. header("Cache-Control: public, nocache, no-cache, max-age=0, must-revalidate");
  159. header("Expires: Fri, 22 Feb 1991 06:00:00 GMT");
  160. header("Last-Modified: ".date('r', filemtime($request)));
  161. //if (isset ($_SERVER['HTTP_ACCEPT_ENCODING']) && preg_match('/gzip/', $_SERVER['HTTP_ACCEPT_ENCODING']) && file_exists($request.".gz")) {
  162. // header("Content-Encoding: gzip");
  163. // $file = fopen($request.".gz", 'r');
  164. //}
  165. //else {
  166. $file = fopen($request, 'r');
  167. //}
  168. fpassthru($file);
  169. fclose($file);
  170. }
  171. else {
  172. die_404();
  173. }