$v) $_GET[$k] = stripslashes($v); foreach($_POST as $k => $v) $_POST[$k] = stripslashes($v); foreach($_COOKIE as $k => $v) $_COOKIE[$k] = stripslashes($v); foreach($_REQUEST as $k => $v) $_REQUEST[$k] = stripslashes($v); } $BASE_DIR = $_GET["basedir"] ? $_GET["basedir"] . "/" : ""; $warning = isset($_GET["warning"]); @include("_config.php"); // config file is not required, see settings above if(!empty($BASE_DIR)) @include($BASE_DIR . "_config.php"); // subdomain specific settings $WIKI_VERSION = "LionWiki 1.0.2"; $PAGES_DIR = $BASE_DIR . "pages/"; $HISTORY_DIR = $BASE_DIR . "history/"; $PLUGINS_DIR = "plugins/"; $LANG_DIR = "lang/"; umask(0); // sets default mask // Default character set for auto content header ini_set("default_charset", "UTF-8"); header("Content-type: text/html; charset=UTF-8"); // some strings may not be translated, in that case, we'll use english translation, which *should* be always complete $T_HOME = "Main page"; $T_HELP = "Help"; $T_EDIT = "Edit"; $T_DONE = "Save changes"; $T_SEARCH = "Search"; $T_SEARCH_RESULTS = "Search results"; $T_LIST_OF_ALL_PAGES = "List of all pages"; $T_RECENT_CHANGES = "Recent changes"; $T_LAST_CHANGED = "Last changed"; $T_HISTORY = "History"; $T_NO_HISTORY = "No history."; $T_RESTORE = "Restore"; $T_PASSWORD = "Password"; $T_ERASE_COOKIE = "Erase cookies"; $T_WIKI_CODE = "Wiki code"; $T_MOVE_TEXT = "Move page to new name to:"; $T_MOVE = "Move"; $T_CREATE_PAGE = "Create page"; $T_PROTECTED_READ = "You need to enter password to view content of site: "; $TE_WRONG_PASSWORD = "Password is incorrect."; if($LANG != "en") @include $LANG_DIR . $LANG . ".php"; $template = "template.html"; // Page template $editable = true; // should be on the page "edit" link? // Installation - create directories pages and history, if possible if(!file_exists($PAGES_DIR)) // create pages directory if doesn't exist if(!mkdir($PAGES_DIR, 0777)) die("Can't create directory $PAGES_DIR. Please create $PAGES_DIR and $HISTORY_DIR with 0777 rights."); if(!file_exists($HISTORY_DIR) && $USE_HISTORY) if(!mkdir($HISTORY_DIR, 0777)) { $USE_HISTORY = false; warning("Can't create directory $HISTORY_DIR. Please create $HISTORY_DIR with 0777 rights or turn off history feature in config file. Turning off history now."); } if($_GET['erasecookie']) { // remove cookie without reloading setcookie('AUT_LIONWIKI'); $_COOKIE['AUT_LIONWIKI'] = ""; } $plugins = array(); $plugin_files = array(); $plugins_included = array(); $plugin_saveok = true; // is OK to save page changes (from plugins) // We load common plugins for all subsites and then just for this subsite. if(is_dir($PLUGINS_DIR) && ($dir = opendir($PLUGINS_DIR))) // common plugins while(($file = readdir($dir)) !== false) { $plugin_files[] = $PLUGINS_DIR . $file; $plugins_included[] = $file; } if(!empty($BASE_DIR) && is_dir($BASE_DIR . $PLUGINS_DIR) && ($dir = opendir($BASE_DIR . $PLUGINS_DIR))) while(($file = readdir($dir)) !== false) if(!in_array($file, $plugins_included)) { // we don't want to load plugin twice $plugin_files[] = $BASE_DIR . $PLUGINS_DIR . $file; $plugins_included[] = $file; // sic! } for($i = 0; $i < count($plugin_files); $i++) if(preg_match("/^wkp_(.+)\.php$/", $plugins_included[$i], $matches) > 0) { require $plugin_files[$i]; $plugins[] = new $matches[1](); } // list of variables for UTF-8 conversion and export $req_conv = array('action', 'query', 'sc', 'content', 'page', 'moveto', 'restore', 'f1', 'f2', 'error', 'gtime'); $page = sanitizeFilename($page); $moveto = sanitizeFilename($moveto); $f1 = sanitizeFilename($f1); $f2 = sanitizeFilename($f2); $gtime = sanitizeFilename($gtime); function sanitizeFilename($filename) { $ret = ""; for($i = 0, $c = strlen($filename); $i < $c; $i++) if(!ctype_cntrl($filename[$i])) $ret .= $filename[$i]; return trim(str_replace("..", "", $ret), "/"); } if(extension_loaded('mbstring')) { // Conversion to UTF-8 ini_set("mbstring.language", "Neutral"); ini_set("mbstring.internal_encoding", "UTF-8"); ini_set("mbstring.http_output", "UTF-8"); ini_set("mbstring.detect_order", "UTF-8,ISO8859-2,ISO-8859-1"); ini_set("mbstring.func_overload", MB_OVERLOAD_STRING); foreach($req_conv as $req_key) $_REQUEST[$req_key] = mb_convert_encoding($_REQUEST[$req_key], "UTF-8", mb_detect_encoding($_REQUEST[$req_key])); } // if mbstring is not supported, nothing bad should happen // export variables to main namespace foreach($req_conv as $req) $$req = trim($_REQUEST[$req]); // setting $PAGE_TITLE if($page) { if(!file_exists($PAGES_DIR . $START_PAGE . ".txt")) $action = "edit"; $PAGE_TITLE = $page; } else if($action == "search") if(empty($query)) $PAGE_TITLE = $T_LIST_OF_ALL_PAGES; else $PAGE_TITLE = "$T_SEARCH_RESULTS $query"; elseif($action == "recent") $PAGE_TITLE = $T_RECENT_CHANGES; else { if(!file_exists($PAGES_DIR . $START_PAGE . ".txt")) $action = "edit"; // for first run after installation $PAGE_TITLE = $START_PAGE; } if(version_compare(phpversion(), "5.1.0") >= 0) @date_default_timezone_set($TIME_ZONE); $datetw = date("Y/m/d H:i", mktime(date("H") + $LOCAL_HOUR)); // does user need password to read content of site. If yes, ask for it. if(!authentified() && $PROTECTED_READ) { $CON = "

