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', 'time');
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 = "
";
$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_TEXT = $T_MOVE_TEXT;
$RENAME_INPUT = "";
$RENAME_SUBMIT = "";
$CON_FORM_BEGIN = "";
$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 = "";
} 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(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
// 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))?\]#', '
', $CON);
// [local.png] / [local.png|left]
$CON = preg_replace('#\[' . $rg_img_local . '(\|(right|left))?\]#', '
', $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', '
', $CON);
// [http|local]
$CON = preg_replace('#\[' . $rg_img_http . '\|' . $rg_link_local . '(\|(right|left))?\]#U', '
', $CON);
// [local|http]
$CON = preg_replace('#\[' . $rg_img_local . '\|' . $rg_link_http . '(\|(right|left))?\]#U', '
', $CON);
// [local|local]
$CON = preg_replace('#\[' . $rg_img_local . '\|' . $rg_link_local . '(\|(right|left))?\]#U', '
', $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
$2", $CON);
$CON = preg_replace('/^\#\#(.*)(\n)/Um', "- $1
$2", $CON);
$CON = preg_replace('/^\#(.*)(\n)/Um', "- $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*)/', "", $CON);
// still fixing. Following three lines fix only XHTML validity
$CON = preg_replace('/<\/li><([uo])l>/', "<$1l>", $CON);
$CON = preg_replace('/<\/([uo])l>- /', "$1l>
- ", $CON);
$CON = preg_replace('/<(\/?)([uo])l><\/?[uo]l>/', "<$1$2l><$1li><$1$2l>", $CON);
/* remove anchors from a text */
function remove_a($link)
{
preg_match_all("#()*([^<>]+)()*#", $link, $txt);
return trim(join("", $txt[2]));
}
// remove_a
function name_title($matches) // replace headings
{
global $headings;
$headings[] = $h = array(strlen($matches[1]) + 1, preg_replace("/[^\da-z]/i", "_", remove_a($matches[2])), $matches[2]);
return "" . $h[2] . "";
}
$CON = preg_replace_callback('/^(!+?)(.*)$/Um', "name_title", $CON);
// do not join adjacent spaces into one (nasty)
$CON = preg_replace('/^( +) ([^ ])/Um', '$1 $2', $CON);
$CON = preg_replace('/(-----*)/m', '
', $CON); // horizontal line
$CON = preg_replace("/<\/([uo])l>\n\n/Us", "$1l>", $CON);
$CON = preg_replace('#()
#', "$1", $CON);
$CON = preg_replace("/'--(.*)--'/Um", '$1', $CON); // strikethrough
$CON = preg_replace("/'__(.*)__'/Um", '$1', $CON); // underlining
$CON = preg_replace("/'''''(.*)'''''/Um", '$1', $CON); // bold and italic
$CON = preg_replace("/'''(.*)'''/Um", '$1', $CON); // bold
$CON = preg_replace("/''(.*)''/Um", '$1', $CON); // italic
$CON = str_replace("{br}", "
", $CON); // new line
if(strpos($CON, "{TOC}")) {
$CON = str_replace("{TOC}", "", $CON);
$TOC = "";
foreach($headings as $h)
$TOC .= str_repeat("", $h[0] - 2);
for($i = 0; $i < 5; $i++) // five possible headings
$TOC = preg_replace('/<\/ul>\n*/', "", $TOC);
$TOC = "";
$TOC = preg_replace('/<\/li>/', "", $TOC);
$TOC = preg_replace('/<\/ul>- /', "
- ", $TOC);
$TOC = preg_replace('/<(\/?)ul><\/?ul>/', "<$1ul><$1li><$1ul>", $TOC);
}
// returning content of {{CODE}}
if($nbcode > 0)
$CON = preg_replace(array_fill(0, $nbcode, "/{{CODE}}/Us"), $matches_code[1], $CON, 1);
// {html} tag
if($n_htmlcodes > 0)
$CON = preg_replace(array_fill(0, $n_htmlcodes, "/{HTML}/Us"), $htmlcodes[1], $CON, 1);
plugin_call_method("formatEnd");
}
// Template substitution
plugin_call_method("template");
$html = preg_replace("/\{plugin:[^}]*\}/U", "", $html); // getting rid of absent plugin tags
if($editable && is_writable($PAGES_DIR . $PAGE_TITLE . ".txt"))
$EDIT = "$T_EDIT";
$tpl_subs = array(
array("{SEARCH}", ""),
array("{HELP}", $action == "edit" ? "$T_HELP" : ""),
array("{HOME}", "$T_HOME"),
array("{RECENT_CHANGES}", "$T_RECENT_CHANGES"),
array("{ERROR}", $error),
array("{HISTORY}", $HISTORY),
array("{PAGE_TITLE}", htmlspecialchars($PAGE_TITLE == $START_PAGE ? $WIKI_TITLE : $PAGE_TITLE)),
array("{EDIT}", $EDIT),
array("{TOC}", $TOC),
array("{PAGE_TITLE_BRUT}", htmlspecialchars($PAGE_TITLE == $START_PAGE ? $T_HOME : $PAGE_TITLE)),
array("{WIKI_TITLE}", $WIKI_TITLE),
array("{LAST_CHANGED_TEXT}", $T_LAST_CHANGED),
array("{LAST_CHANGED}", $LAST_CHANGED),
array("{CONTENT}", $action != "edit" ? $CON : ""),
array("{CONTENT_FORM}", $CON_FORM_BEGIN),
array("{/CONTENT_FORM}", $CON_FORM_END),
array("{CONTENT_TEXTAREA}", $CON_TEXTAREA),
array("{CONTENT_SUBMIT}", $CON_SUBMIT),
array("{RENAME_FORM}", $RENAME_FORM_BEGIN),
array("{/RENAME_FORM}", $RENAME_FORM_END),
array("{RENAME_TEXT}", $RENAME_TEXT),
array("{RENAME_INPUT}", $RENAME_INPUT),
array("{RENAME_SUBMIT}", $RENAME_SUBMIT),
array("{FORM_PASSWORD}", $FORM_PASSWORD),
array("{FORM_PASSWORD_INPUT}", $FORM_PASSWORD_INPUT),
array("{LANG}", $LANG),
array("{LIST_OF_ALL_PAGES}", "$T_LIST_OF_ALL_PAGES"),
array("{WIKI_VERSION}", $WIKI_VERSION),
array("{DATE}", $datetw),
array("{IP}", $_SERVER['REMOTE_ADDR']),
array("{COOKIE}", $_COOKIE['AUT_LIONWIKI'] ? '' . $T_ERASE_COOKIE . '' : "")
);
foreach($tpl_subs as $subs) // substituting values
$html = str_replace($subs[0], $subs[1], $html);
echo $html; // voila
// Function library
function diff($f1, $f2, $short_diff = 0)
{
global $PAGE_TITLE, $HISTORY_DIR;
function pcolor($color, $txt) { return "
$txt
"; }
$fn1 = $HISTORY_DIR . $PAGE_TITLE . "/" . $f1;
$fn2 = $HISTORY_DIR . $PAGE_TITLE . "/" . $f2;
if($fn2 < $fn1)
list($fn1, $fn2) = array($fn2, $fn1);
$f1 = lwopen($fn1, "r");
$f2 = lwopen($fn2, "r");
$a1 = explode("\n", @lwread($f1));
$a2 = explode("\n", @lwread($f2));
lwclose($f1);
lwclose($f2);
$d1 = array_diff($a1, $a2);
$d2 = array_diff($a2, $a1);
$ret = "";
for($i = 0; $i <= max(sizeof($a2), sizeof($a1)); $i++) {
if($r1 = array_key_exists($i, $d1))
$ret .= pcolor("red", "-" . $d1[$i]);
if($r2 = array_key_exists($i, $d2))
$ret .= pcolor("green", "+" . $d2[$i]);
if(!$r1 && !$r2 && !$short_diff)
$ret .= pcolor("black", " " . $a2[$i]);
}
return $ret . "
";
}
function warning($w)
{
global $warning;
if($warning)
echo "Warning: ", $w, "
";
}
function lwopen($name, $par)
{
global $FILE_TYPE;
global $HISTORY_COMPRESSION;
if($par == "r") {
if(file_exists($name)) {
$FILE_TYPE = "plain";
return fopen($name, $par);
} elseif(file_exists($name . ".gz")) {
$FILE_TYPE = "gzip";
return @gzopen($name . ".gz", $par);
} elseif(file_exists($name . ".bz2")) {
$FILE_TYPE = "bzip2";
return @bzopen($name . ".bz2", $par);
}
} elseif($par == "w") {
$FILE_TYPE = $HISTORY_COMPRESSION;
if($HISTORY_COMPRESSION == "plain")
return @fopen($name, $par);
elseif($HISTORY_COMPRESSION == "gzip")
return @gzopen($name . ".gz", $par);
elseif($HISTORY_COMPRESSION == "bzip2")
return @bzopen($name . ".bz2", $par);
}
return 0;
}
function lwclose($handle)
{
global $FILE_TYPE;
if($FILE_TYPE == "plain")
return fclose($handle);
elseif($FILE_TYPE == "gzip")
return gzclose($handle);
elseif($FILE_TYPE == "bzip2")
return bzclose($handle);
$FILE_TYPE = "";
}
function lwread($handle)
{
global $FILE_TYPE;
$buffer = "";
$ret = "";
if($FILE_TYPE == "plain") {
$stat = fstat($handle);
return fread($handle, $stat["size"]);
}
elseif($FILE_TYPE == "gzip") {
while($buffer = gzread($handle, 8192))
$ret .= $buffer;
return $ret;
}
elseif($FILE_TYPE == "bzip2") {
while($buffer = bzread($handle, 8192))
$ret .= $buffer;
return $ret;
}
}
function lwwrite($handle, $data)
{
global $FILE_TYPE;
if($FILE_TYPE == "plain")
return fwrite($handle, $data);
elseif($FILE_TYPE == "gzip")
return gzwrite($handle, $data);
elseif($FILE_TYPE == "bzip2")
return bzwrite($handle, $data);
}
// checks autentification
function authentified()
{
global $PASSWORD, $sc;
$pwd = md5($PASSWORD);
if(empty($PASSWORD) || $_COOKIE['AUT_LIONWIKI'] == $pwd || $sc == $PASSWORD) {
if(($PASSWORD != "" && empty($_COOKIE['AUT_LIONWIKI'])) || $_COOKIE['AUT_LIONWIKI'] != $pwd) {
setcookie('AUT_LIONWIKI', $pwd, time() + $PROTECTED_READ ? $COOKIE_LIFE_READ : $COOKIE_LIFE_WRITE);
$_COOKIE['AUT_LIONWIKI'] = $pwd;
}
return true;
} else
return false;
}
/** 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 '
{WIKI_TITLE} - {PAGE_TITLE_BRUT}
{plugin:RSS}
{PAGE_TITLE} |
|
{TOC}
{ERROR}
{CONTENT}
{RENAME_FORM} {RENAME_TEXT} {RENAME_INPUT} {FORM_PASSWORD} {FORM_PASSWORD_INPUT} {plugin:CAPTCHA_QUESTION} {plugin:CAPTCHA_INPUT} {RENAME_SUBMIT} {/RENAME_FORM}
{CONTENT_FORM} {CONTENT_TEXTAREA} {CONTENT_SUBMIT} {FORM_PASSWORD} {FORM_PASSWORD_INPUT} {plugin:CAPTCHA_QUESTION} {plugin:CAPTCHA_INPUT} {/CONTENT_FORM}
|
|
{SEARCH} |
Powered by {WIKI_VERSION}. {LAST_CHANGED_TEXT}: {LAST_CHANGED} {COOKIE} |
{EDIT} {HELP} {HISTORY} |
'; }
?>