PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/index.php

https://github.com/pastak/jichikai_web
PHP | 664 lines | 529 code | 66 blank | 69 comment | 86 complexity | a008187c1d1ea2d267737ff26d159e33 MD5 | raw file
  1. <?php // LionWiki 3.2.4, (c) Adam Zivner, licensed under GNU/GPL v2
  2. //require("plugins/HatenaSyntax_for_php4.php");
  3. session_start();
  4. require("plugins/original_HatenaSyntax.php");
  5. require("plugins/BlogList.php");
  6. print_r($_SESSION);
  7. foreach($_REQUEST as $k => $v)
  8. unset($$k); // register_globals = off
  9. $START_PAGE = 'MainPage'; // Which page should be default (start page)?
  10. $SYNTAX_PAGE = 'http://lionwiki.0o.cz/?page=Syntax+reference';
  11. $DATE_FORMAT = 'Y/m/d H:i';
  12. $LOCAL_HOUR = 0;
  13. $bl=new BlogList();
  14. @error_reporting(E_ERROR | E_WARNING | E_PARSE);
  15. @ini_set('default_charset', 'UTF-8');
  16. set_magic_quotes_runtime(0);
  17. umask(0);
  18. if(get_magic_quotes_gpc()) // magic_quotes_gpc can't be turned off
  19. for($i = 0, $_SG = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST), $c = count($_SG); $i < $c; ++$i)
  20. $_SG[$i] = array_map('stripslashes', $_SG[$i]);
  21. //$self =$_SERVER['REQUEST_URI'];
  22. $self = basename($_SERVER['PHP_SELF']);
  23. $REAL_PATH = realpath(dirname(__FILE__)).'/';
  24. $VAR_DIR = 'var/';
  25. $PG_DIR = $VAR_DIR.'pages/';
  26. $HIST_DIR = $VAR_DIR.'history';
  27. $PLUGINS_DIR = 'plugins/';
  28. $PLUGINS_DATA_DIR = $VAR_DIR.'plugins/';
  29. $LANG_DIR = 'lang/';
  30. @include('config.php'); // config file is not required, see settings above
  31. // default translation
  32. $ARCON=$bl->BlogList(null,true);
  33. $T_HOME = 'MainPage';
  34. $T_SYNTAX = '記法について';
  35. $T_DONE = '保存する';
  36. $T_DISCARD_CHANGES = 'Discard changes';
  37. $T_PREVIEW = 'Preview';
  38. $T_SEARCH = 'Search';
  39. $T_SEARCH_RESULTS = 'Search results';
  40. $T_LIST_OF_ALL_PAGES = 'List of all pages';
  41. $T_RECENT_CHANGES = 'Recent changes';
  42. $T_LAST_CHANGED = 'Last changed';
  43. $T_HISTORY = 'History';
  44. $T_RESTORE = 'Restore';
  45. $T_REV_DIFF = '<b>Difference between revisions from {REVISION1} and {REVISION2}.</b>';
  46. $T_REVISION = "'''This revision is from {TIME}. You can {RESTORE} it.'''\n\n";
  47. $T_PASSWORD = 'Password';
  48. $T_EDIT = 'このページを編集する';
  49. $T_EDIT_SUMMARY = 'Summary of changes';
  50. $T_EDIT_CONFLICT = 'Edit conflict: somebody saved this page after you started editing. See last {DIFF} before saving your changes.';
  51. $T_SHOW_SOURCE = 'Show source';
  52. $T_SHOW_PAGE = 'Show page';
  53. $T_ERASE_COOKIE = 'Erase cookies';
  54. $T_MOVE_TEXT = 'ページ名';
  55. $T_DIFF = 'diff';
  56. $T_CREATE_PAGE = 'Create page';
  57. $T_PROTECTED_READ = 'You need to enter password to view content of site: ';
  58. $T_WRONG_PASSWORD = 'Password is incorrect.';
  59. $filetext=file_get_contents($PG_DIR."/".$_GET["page"].".txt");
  60. $filecon=preg_split("/\n/",$filetext);
  61. $text=$filecon[0];
  62. $blogTitle=substr($text,1);
  63. $blogTitle=strip_tags($blogTitle);
  64. if($_GET['lang']) {
  65. $LANG = clear_path($_GET['lang']);
  66. setcookie('LW_LANG', $LANG, time() + 365 * 86400);
  67. } elseif($_COOKIE['LW_LANG'])
  68. $LANG = clear_path($_COOKIE['LW_LANG']);
  69. else
  70. list($LANG) = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  71. $LANG = 'en';
  72. // Creating essential directories if they don't exist
  73. /*
  74. if(!file_exists($VAR_DIR) && !mkdir(rtrim($VAR_DIR, "/")))
  75. die("Can't create directory $VAR_DIR. Please create $VAR_DIR with 0777 rights.");
  76. else foreach(array($PG_DIR, $HIST_DIR, $PLUGINS_DATA_DIR) as $DIR)
  77. if(@mkdir(rtrim($DIR, '/'), 0777)) {
  78. $f = fopen($DIR . ".htaccess", "w"); fwrite($f, "deny from all"); fclose($f); }
  79. */
  80. if($_GET['erasecookie']) // remove cookie without reloading
  81. foreach($_COOKIE as $k => $v)
  82. if(substr($k, 0, 3) == 'LW_') {
  83. setcookie($k);
  84. unset($_COOKIE[$k]);
  85. }
  86. for($plugins = array(), $dir = @opendir($PLUGINS_DIR); $dir && $f = readdir($dir);) // load plugins
  87. $f = readdir($dir);
  88. if(preg_match('/wkp_(.+)\.php$/', $f, $m) > 0) {
  89. //check plugin is off?
  90. /*
  91. foreach($Off_Plugins as $_pluginname){
  92. if($_chkpluginoff || $f=="wkp_".$_pluginname.".php"){
  93. $_chkpluginoff=true;
  94. break;
  95. }
  96. }
  97. if($_chkpluginoff){continue;}
  98. */
  99. require $PLUGINS_DIR . $f;
  100. $plugins[$m[1]] = new $$m[1]();
  101. if(isset($$m[1])){
  102. foreach($m[1] as $name => $value){
  103. $plugins[$m[1]]->$name = $value;
  104. }
  105. }
  106. }
  107. //echo"aa";
  108. //here is end of loading plugins
  109. plugin('pluginsLoaded');
  110. foreach(array('action', 'content', 'error', 'esum', 'f1', 'f2', 'last_changed', 'moveto', 'page', 'par', 'preview', 'query', 'restore', 'sc', 'showsource', 'time') as $req)
  111. $$req = $_REQUEST[$req]; // export request variables to global namespace
  112. $TITLE = $page = clear_path($page); $moveto = clear_path($moveto); $f1 = clear_path($f1); $f2 = clear_path($f2);
  113. $CON = $content;
  114. plugin('actionBegin');
  115. if(!$action)
  116. if(!$page)
  117. die(header("Location:$self?page=" . u($START_PAGE)));
  118. elseif(file_exists("$PG_DIR$page.$LANG.txt")) // language variant
  119. die(header("Location:$self?page=" . u("$page.$LANG")));
  120. elseif(!file_exists("$PG_DIR$page.txt"))
  121. $action = 'edit'; // create page if it doesn't exist
  122. if($PROTECTED_READ && !authentified()) { // does user need password to read content of site. If yes, ask for it.
  123. $CON = "<form action=\"$self?page=".u($page)."\" method=\"post\"><p>$T_PROTECTED_READ <input type=\"password\" name=\"sc\"/> <input class=\"submit\" type=\"submit\"/></p></form>";
  124. $action = 'view-html';
  125. } else
  126. if($restore || $action == 'rev') { // Show old revision
  127. $CON = @file_get_contents("$HIST_DIR$page/$f1");
  128. if($action == 'rev') {
  129. $rev_restore = "[$T_RESTORE|./$self?page=".u($page)."&amp;action=edit&amp;f1=$f1&amp;restore=1]";
  130. $CON = strtr($T_REVISION, array('{TIME}' => rev_time($f1), '{RESTORE}' => $rev_restore)) . $CON;
  131. $action = '';
  132. }
  133. } else if($page) { // Load the page
  134. $last_changed_ts = @filemtime("$PG_DIR$page.txt");
  135. if(!$action || $action == 'edit') {
  136. $CON = @file_get_contents("$PG_DIR$page.txt");
  137. $CON = $par ? get_paragraph($CON, $par) : $CON;
  138. if(!$action && substr($CON, 0, 10) == '{redirect:' && $_REQUEST['redirect'] != 'no')
  139. die(header("Location:$self?page=".u(substr($CON, 10, strpos($CON, '}') - 10))));
  140. }
  141. }
  142. if($action == 'save' && !$preview && authentified()) { // do we have page to save?
  143. if(!trim($content) && !$par) // delete empty page
  144. @unlink("$PG_DIR$page.txt");
  145. elseif($last_changed < @filemtime("$PG_DIR$page.txt")) {
  146. $action = 'edit';
  147. $error = str_replace('{DIFF}', "<a href=\"$self?page=".u($page)."&amp;action=diff\">$T_DIFF</a>", $T_EDIT_CONFLICT);
  148. } elseif(!plugin('writingPage')) { // are plugins OK with page? (e.g. checking for spam)
  149. if($par) {
  150. $c = @file_get_contents("$PG_DIR$page.txt");
  151. $content = str_replace(get_paragraph($c, $par), $content, $c);
  152. }
  153. if(!$file = @fopen("$PG_DIR$page.txt", 'w'))
  154. die("Could not write page $PG_DIR$page.txt!");
  155. fwrite($file,$content); fclose($file);
  156. /**
  157. // Backup old revision
  158. @mkdir($HIST_DIR.$page, 0777); // Create directory if does not exist
  159. $rightnow = date('Ymd-Hi-s', time() + $LOCAL_HOUR * 3600);
  160. if(!$bak = @fopen("$HIST_DIR$page/$rightnow.bak", 'w'))
  161. die("Could not write to $HIST_DIR$page!");
  162. fwrite($bak, $content); fclose($bak);
  163. $es = fopen("$HIST_DIR$page/meta.dat", 'ab');
  164. fwrite($es, '!' . $rightnow .
  165. str_pad($_SERVER['REMOTE_ADDR'], 16, ' ', STR_PAD_LEFT) .
  166. str_pad(filesize("$PG_DIR$page.txt"), 11, ' ', STR_PAD_LEFT) . ' ' .
  167. str_pad(substr($esum, 0, 128), 128 + 2)) . "\n";
  168. fclose($es);
  169. if($moveto != $page && $moveto)
  170. if(file_exists("$PG_DIR$moveto.txt"))
  171. die('Error: target filename already exists. Page was not moved.');
  172. elseif(!rename("$PG_DIR$page.txt", "$PG_DIR$moveto.txt"))
  173. die('Unknown error! Page was not moved.');
  174. elseif(!rename($HIST_DIR.$page, $HIST_DIR.$moveto)) {
  175. rename("$PG_DIR$moveto.txt", "$PG_DIR$page.txt"); // revert previous change
  176. die('Unknown error2! Page was not moved.');
  177. } else
  178. $page = $moveto;
  179. **/
  180. if(!plugin('pageWritten'))
  181. die(header("Location:$self?page=" . u($page) . '&redirect=no' . ($par ? "&par=$par" : '') . ($_REQUEST['ajax'] ? '&ajax=1' : '')));
  182. else
  183. $action = ''; // display content ...
  184. } else // there's some problem with page, give user a chance to fix it
  185. $action = 'edit';
  186. } elseif($action == 'save' && !$preview) { // wrong password, give user another chance
  187. $error = $T_WRONG_PASSWORD;
  188. $action = 'edit';
  189. }
  190. if($action == 'edit' || $preview) {
  191. $CON_FORM_BEGIN = "<form action=\"$self\" method=\"post\" onsubmit=\"editor.submit(this);return false\"><input type=\"hidden\" name=\"action\" value=\"save\"/><input type=\"hidden\" name=\"last_changed\" value=\"$last_changed_ts\"/><input type=\"hidden\" name=\"showsource\" value=\"$showsource\"/><input type=\"hidden\" name=\"par\" value=\"".h($par)."\"/><input type=\"hidden\" name=\"page\" value=\"".h($page)."\"/>";
  192. $CON_FORM_END = '</form>';
  193. $CON_TEXTAREA = '<textarea class="contentTextarea" name="content" style="width:100%" cols="100" rows="30">'.h($CON).'</textarea>';
  194. $CON_PREVIEW = '<input class="submit" type="button" name="preview" value="'.$T_PREVIEW.'" onClick="editor.preview()" "/>';
  195. if(!$showsource) {
  196. $CON_SUBMIT = '<input class="submit" type="submit" value="'.$T_DONE.'"/>';
  197. $EDIT_SUMMARY_TEXT = $T_EDIT_SUMMARY;
  198. $EDIT_SUMMARY = '<input type="text" name="esum" value="'.h($esum).'"/>';
  199. if(!authentified()) { // if not logged on, require password
  200. $FORM_PASSWORD = $T_PASSWORD;
  201. $FORM_PASSWORD_INPUT = '<input type="password" name="sc"/>';
  202. }
  203. if(!$par) {
  204. if(isset($_SESSION['jichikaiLogin'])){
  205. if($_GET["blog"]==="true"|preg_match("/^_Blog__/",$_GET["page"])){
  206. $RENAME_TEXT = "ブログ編集モード<br />";
  207. $RENAME_INPUT = '<input type="hidden" name="moveto" value="'.h($page).'"/>';
  208. }else{
  209. $RENAME_TEXT = $T_MOVE_TEXT;
  210. $RENAME_INPUT = '<input type="text" name="moveto" value="'.h($page).'"/>';
  211. }
  212. }else{
  213. $RENAME_INPUT ="ログインしてください";
  214. }
  215. }
  216. }
  217. if($preview)
  218. $TITLE = "$T_PREVIEW: $page";
  219. } elseif($action == 'history') { // show whole history of page
  220. for($dir = @opendir("$HIST_DIR$page/"); $f = @readdir($dir);)
  221. if(substr($f, -4) == '.bak')
  222. $files[] = $f;
  223. rsort($files);
  224. $CON = '<form action="'.$self.'" method="get"><input type="hidden" name="action" value="diff"/><input type="hidden" name="page" value="'.h($page).'"/><input type="submit" class="submit" value="'.$T_DIFF.'"/><br/>';
  225. $meta = @fopen("$HIST_DIR$page/meta.dat", "rb");
  226. for($i = 0, $mi = 1, $c = count($files); $i < $c; $i++) {
  227. if(($m = meta_getline($meta, $mi)) && !strcmp(basename($files[$i], ".bak"), $m[0]))
  228. $mi++;
  229. $CON .= '<input type="radio" name="f1" value="'.h($files[$i]).'"/><input type="radio" name="f2" value="'.h($files[$i]).'"/>';
  230. $CON .= "<a href=\"$self?page=".u($page)."&amp;action=rev&amp;f1=".$files[$i]."\">".rev_time($files[$i])."</a> - ($m[2] B) $m[1] <i>".h($m[3])."</i><br/>";
  231. }
  232. $CON .= '</form>';
  233. }
  234. elseif($action == 'search') {
  235. for($files = array(), $dir = opendir($PG_DIR); $f = readdir($dir);)
  236. if(substr($f, -4) == '.txt' && ($c = @file_get_contents($PG_DIR . $f)))
  237. if(!$query || stristr($f . $c, $query) !== false)
  238. $files[] = substr($f, 0, -4);
  239. sort($files);
  240. foreach($files as $f)
  241. $list .= "<li><a href=\"$self?page=".u($f).'&amp;redirect=no">'.h($f)."</a></li>";
  242. $CON = "<ul>$list</ul>";
  243. if($query && !file_exists("$PG_DIR$query.txt")) // offer to create the page
  244. $CON = "<p><i><a href=\"$self?action=edit&amp;page=".u($query)."\">$T_CREATE_PAGE ".h($query)."</a>.</i></p>".$CON;
  245. $TITLE = (!$query ? $T_LIST_OF_ALL_PAGES : "$T_SEARCH_RESULTS $query") . " (".count($files).")";
  246. } elseif($action == 'recent') { // recent changes
  247. for($files = array(), $dir = opendir($PG_DIR); $f = readdir($dir);)
  248. if(substr($f, -4) == '.txt')
  249. $files[substr($f, 0, -4)] = filemtime($PG_DIR . $f);
  250. arsort($files);
  251. foreach(array_slice($files, 0, 100) as $f => $ts) { // just first 100 files
  252. if($meta = @fopen($HIST_DIR . basename($f, '.txt') . '/meta.dat', 'r')) {
  253. $m = meta_getline($meta, 1);
  254. fclose($meta);
  255. }
  256. $recent .= "<tr><td class=\"rc-diff\"><a href=\"$self?page=".u($f)."&amp;action=diff\">$T_DIFF</a></td><td class=\"rc-date\" nowrap>".date($DATE_FORMAT, $ts + $LOCAL_HOUR * 3600)."</td><td class=\"rc-ip\">$m[1]</td><td class=\"rc-page\"><a href=\"$self?page=".u($f)."&amp;redirect=no\">".h($f)."</a> <span class=\"rc-size\">($m[2] B)</span><i class=\"rc-esum\"> ".h($m[3])."</i></td></tr>";
  257. }
  258. $CON = "<table>$recent</table>";
  259. $TITLE = $T_RECENT_CHANGES;
  260. } else
  261. plugin('action', $action);
  262. if(!$action || $preview) { // page parsing
  263. if(preg_match("/(?<!\^)\{title:([^}\n]*)\}/U", $CON, $m)) { // Change page title
  264. $TITLE = $m[1];
  265. $CON = str_replace($m[0], "", $CON);
  266. }
  267. // subpages
  268. while(preg_match('/(?<!\^){include:([^}]+)}/Um', $CON, $m))
  269. if(!strcmp($m[1], $page)) // limited recursion protection
  270. $CON = str_replace($m[0], "'''Warning: subpage recursion!'''", $CON);
  271. elseif(file_exists("$PG_DIR$m[1].txt"))
  272. $CON = str_replace($m[0], file_get_contents("$PG_DIR$m[1].txt"), $CON);
  273. else
  274. $CON = str_replace($m[0], "'''Warning: subpage $m[1] was not found!'''", $CON);
  275. plugin('subPagesLoaded');
  276. // save content not intended for substitutions ({html} tag)
  277. if(!$NO_HTML) { // XSS protection
  278. preg_match_all("/(?<!\^)\{html\}(.+)\{\/html\}/Ums", $CON, $htmlcodes, PREG_PATTERN_ORDER);
  279. $CON = preg_replace("/(?<!\^)\{html\}.+\{\/html\}/Ums", "{HTML}", $CON);
  280. }
  281. $CON = preg_replace("/(?<!\^)<!--.*-->/U", "", $CON); // internal comments
  282. $CON = preg_replace("/\^(.)/e", "'&#'.ord('$1').';'", $CON);
  283. //$CON = str_replace(array("<", "&"), array("&lt;", "&amp;"), $CON);
  284. $CON = preg_replace("/&amp;([a-z]+;|\#[0-9]+;)/U", "&$1", $CON); // keep HTML entities
  285. $CON = preg_replace("/(\r\n|\r)/", "\n", $CON); // unifying newlines to Unix ones
  286. preg_match_all("/{{(.+)}}/Ums", $CON, $codes, PREG_PATTERN_ORDER);
  287. $CON = preg_replace("/{{(.+)}}/Ums", "<pre>{CODE}</pre>", $CON);
  288. // spans
  289. preg_match_all("/\{([\.#][^\s\"\}]*)(\s([^\}\"]*))?\}/m", $CON, $spans, PREG_SET_ORDER);
  290. foreach($spans as $m) {
  291. $class = $id = '';
  292. $parts = preg_split('/([\.#])/', $m[1], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
  293. for($i = 0, $c = count($parts); $c > 1 && $i < $c; $i += 2)
  294. if($parts[$i] == '.')
  295. $class .= $parts[$i + 1] . ' ';
  296. else
  297. $id = $parts[$i + 1];
  298. $CON = str_replace($m[0], '<span'.($id ? " id=\"$id\"" : '').($class ? " class=\"$class\"" : '').($m[3] ? " style=\"$m[3]\"" : '').'>', $CON);
  299. }
  300. $hs=new HatenaSyntax(); //convert hatena syntax class
  301. //$CON = str_replace('{/}', '</span>', $CON);
  302. $CON=$hs->ConvertHatenaSyntax("$CON");
  303. plugin('formatBegin');
  304. /*
  305. $CON = strtr($CON, array('&lt;-->' => '&harr;', '-->' => '&rarr;', '&lt;--' => '&larr;', "(c)" => '&copy;', "(r)" => '&reg;'));
  306. $CON = preg_replace("/\{small\}(.*)\{\/small\}/U", "<small>$1</small>", $CON); // small
  307. $CON = preg_replace("/\{su([bp])\}(.*)\{\/su([bp])\}/U", "<su$1>$2</su$3>", $CON); // sup and sub
  308. $CON = preg_replace("/^([^!\*#\n][^\n]+)$/Um", '<p>$1</p>', $CON); // paragraphs
  309. // images
  310. preg_match_all("#\[((https?://|\./)[^\]]+\.(jpeg|jpg|gif|png))(\|[^\]]+)?\]#", $CON, $imgs, PREG_SET_ORDER);
  311. foreach($imgs as $img) {
  312. $link = $i_attr = $a_attr = $center = $tag = "";
  313. preg_match_all("/\|([^\]\|=]+)(=([^\]\|\"]+))?(?=[\]\|])/", $img[0], $options, PREG_SET_ORDER);
  314. foreach($options as $o)
  315. if($o[1] == 'center') $center = true;
  316. elseif($o[1] == 'right' || $o[1] == 'left') $i_attr .= " style=\"float:$o[1]\"";
  317. elseif($o[1] == 'link') $link = (substr($o[3], 0, 4) == "http" || substr($o[3], 0, 2) == "./") ? $o[3] : "$self?page=" . u($o[3]);
  318. elseif($o[1] == 'alt') $i_attr .= " alt=\"$o[3]\"";
  319. elseif($o[1] == 'title') $a_attr .= " title=\"$o[3]\"";
  320. $tag = "<img src=\"$img[1]\"$i_attr/>";
  321. if($link) $tag = "<a href=\"$link\"$a_attr>$tag</a>";
  322. if($center) $tag = "<div style=\"text-align:center\">$tag</div>";
  323. $CON = str_replace($img[0], $tag, $CON);
  324. }
  325. $CON = preg_replace('#([0-9a-zA-Z\./~\-_]+@[0-9a-z/~\-_]+\.[0-9a-z\./~\-_]+)#i', '<a href="mailto:$0">$0</a>', $CON); // mail recognition
  326. // links
  327. $CON = preg_replace("#\[([^\]\|]+)\|(\./([^\]]+)|(https?://[^\]]+))\]#U", '<a href="$2" class="external">$1</a>', $CON);
  328. $CON = preg_replace("#(?<!\")https?://[0-9a-zA-Z\.\#/~\-_%=\?\&,\+\:@;!\(\)\*\$']*#i", '<a href="$0" class="external">$0</a>', $CON);
  329. preg_match_all("/\[(?:([^|\]]+)\|)?([^\]#]+)(?:#([^\]]+))?\]/", $CON, $matches, PREG_SET_ORDER); // matching Wiki links
  330. foreach($matches as $m) {
  331. $m[1] = $m[1] ? $m[1] : $m[2]; // is page label same as its name?
  332. $m[3] = $m[3] ? '#'.u(preg_replace('/[^\da-z]/i', '_', $m[3])) : ''; // anchor
  333. $attr = file_exists("$PG_DIR$m[2].txt") ? $m[3] : '&amp;action=edit" class="pending';
  334. $CON = str_replace($m[0], '<a href="'.$self.'?page='.u($m[2]).$attr.'">'.$m[1].'</a>', $CON);
  335. }
  336. for($i = 10; $i >= 1; $i--) { // Lists, ordered, unordered
  337. $CON = preg_replace('/^'.str_repeat('\*', $i)."(.*)(\n?)/m", str_repeat('<ul>', $i).'<li>$1</li>'.str_repeat('</ul>', $i).'$2', $CON);
  338. $CON = preg_replace('/^'.str_repeat('\#', $i)."(.*)(\n?)/m", str_repeat('<ol>', $i).'<li>$1</li>'.str_repeat('</ol>', $i).'$2', $CON);
  339. $CON = preg_replace("#(</ol>\n?<ol>|</ul>\n?<ul>)#", '', $CON);
  340. }
  341. // headings
  342. preg_match_all('/^(!+)(.*)$/m', $CON, $matches, PREG_SET_ORDER);
  343. $stack = array();
  344. for($h_id = max($par, 1), $i = 0, $c = count($matches); $i < $c && $m = $matches[$i]; $i++, $h_id++) {
  345. $excl = strlen($m[1]) + 1;
  346. $hash = preg_replace('/[^\da-z]/i', '_', $m[2]);
  347. for($ret = ''; end($stack) >= $excl; $ret .= '</div>', array_pop($stack));
  348. $stack[] = $excl;
  349. $ret .= "<div class=\"par-div\" id=\"par-$h_id\"><h$excl id=\"$hash\">$m[2]";
  350. if(is_writable($PG_DIR . $page . '.txt'))
  351. $ret .= "<span class=\"par-edit\">(<a href=\"$self?action=edit&amp;page=".u($page)."&amp;par=$h_id\">$T_EDIT</a>)</span>";
  352. $CON = preg_replace('/' . preg_quote($m[0], '/') . '/', "$ret</h$excl>", $CON, 1);
  353. $TOC .= str_repeat("<ul>", $excl - 2).'<li><a href="'.$self.'?page='.u($page).'#'.u($hash).'">'.$m[2].'</a></li>'.str_repeat("</ul>", $excl - 2);
  354. }
  355. $CON .= str_repeat('</div>', count($stack));
  356. $TOC = '<ul id="toc">' . preg_replace(array_fill(0, 5, "#</ul>\n*<ul>#"), array_fill(0, 5, ''), $TOC) . '</ul>';
  357. $TOC = str_replace(array('</li><ul>', '</ul><li>', '</ul></ul>', '<ul><ul>'), array('<ul>', '</ul></li><li>', '</ul></li></ul>', '<ul><li><ul>'), $TOC);
  358. $CON = preg_replace("/'--(.*)--'/Um", '<del>$1</del>', $CON); // strikethrough
  359. $CON = preg_replace("/'__(.*)__'/Um", '<u>$1</u>', $CON); // underlining
  360. $CON = preg_replace("/'''(.*)'''/Um", '<strong>$1</strong>', $CON); // bold
  361. $CON = preg_replace("/''(.*)''/Um", '<em>$1</em>', $CON); // italic
  362. $CON = str_replace('{br}', '<br style="clear:both"/>', $CON); // new line
  363. */
  364. //$CON = preg_replace('/-----*/', '<hr/>', $CON); // horizontal line
  365. /*
  366. $CON = str_replace('--', '&mdash;', $CON); // --
  367. $CON = preg_replace(array_fill(0, count($codes[1]) + 1, '/{CODE}/'), $codes[1], $CON, 1); // put HTML and "normal" codes back
  368. $CON = preg_replace(array_fill(0, count($htmlcodes[1]) + 1, '/{HTML}/'), $htmlcodes[1], $CON, 1);
  369. */
  370. }
  371. plugin('formatEnd');
  372. plugin('formatFinished');
  373. // Loading template. If does not exist, use built-in default
  374. $html = file_exists($TEMPLATE) ? file_get_contents(clear_path($TEMPLATE)) : fallback_template();
  375. // including pages in pure HTML
  376. while(preg_match('/{include:([^}]+)}/U', $html, $m)) {
  377. $inc = str_replace(array('{html}', '{/html}'), '', @file_get_contents("$PG_DIR$m[1].txt"));
  378. $html = str_replace($m[0], $inc, $html);
  379. }
  380. plugin('template');
  381. $html = preg_replace('/\{([^}]* )?plugin:.+( [^}]*)?\}/U', '', $html); // get rid of absent plugin tags
  382. $hs_ex=new HatenaSyntax();
  383. //this part is setting on Template Tag
  384. $tpl_subs = array(
  385. 'HOME_URL' =>'?page=MainPage',
  386. 'INFO_URL' =>'?page=infomation',
  387. 'MEMBER_URL' =>'?page=members',
  388. 'ARCHIVES_URL'=>'?page=MainPage&Archives=1',
  389. 'CONTACT_URL'=>'?page=contact_us',
  390. 'MAKE_NEW_ARTICLE'=>'<a href="?blog=true&page=_Blog__'.date("YmdHmi").'&action=edit">ブログ新規記事を作成する</a>',
  391. 'SYNTAX_EXPLAIN'=>$action == "edit" || $preview ?preg_replace("/\!--/","<br /><a href='#syntax_explain'>▲先頭に戻る</a><hr />",$hs_ex->ConvertHatenaSyntax(file_get_contents("syntax_explain.txt"))):"",
  392. 'TOOLBAR'=>isset($_SESSION['jichikaiLogin'])?
  393. $action == "edit" || $preview ?file_get_contents("plugins/toolbar.html"):""
  394. :"",
  395. 'BlogArticleList'=>$bl->BlogList(5),
  396. 'EditInfo'=>isset($_SESSION['jichikaiLogin'])?"|{MAKE_NEW_ARTICLE}|{EDIT}|":"{LOGIN}",
  397. 'LOGIN'=>'|<form action="logincheck.php" method="post"><input name="backto" type="hidden" value="?page='.$page.'" /><label>ユーザー名 <input name="user" type="text" size="20" /></label>|<label>パスワード <input type="password" name="pass" size="20" /></label>|<input type="submit" size="15" value="ログイン" /></form>|',
  398. 'HEAD' => $HEAD . ($action ? '<meta name="robots" content="noindex, nofollow"/>' : ''),
  399. 'SEARCH_FORM' => '<form action="'.$self.'" method="get"><span><input type="hidden" name="action" value="search"/><input type="submit" style="display:none;"/>',
  400. '\/SEARCH_FORM' => "</span></form>",
  401. 'SEARCH_INPUT' => '<input type="text" name="query" value="'.h($query).'"/>',
  402. 'SEARCH_SUBMIT' => "<input class=\"submit\" type=\"submit\" value=\"$T_SEARCH\"/>",
  403. 'HOME' => "<a href=\"$self?page=".u($START_PAGE)."\">$T_HOME</a>",
  404. 'RECENT_CHANGES' => "<a href=\"$self?action=recent\">$T_RECENT_CHANGES</a>",
  405. 'ERROR' => $error,
  406. 'HISTORY' => $page ? "<a href=\"$self?page=".u($page)."&amp;action=history\">$T_HISTORY</a>" : "",
  407. //'PAGE_TITLE' => h($page == $START_PAGE && $page == $TITLE ? $WIKI_TITLE : $TITLE),
  408. 'PAGE_TITLE_HEAD' => preg_match("/_Blog__/",$page) ? $blogTitle : ($_GET["Archives"] ? "Archives" : h($TITLE) ),
  409. 'PAGE_URL' => u($page),
  410. 'EDIT' => !$action ? ("<a href=\"$self?page=".u($page)."&amp;action=edit".(is_writable("$PG_DIR$page.txt") ? "\">$T_EDIT</a>" : "&amp;showsource=1\">$T_SHOW_SOURCE</a>")) : "",
  411. 'WIKI_TITLE' => h($WIKI_TITLE),
  412. 'LAST_CHANGED_TEXT' => $last_changed_ts ? $T_LAST_CHANGED : "",
  413. 'LAST_CHANGED' => $last_changed_ts ? date($DATE_FORMAT, $last_changed_ts + $LOCAL_HOUR * 3600) : "",
  414. 'CONTENT' => $action != "edit" ? $_GET["Archives"] ? $ARCON : $CON : "",
  415. 'TOC' => $TOC,
  416. 'SYNTAX' => isset($_SESSION['jichikaiLogin'])?
  417. $action == "edit" || $preview ? "<a href='javascript:void(0);' onClick='Show_Syntax(this)'>▼記法について</a>" : ""
  418. :"",
  419. 'SHOW_PAGE' => $action == "edit" || $preview ? "<a href=\"$self?page=".u($page)."\">$T_SHOW_PAGE</a>" : "",
  420. 'COOKIE' => '<a href="'.$self.'?page='.u($page).'&amp;action='.u($action).'&amp;erasecookie=1">'.$T_ERASE_COOKIE.'</a>',
  421. 'CONTENT_FORM' => isset($_SESSION['jichikaiLogin'])?$CON_FORM_BEGIN:"",
  422. '\/CONTENT_FORM' => isset($_SESSION['jichikaiLogin'])?$CON_FORM_END:"",
  423. 'CONTENT_TEXTAREA' => isset($_SESSION['jichikaiLogin'])?$CON_TEXTAREA:"",
  424. 'CONTENT_SUBMIT' => isset($_SESSION['jichikaiLogin'])?$CON_SUBMIT:"",
  425. 'CONTENT_PREVIEW' => isset($_SESSION['jichikaiLogin'])?$CON_PREVIEW:"",
  426. 'RENAME_TEXT' => $RENAME_TEXT,
  427. 'RENAME_INPUT' => $RENAME_INPUT,
  428. 'EDIT_SUMMARY_TEXT' => $EDIT_SUMMARY_TEXT,
  429. 'EDIT_SUMMARY_INPUT' => $EDIT_SUMMARY,
  430. 'FORM_PASSWORD' => $FORM_PASSWORD,
  431. 'FORM_PASSWORD_INPUT' => $FORM_PASSWORD_INPUT
  432. );
  433. foreach($tpl_subs as $tpl => $rpl) // substituting values
  434. $html = template_replace($tpl, $rpl, $html);
  435. foreach($tpl_subs as $tpl => $rpl) // substituting values
  436. $html = template_replace($tpl, $rpl, $html);
  437. header('Content-type: text/html; charset=UTF-8');
  438. die($html);
  439. // Function library
  440. function h($t) { return htmlspecialchars($t); }
  441. function u($t) { return urlencode($t); }
  442. function template_replace($what, $subs, $where) { return preg_replace("/\{(([^}]*) )?$what( ([^}]*))?\}/U", empty($subs) ? "" : "\${2}".str_replace("$", "&#36;", trim($subs))."\${4}", $where); }
  443. function template_match($what, $where, &$dest) { return preg_match("/\{(([^}]*) )?$what( ([^}]*))?\}/U", $where, $dest); }
  444. function clear_path($s) {
  445. for($i = 0, $ret = "", $c = strlen($s); $i < $c; $i++)
  446. $ret .= ctype_cntrl($s[$i]) ? "" : $s[$i];
  447. return trim(str_replace("..", "", $ret), "/");
  448. }
  449. function rev_time($time) {
  450. preg_match('/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})-(\d{2})/U', $time, $m);
  451. return date($GLOBALS['DATE_FORMAT'], mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]));
  452. }
  453. // get paragraph number $par_id.
  454. function get_paragraph($text, $par_id) {
  455. $par = array(); // paragraph
  456. $count = 1; // paragraph count
  457. $par_excl = 0; // number of !
  458. $inside_code = $inside_html = false; // exclamation marks inside {{}} and {html}{/html} are not headings
  459. $lines = explode("\n", $text);
  460. foreach($lines as $l) {
  461. if($l[0] == '!' && !$inside_html && !$inside_code) {
  462. for($excl = 1, $c = strlen($l); $excl < $c && $l[$excl] == '!'; $excl++);
  463. if($count == $par_id) {
  464. $par[] = $l;
  465. $par_excl = $excl;
  466. } elseif($par_excl)
  467. if($excl > $par_excl)
  468. $par[] = $l;
  469. else
  470. break;
  471. $count++;
  472. }
  473. elseif($par_excl)
  474. $par[] = $l;
  475. if(preg_match('/(?<!\^)\{html\}/', $l)) $inside_html = true;
  476. if(preg_match('/(?<!\^)\{\/html\}/', $l)) $inside_html = false;
  477. if(preg_match('/(?<!\^)\{\{/', $l)) $inside_code = true;
  478. if(preg_match('/(?<!\^)\}\}/', $l)) $inside_code = false;
  479. }
  480. return join("\n", $par);
  481. }
  482. function diff($f1, $f2) { // executes either builtin simple diff or complex diff plugin, if present ...
  483. list($f1, $f2) = array(min($f1, $f2), max($f1, $f2));
  484. $dir = $GLOBALS['HIST_DIR'] . $GLOBALS['page'] . '/';
  485. return plugin('diff', $dir.$f1, $dir.$f2) ? $GLOBALS['plugin_ret_diff'] : diff_builtin($dir.$f1, $dir.$f2);
  486. }
  487. function diff_builtin($f1, $f2) {
  488. $a1 = explode("\n", @file_get_contents($f1));
  489. $a2 = explode("\n", @file_get_contents($f2));
  490. $d1 = array_diff($a1, $a2);
  491. $d2 = array_diff($a2, $a1);
  492. for($i = 0, $ret = ''; $i <= max(count($a2), count($a1)); $i++) {
  493. if($r1 = array_key_exists($i, $d1)) $ret .= '<del>'.h(trim($d1[$i]))."</del>\n";
  494. if($r2 = array_key_exists($i, $d2)) $ret .= '<ins>'.h(trim($d2[$i]))."</ins>\n";
  495. if(!$r1 && !$r2) $ret .= h(trim($a2[$i]))."\n";
  496. }
  497. return "<pre id=\"diff\">$ret</pre>";
  498. }
  499. function authentified() {
  500. if(!$GLOBALS['PASSWORD'] || !strcasecmp($_COOKIE['LW_AUT'], $GLOBALS['PASSWORD']) || !strcasecmp(sha1($GLOBALS['sc']), $GLOBALS['PASSWORD'])) {
  501. setsafecookie('LW_AUT', $GLOBALS['PASSWORD'], time() + ($GLOBALS['PROTECTED_READ'] ? 4 * 3600 : 365 * 86400));
  502. return true;
  503. } else
  504. return false;
  505. }
  506. function setsafecookie() { // setcookie for sensitive informations
  507. $args = func_get_args();
  508. if(version_compare(PHP_VERSION, '5.2.0') >= 0) {
  509. while(count($args) != 6)
  510. $args[] = '';
  511. $args[] = true; // httponly, supported only in some browsers and PHP >= 5.2.0. Successfully prevents XSS attacks.
  512. }
  513. call_user_func_array('setcookie', $args);
  514. }
  515. // returns "line" from meta.dat files. $lnum is number of line from the end of file starting with 1
  516. function meta_getline($file, $lnum) {
  517. if(fseek($file, -($lnum * 175), SEEK_END) || !($line = fread($file, 175)) || $line[0] != "!")
  518. return false; // ! is control character
  519. $date = substr($line, 1, 16);
  520. $ip = trim(substr($line, 19, 15));
  521. $size = (int) substr($line, 35, 10);
  522. $esum = trim(substr($line, 45, 128));
  523. return array($date, $ip, $size, $esum);
  524. }
  525. // Call a method for all plugins, second to last arguments are forwarded to plugins as arguments
  526. function plugin($method) {
  527. $ret = false;
  528. $args = array_slice(func_get_args(), 1);
  529. foreach($GLOBALS['plugins'] as $idx => $plugin)
  530. $ret |= method_exists($GLOBALS['plugins'][$idx], $method) && call_user_func_array(array(&$GLOBALS['plugins'][$idx], $method), $args);
  531. return $ret; // returns true if treated by a plugin
  532. }