$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"] . "/" : ""; @include("_config.php"); // config file is not required, see settings above if(!empty($BASE_DIR)) @include($BASE_DIR . "_config.php"); // subdomain specific settings if(empty($PASSWORD_MD5) && !empty($PASSWORD)) $PASSWORD_MD5 = md5($PASSWORD); $WIKI_VERSION = "LionWiki 2.1.6"; $PAGES_DIR = $BASE_DIR . "pages/"; $HISTORY_DIR = $BASE_DIR . "history/"; $PLUGINS_DIR = "plugins/"; $LANG_DIR = "lang/"; umask(0); // sets default mask // some strings may not be translated, in that case, we'll use english translation, which should be always complete $T_HOME = "Main page"; $T_SYNTAX = "Syntax"; $T_EDIT = "Edit"; $T_DONE = "Save changes"; $T_PREVIEW = "Preview"; $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_REV_DIFF = "Difference between revisions from {REVISION1} and {REVISION2}."; $T_REVISION = "'''This revision is from {TIME}. You can {RESTORE} it.'''\n\n"; $T_PASSWORD = "Password"; $T_EDIT_SUMMARY = "Edit summary"; $T_ERASE_COOKIE = "Erase cookies"; $T_WIKI_CODE = "Wiki code"; $T_MOVE_TEXT = "New name"; $T_MOVE = "Move"; $T_DIFF = "diff"; $T_CREATE_PAGE = "Create page"; $T_PROTECTED_READ = "You need to enter password to view content of site: "; $T_EDIT_CONFLICT = "Edit conflict: somebody saved this page after you started editing. It is strongly encouraged to see last {DIFF} before saving it. After reviewing and possibly merging changes, you can save page by clicking on save button."; $TE_WRONG_PASSWORD = "Password is incorrect."; // Default character set for auto content header @ini_set("default_charset", "UTF-8"); header("Content-type: text/html; charset=UTF-8"); // consider only first language, don't consider language variant (like en-us or pt-br) if($USE_AUTOLANG) $LANG = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); $LANG = !empty($_COOKIE["LW_LANG"]) ? $_COOKIE["LW_LANG"] : $LANG; if(!empty($_GET["lang"])) { $LANG = $_GET["lang"]; setcookie('LW_LANG', $LANG, time() + 365 * 86400); } if($LANG != "en" && @file_exists($LANG_DIR . $LANG . ".php")) @include $LANG_DIR . $LANG . ".php"; else $LANG = "en"; // Installation - create directories pages and history, if possible if(!file_exists($PAGES_DIR) && !mkdir(rtrim($PAGES_DIR, "/"))) die("Can't create directory $PAGES_DIR. Please create $PAGES_DIR and $HISTORY_DIR with 0777 rights."); if($USE_HISTORY && !file_exists($HISTORY_DIR) && !mkdir(rtrim($HISTORY_DIR, "/"))) die("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 foreach($_COOKIE as $key => $value) if(!strcmp(substr($key, 0, 3), "LW_")) { setcookie($key); unset($_COOKIE[$key]); } $plugins = array(); $plugin_files = 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(!empty($BASE_DIR) && ($dir = @opendir($BASE_DIR . $PLUGINS_DIR))) while($file = readdir($dir)) $plugin_files[] = $BASE_DIR . $PLUGINS_DIR . $file; if($dir = @opendir($PLUGINS_DIR)) // common plugins while($file = readdir($dir)) if(!in_array($PLUGINS_DIR . $BASE_DIR . $file, $plugin_files)) // we don't want to load plugin twice $plugin_files[] = $PLUGINS_DIR . $file; foreach($plugin_files as $pfile) if(preg_match("/^.*wkp_(.+)\.php$/", $pfile, $matches) > 0) { require $pfile; $plugins[] = new $matches[1](); } plugin_call_method("pluginsLoaded"); // list of variables for UTF-8 conversion and export $req_conv = array("action", "query", "sc", "content", "page", "moveto", "restore", "f1", "f2", "error", "time", "esum", "preview", "last_changed", "econfprot", "gtime"); 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 foreach($req_conv as $req) // export variables to main namespace $$req = trim($_REQUEST[$req]); $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), "/"); } $editable = $page || empty($action); // should be on the page "edit" link? if(!empty($preview)) { $action = "edit"; $CON = $content; } // setting $PAGE_TITLE if($page || empty($action)) { $page = $page_nolang = $TITLE = $page ? $page : $START_PAGE; if($action == "" && file_exists($PAGES_DIR . $page . ".$LANG.txt")) // language variant $page = $TITLE = $page_nolang . "." . $LANG; else if(!file_exists($PAGES_DIR . $page . ".txt") && $action != "save") $action = "edit"; // create page if it doesn't exist if(!empty($preview)) $TITLE = $T_PREVIEW . ": " . $page; } else if($action == "search") $TITLE = empty($query) ? $T_LIST_OF_ALL_PAGES : "$T_SEARCH_RESULTS $query"; elseif($action == "recent") $TITLE = $T_RECENT_CHANGES; if(version_compare(phpversion(), "5.1.0") >= 0) @date_default_timezone_set($TIME_ZONE); $datetw = date("Y/m/d H:i", time() + $LOCAL_HOUR * 3600); // does user need password to read content of site. If yes, ask for it. if(!authentified() && $PROTECTED_READ) { $CON = "
"; $action = "view-html"; } else if($action == "save" && authentified()) { // do we have page to save? $LAST_CHANGED_TIMESTAMP = @filemtime($PAGES_DIR . $page . ".txt"); if($last_changed < $LAST_CHANGED_TIMESTAMP && $econfprot) { $action = "edit"; $error = str_replace("{DIFF}", "$T_DIFF", $T_EDIT_CONFLICT); } else if(!plugin_call_method("writingPage") || $plugin_saveok) { // are plugins happy with page? (no - spam, etc) if(!$file = @fopen($PAGES_DIR . $page . ".txt", "w")) die("Could not write page $PAGES_DIR$page.txt!"); fputs($file, $content); fclose($file); if($USE_HISTORY) { // let's archive previous revision $complete_dir = $HISTORY_DIR . $page; if(!is_dir($complete_dir)) mkdir($complete_dir); $rightnow = date("Ymd-Hi-s", time() + $LOCAL_HOUR * 3600); $filename = $complete_dir . "/" . $rightnow . ".bak"; if(!$bak = @lwopen($filename, "w")) die("Could not write backup $filename of page!"); lwwrite($bak, $content); lwclose($bak); if($USE_META) $es = fopen($complete_dir . "/meta.dat", "ab"); if($es) { $filesize = filesize($PAGES_DIR . "/" . $page . ".txt"); // Strings are in UTF-8, it's dangerous to just cut off piece of string, therefore +2 fwrite($es, "!" . $rightnow . str_pad($_SERVER['REMOTE_ADDR'], 16, " ", STR_PAD_LEFT) . str_pad($filesize, 11, " ", STR_PAD_LEFT) . " " . str_pad(substr($esum, 0, $EDIT_SUMMARY_LEN), $EDIT_SUMMARY_LEN + 2)) . "\n"; fclose($es); } } plugin_call_method("pageWritten", $file); header("Location:?page=" . urlencode($page) . ($error ? ("&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($action == "save") { // wrong password, give user another chance (do not throw away submitted content) $error = $TE_WRONG_PASSWORD; $CON = $content; $action = "edit"; } if($moveto && authentified()) { // moving/renaming page 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_exists($PAGES_DIR . $page . ".txt")) { $LAST_CHANGED_TIMESTAMP = @filemtime($PAGES_DIR . $page . ".txt"); $LAST_CHANGED = date("Y/m/d H:i", $LAST_CHANGED_TIMESTAMP + $LOCAL_HOUR * 3600); $HISTORY = "" . $T_HISTORY . ""; // Restoring old version of page if($gtime && ($restore || $action == "rev") && ($file = @lwopen($HISTORY_DIR . $page . "/" . $gtime, "r"))) { if($action == "rev") { $rev_restore = "[$T_RESTORE|./?page=" . urlencode($page) . "&action=edit>ime=" . $gtime . "&restore=1]"; $CON = str_replace(array("{TIME}", "{RESTORE}"), array(revTime($gtime), $rev_restore), $T_REVISION); } $CON .= @lwread($file); @lwclose($file); } else { $CON = @file_get_contents($PAGES_DIR . $page . ".txt"); if(substr($CON, 0, 10) == "{redirect:" && $action == "") { header("Location:?page=" . substr($CON, 10, strpos($CON, "}") - 10)); // urlencode? die(); } } } if($action == "edit") { if(!authentified()) { // if not logged on, require password $FORM_PASSWORD = $T_PASSWORD; $FORM_PASSWORD_INPUT = ""; } $EDIT_SUMMARY_TEXT = $T_EDIT_SUMMARY; $EDIT_SUMMARY = ""; if(!$preview) { $RENAME_FORM_BEGIN = ""; $RENAME_TEXT = $T_MOVE_TEXT; $RENAME_INPUT = ""; $RENAME_SUBMIT = ""; } $CON_FORM_BEGIN = ""; $CON_TEXTAREA = ""; $CON_SUBMIT = ""; $CON_PREVIEW = ""; if($preview) $action = ""; } elseif($action == "rev" && !empty($gtime)) // show old revision of page $action = ""; elseif($action == "history") { // show whole history of page $complete_dir = $HISTORY_DIR . $page . "/"; if($opening_dir = @opendir($complete_dir)) { while($filename = @readdir($opening_dir)) if(preg_match('/(.+)\.bak.*$/', $filename)) $files[] = $filename; rsort($files); $CON = ""; } else $CON = $NO_HISTORY; } elseif($action == "diff") { if(empty($f1) && $opening_dir = @opendir($HISTORY_DIR . $page . "/")) { // diff is made on two last revisions 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) . "&f1=$files[0]&f2=$files[1]"); die(); } $r1 = "".revTime($f1).""; $r2 = "".revTime($f2).""; $CON = str_replace(array("{REVISION1}", "{REVISION2}"), array($r1, $r2), $T_REV_DIFF); $CON .= diff($f1, $f2); } elseif($action == "search") { $dir = opendir($PAGES_DIR); // offer to create page if it doesn't exist if($query && !file_exists($PAGES_DIR . $query . ".txt")) $CON = "{{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); // sup and sub $CON = preg_replace("/\{sup\}(.*)\{\/sup\}/U", "$1", $CON); $CON = preg_replace("/\{sub\}(.*)\{\/sub\}/U", "$1", $CON); // small $CON = preg_replace("/\{small\}(.*)\{\/small\}/U", "$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))?\]#', '";
for($i = 0; $i <= max(sizeof($a2), sizeof($a1)); $i++) {
if($r1 = array_key_exists($i, $d1)) $ret .= "".htmlspecialchars(trim($d1[$i]))."\n";
if($r2 = array_key_exists($i, $d2)) $ret .= "".htmlspecialchars(trim($d2[$i]))."\n";
if(!$r1 && !$r2 && !$short_diff) $ret .= "".htmlspecialchars(trim($a2[$i]))."\n";
}
return $ret . "";
}
function lwopen($name, $par) {
global $HISTORY_COMPRESSION;
if($par == "r") {
if(file_exists($name)) return array(@fopen($name, $par), "plain");
elseif(file_exists($name . ".gz")) return array(@gzopen($name . ".gz", $par), "gzip");
elseif(file_exists($name . ".bz2")) return @bzopen($name . ".bz2", $par, "bzip2");
} elseif($par == "w") {
if($HISTORY_COMPRESSION == "plain") return array(@fopen($name, $par), $HISTORY_COMPRESSION);
elseif($HISTORY_COMPRESSION == "gzip") return array(@gzopen($name . ".gz", $par), $HISTORY_COMPRESSION);
elseif($HISTORY_COMPRESSION == "bzip2") return array(@bzopen($name . ".bz2", $par), $HISTORY_COMPRESSION);
}
}
function lwclose($h) {
if($h[1] == "plain") return fclose($h[0]);
elseif($h[1] == "gzip") return gzclose($h[0]);
elseif($h[1] == "bzip2") return bzclose($h[0]);
}
function lwread($h) {
$ret = $buffer = "";
if($h[1] == "plain") {
$stat = fstat($h[0]);
return fread($h[0], $stat["size"]);
} elseif($h[1] == "gzip") {
while($buffer = gzread($h[0], 8192))
$ret .= $buffer;
return $ret;
} elseif($h[1] == "bzip2") {
while($buffer = bzread($h[0], 8192))
$ret .= $buffer;
return $ret;
}
}
function lwwrite($h, $data) {
if($h[1] == "plain") return fwrite($h[0], $data);
elseif($h[1] == "gzip") return gzwrite($h[0], $data);
elseif($h[1] == "bzip2") return bzwrite($h[0], $data);
}
// checks autentification
function authentified() {
global $PASSWORD_MD5, $sc;
if(empty($PASSWORD_MD5) || $_COOKIE['LW_AUT'] == $PASSWORD_MD5 || md5($sc) == $PASSWORD_MD5) {
setcookie('LW_AUT', $PASSWORD_MD5, time() + $PROTECTED_READ ? $COOKIE_LIFE_READ : $COOKIE_LIFE_WRITE);
$_COOKIE['LW_AUT'] = $PASSWORD_MD5;
return true;
} else
return false;
}
// returns "line" from meta.dat files. $lnum is number of line from the end of file starting with 1
function meta_getline($file, $lnum) {
global $EDIT_SUMMARY_LEN;
if(fseek($file, -($lnum * 175), SEEK_END) != 0)
return false;
$line = fread($file, 175);
if($line[0] != "!") // control character
return false;
$date = substr($line, 1, 16);
$ip = trim(substr($line, 19, 15));
$size = trim(substr($line, 35, 10));
$esum = trim(substr($line, 45, $EDIT_SUMMARY_LEN));
return array($date, $ip, $size, $esum);
}
/** Call a method for all plugins
* $mname: method name
* [...] : method arguments
* return: true if treated by a plugin
*/
function plugin_call_method($mname) {
global $plugins;
$ret = false;
foreach($plugins as $plugin)
if(method_exists($plugin, $mname)) {
$args = func_get_args();
$ret |= call_user_func_array(array($plugin, $mname), array_slice($args, 1));
}
return $ret;
}
function fallback_template() { return '
| {HOME} {RECENT_CHANGES} | {EDIT} {SYNTAX} {HISTORY} | |
{PAGE_TITLE} | ||
|---|---|---|
|
{ ERROR }
{CONTENT}
{RENAME_FORM} {RENAME_TEXT} {RENAME_INPUT} {FORM_PASSWORD} {FORM_PASSWORD_INPUT} {RENAME_SUBMIT} {/RENAME_FORM}
{CONTENT_FORM} {CONTENT_TEXTAREA}{FORM_PASSWORD} {FORM_PASSWORD_INPUT} {plugin:CAPTCHA_QUESTION} {plugin:CAPTCHA_INPUT} {EDIT_SUMMARY_TEXT} {EDIT_SUMMARY_INPUT} {CONTENT_SUBMIT} {CONTENT_PREVIEW} {/CONTENT_FORM} |
||
{SEARCH_FORM}{SEARCH_INPUT}{SEARCH_SUBMIT}{/SEARCH_FORM} |
Powered by LionWiki. {LAST_CHANGED_TEXT}: {LAST_CHANGED} {COOKIE} | {EDIT} {SYNTAX} {HISTORY} |