$T_PROTECTED_READ

"; $action = "view-html"; $editable = false; } else if($content && authentified()) { // do we have page to save? plugin_call_method("writingPage"); if($plugin_saveok) { // are plugins happy with page? (no spam, etc) if(!$file = @fopen($PAGES_DIR . $PAGE_TITLE . ".txt", "w")) die("Could not write page $PAGES_DIR$PAGE_TITLE.txt!"); fputs($file, $content); fclose($file); if($USE_HISTORY) { // let's archive previous revision $complete_dir = $HISTORY_DIR . $PAGE_TITLE . "/"; if(!$dir = @opendir($complete_dir)) mkdir($complete_dir, 0777); $filename = $complete_dir . date("Ymd-Hi", mktime(date("H") + $LOCAL_HOUR)) . ".bak"; if(!$bak = @lwopen($filename, "w")) die("Could not write backup $filename of page!"); lwwrite($bak, "\n// " . $datetw . " / " . " " . $_SERVER['REMOTE_ADDR'] . "\n"); lwwrite($bak, $content); lwclose($bak); } plugin_call_method("writedPage", $file); header("Location:?page=" . urlencode($PAGE_TITLE) . "&error=" . urlencode($error)); die(); } else { // there's some problem with page, give user a chance to fix it (do not throw away submitted content) $CON = $content; $action = "edit"; } } else if($content) { // wring password, give user another chance (do not throw away submitted content) $error = $TE_WRONG_PASSWORD; $CON = $content; $action = "edit"; } // moving/renaming page if($moveto && authentified()) { plugin_call_method("renamingPage"); if($plugin_saveok) { if(!rename($PAGES_DIR . $page . ".txt", $PAGES_DIR . $moveto . ".txt")) die("Moving page was not succesful! Page was not moved."); else if(!rename($HISTORY_DIR . $page, $HISTORY_DIR . $moveto)) { rename($PAGES_DIR . $moveto, $PAGES_DIR . $page); // revert previous change die("Moving history of the was not succesful! Page was not moved."); } else { @touch($PAGES_DIR . $moveto . ".txt"); // moved page should be at the top of recent ch. header("Location:?page=" . urlencode($moveto)); die(); } } } else if($moveto) $error = $TE_WRONG_PASSWORD; // lets check first subsite specific template, then common, then fallback if(file_exists($BASE_DIR . $template)) $html = file_get_contents($BASE_DIR . $template); elseif(file_exists($template)) $html = file_get_contents($template); else // there's no template file, we'll use default minimal template $html = fallback_template(); if(!$CON && ($file = @fopen($PAGES_DIR . $PAGE_TITLE . ".txt", "r"))) { if($file) $LAST_CHANGED = date("Y/m/d H:i", @filemtime($PAGES_DIR . $PAGE_TITLE . ".txt") + $LOCAL_HOUR * 3600); // Restoring old version of page if($gtime && $restore && ($file = @lwopen($HISTORY_DIR . $PAGE_TITLE . "/" . $gtime, "r"))) $CON = "\n" . @lwread($file) . "\n"; else $CON = @fread($file, @filesize($PAGES_DIR . $PAGE_TITLE . ".txt")) . "\n"; @lwclose($file); } if($action == "edit") { $editable = false; $HISTORY = "" . $T_HISTORY . "
"; if(!authentified()) { // if not logged on, require password $FORM_PASSWORD = $T_PASSWORD; $FORM_PASSWORD_INPUT = ""; } $RENAME_FORM_BEGIN = "
"; $RENAME_FORM_END = "
"; $RENAME_TEXT = $T_MOVE_TEXT; $RENAME_INPUT = ""; $RENAME_SUBMIT = ""; $CON_FORM_BEGIN = "
"; $CON_FORM_END = "
"; $CON_TEXTAREA = "
"; $CON_SUBMIT = " "; } elseif($action == "history") { if(isset($gtime)) { // show old revision of page $complete_dir = $HISTORY_DIR . $PAGE_TITLE . "/"; $HISTORY = "" . $T_HISTORY . ""; if($file = @lwopen($HISTORY_DIR . $PAGE_TITLE . "/" . $gtime, "r")) { $HISTORY = "" . $T_RESTORE . " " . $HISTORY; $action = ""; } } else { // show whole history of page $complete_dir = $HISTORY_DIR . $PAGE_TITLE . "/"; if($opening_dir = @opendir($complete_dir)) { while($filename = @readdir($opening_dir)) if(preg_match('/(.+)\.bak.*$/', $filename)) $files[] = $filename; rsort($files); $CON = "
\n"; foreach($files as $fname) { $fname = basename(basename($fname, ".bz2"), ".gz"); $CON .= ""; $CON .= "" . $fname . "
"; } $CON .= "
"; } else $CON = $NO_HISTORY; } } elseif($action == "diff") { if(empty($f1)) { // diff is made on two last revisions $complete_dir = $HISTORY_DIR . $PAGE_TITLE . "/"; if($opening_dir = @opendir($complete_dir)) { while($filename = @readdir($opening_dir)) if(preg_match('/\.bak.*$/', $filename)) $files[] = basename(basename($filename, ".gz"), ".bz2"); rsort($files); header("Location: ?action=diff&page=" . urlencode($PAGE_TITLE) . "&f1=$files[0]&f2=$files[1]"); die(); } } $HISTORY = "" . $T_HISTORY . ""; $CON = diff($f1, $f2); } elseif($action == "search") { $editable = false; $dir = opendir(getcwd() . "/$PAGES_DIR"); // offer to create page if it doesn't exist if($query && !file_exists($PAGES_DIR . $query . ".txt")) $CON = "

$T_CREATE_PAGE $query.


"; $files = array(); while($file = readdir($dir)) { if(preg_match("/\.txt$/", $file)) { @$con = file_get_contents($PAGES_DIR . $file); if(empty($query) || stripos($con, $query) !== false || stripos($file, $query) !== false) $files[] = substr($file, 0, strlen($file) - 4); } } sort($files); foreach($files as $file) $CON .= "" . $file . "
"; $PAGE_TITLE .= " (" . count($files) . ")"; } elseif($action == "recent") { // recent changes $editable = false; $dir = opendir(getcwd() . "/$PAGES_DIR"); while($file = readdir($dir)) if(preg_match("/\.txt$/", $file)) $filetime[$file] = filemtime($PAGES_DIR . $file); arsort($filetime); $filetime = array_slice($filetime, 0, 100); // just first 100 changed files foreach($filetime as $filename => $timestamp) { $filename = substr($filename, 0, strlen($filename) - 4); $CON .= "" . $filename . " (" . strftime("$TIME_FORMAT", $timestamp + $LOCAL_HOUR * 3600) . " - diff)
"; } } elseif($action != "view-html" && $action != "") if(!plugin_call_method("action", $action)) $action = ""; if($action == "") { // substituting $CON to be viewed as HTML $CON = "\n" . $CON; // fix for {html} tag at the very start of the page $CON = str_replace("{/html}{html}", "{/html} {html}", $CON); // fix for adjacent {html} tags // save content not intended for substitutions ({html} tag) $n_htmlcodes = preg_match_all("/[^\^]\{html\}(.+)\{\/html\}/Us", $CON, $htmlcodes, PREG_PATTERN_ORDER); $CON = preg_replace("/[^\^]\{html\}(.+)\{\/html\}/Us", "{HTML}", $CON); $CON = str_replace("&", "&", $CON); // escape HTML spec. chars $CON = str_replace("<", "<", $CON); // escaping ^codes which protects them from substitution $CON = preg_replace("/\^(.)/Umsie", "'&#'.ord('$1').';'", $CON); $CON = preg_replace("/(\r\n|\r)/", "\n", $CON); // unifying newlines to Unix ones // {{CODE}} $nbcode = preg_match_all("/{{(.+)}}/Ums", $CON, $matches_code, PREG_PATTERN_ORDER); $CON = preg_replace("/{{(.+)}}/Ums", "
{{CODE}}
", $CON); plugin_call_method("formatBegin"); // substituting special characters $CON = str_replace("<-->", "↔", $CON); // <--> $CON = str_replace("-->", "→", $CON); // --> $CON = str_replace("<--", "←", $CON); // <-- $CON = preg_replace("/\([cC]\)/Umsi", "©", $CON); // (c) $CON = preg_replace("/\([rR]\)/Umsi", "®", $CON); // (r) $CON = preg_replace("/^([^!\*#\n][^\n]+)$/Um", "

$1

", $CON); // TODO: verif & / & $rg_url = "[0-9a-zA-Z\.\#/~\-_%=\?\&,\+\:@;!\(\)\*\$']*"; $rg_img_local = "(" . $rg_url . "\.(jpeg|jpg|gif|png))"; $rg_img_http = "h(ttps?://" . $rg_url . "\.(jpeg|jpg|gif|png))"; $rg_link_local = "(" . $rg_url . ")"; $rg_link_http = "h(ttps?://" . $rg_url . ")"; // IMAGES // [http.png] / [http.png|right] $CON = preg_replace('#\[' . $rg_img_http . '(\|(right|left))?\]#', 'xx$1', $CON); // [local.png] / [local.png|left] $CON = preg_replace('#\[' . $rg_img_local . '(\|(right|left))?\]#', '$1', $CON); // image link [http://wikiss.tuxfamily.org/img/logo_100.png|http://wikiss.tuxfamily.org/img/logo_100.png] // [http|http] $CON = preg_replace('#\[' . $rg_img_http . '\|' . $rg_link_http . '(\|(right|left))?\]#U', 'xx$3', $CON); // [http|local] $CON = preg_replace('#\[' . $rg_img_http . '\|' . $rg_link_local . '(\|(right|left))?\]#U', '$3', $CON); // [local|http] $CON = preg_replace('#\[' . $rg_img_local . '\|' . $rg_link_http . '(\|(right|left))?\]#U', 'xx$3', $CON); // [local|local] $CON = preg_replace('#\[' . $rg_img_local . '\|' . $rg_link_local . '(\|(right|left))?\]#U', '$3', $CON); // LINKS $CON = preg_replace('#\[([^\]]+)\|' . $rg_link_http . '\]#U', '$1', $CON); // local links has to start either with / or ./ $CON = preg_replace('#\[([^\]]+)\|\.\/' . $rg_link_local . '\]#U', '$1', $CON); $CON = preg_replace('#' . $rg_link_http . '#i', 'xx$1', $CON); $CON = preg_replace('#xxttp#', 'http', $CON); $CON = preg_replace('#\[\?(.*)\]#Ui', '$1', $CON); // Wikipedia preg_match_all("/\[([^|\]]+\|)?([^\]#]+)(#[^\]]+)?\]/", $CON, $matches, PREG_SET_ORDER); // matching Wiki links foreach($matches as $match) { if(empty($match[1])) // is page label same as its name? $match[1] = $match[2]; else $match[1] = rtrim($match[1], "|"); if($match[3]) // link to the heading $match[3] = "#" . preg_replace("/[^\da-z]/i", "_", urlencode(substr($match[3], 1, strlen($match[3]) - 1))); if(file_exists($PAGES_DIR . "$match[2].txt")) $CON = str_replace($match[0], '' . $match[1] . '', $CON); else $CON = str_replace($match[0], '' . $match[1] . '', $CON); } $CON = preg_replace('#([0-9a-zA-Z\./~\-_]+@[0-9a-z\./~\-_]+)#i', '$0', $CON); // mail recognition // LIST, ordered, unordered $CON = preg_replace('/^\*\*\*(.*)(\n)/Um', "$2", $CON); $CON = preg_replace('/^\*\*(.*)(\n)/Um', "$2", $CON); $CON = preg_replace('/^\*(.*)(\n)/Um', "$2", $CON); $CON = preg_replace('/^\#\#\#(.*)(\n)/Um', "
      1. $1
$2", $CON); $CON = preg_replace('/^\#\#(.*)(\n)/Um', "
    1. $1
$2", $CON); $CON = preg_replace('/^\#(.*)(\n)/Um', "
  1. $1
$2", $CON); // Fixing crappy job of parsing *** and ###. 3 times for 3 levels. for($i = 0; $i < 3; $i++) $CON = preg_replace('/(<\/ol>\n*
    |<\/ul>\n*