filename = utf8_encode($pagefilename); $newentry->size = filesize($pagefilename); $newentry->lastmodified = filemtime($pagefilename); $newentry->lasteditor = utf8_encode("unknown"); $pagekey = utf8_encode(substr($pagefilename, 0, -3)); $pageindex->$pagekey = $newentry; } file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); } else { $pageindex = json_decode(file_get_contents("./pageindex.json")); } /* * @summary makes a path safe * * @details paths may only contain alphanumeric characters, spaces, underscores, and dashes */ function makepathsafe($string) { return preg_replace("/[^0-9a-zA-Z\_\-\ ]/i", "", $string); } /* * @summary Hides an email address from bots by adding random html entities. * * @returns The mangled email address. */ function hide_email($str) { $hidden_email = ""; for($i = 0; $i < strlen($str); $i++) { if($str[$i] == "@") { $hidden_email .= "" . ord("@") . ";"; continue; } if(rand(0, 1) == 0) $hidden_email .= $str[$i]; else $hidden_email .= "" . ord($str[$i]) . ";"; } return $hidden_email; } //Work around an Opera + Syntastic bug where there is no margin at the left hand side if there isn't a query string when accessing a .php file if(!isset($_GET["action"]) and !isset($_GET["page"])) { http_response_code(302); header("location: index.php?action=view&page=$defaultpage"); exit(); } //make sure that the action is set if(!isset($_GET["action"])) $_GET["action"] = "view"; if(!isset($_GET["page"]) or strlen($_GET["page"]) === 0) $_GET["page"] = $defaultpage; //redirect the user to the safe version of the path if they entered an unsafe character if(makepathsafe($_GET["page"]) !== $_GET["page"]) { http_response_code(301); header("location: index.php?action=" . rawurlencode($_GET["action"]) . "&page=" . makepathsafe($_GET["page"])); header("x-requested-page: " . $_GET["page"]); header("x-actual-page: " . makepathsafe($_GET["page"])); exit(); } $page = $_GET["page"]; /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// HTML fragments ////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// function renderpage($title, $content, $minimal = false) { global $sitename, $page, $css, $favicon, $user, $isloggedin, $isadmin, $admins, $admindisplaychar, $navlinks, $admindetails, $start_time, $pageindex; $html = "
From $sitename, which is managed by " . $admindetails["name"] . ".
Timed at " . date("l jS \of F Y \a\\t h:ia T") . ".
Powered by Pepperminty Wiki
"; } else { $html .= "\1', // quote '/`(.*?)`/' => '
\1
', // inline code
'/\n\*(.*)/' => 'self::ul_list', // ul lists
'/\n[0-9]+\.(.*)/' => 'self::ol_list', // ol lists
'/\n(>|\>)(.*)/' => 'self::blockquote', // blockquotes
'/\n-{3,}/' => "\n/' => "\n" // fix extra blockquote ); private static function para ($regs) { $line = $regs[1]; $trimmed = trim ($line); if (preg_match ('/^<\/?(ul|ol|li|h|p|bl)/', $trimmed)) { return "\n" . $line . "\n"; } return sprintf ("\n%s
\n", $trimmed); } private static function ul_list ($regs) { $item = $regs[1]; return sprintf ("\n\n\t
", trim($item)); } private static function ol_list ($regs) { $item = $regs[1]; return sprintf ("\n- %s
\n\n\t
", trim($item)); } private static function blockquote ($regs) { $item = $regs[2]; return sprintf ("\n- %s
\n%s", trim($item)); } private static function header ($regs) { list ($tmp, $chars, $header) = $regs; $level = strlen ($chars); return sprintf ('%s ', $level + 1, trim($header), $level + 1); } /** * Add a rule. */ public static function add_rule ($regex, $replacement) { self::$rules[$regex] = $replacement; } /** * Render some Markdown into HTML. */ public static function render ($text) { foreach (self::$rules as $regex => $replacement) { if (is_callable ( $replacement)) { $text = preg_replace_callback ($regex, $replacement, $text); } else { $text = preg_replace ($regex, $replacement, $text); } } return trim ($text); } } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////// //////////////// Functions //////////////// /////////////////////////////////////////// //from http://php.net/manual/en/function.filesize.php#106569 function human_filesize($bytes, $decimals = 2) { $sz = 'BKMGTPEYZ'; $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor]; } //from http://snippets.pro/snippet/137-php-convert-the-timestamp-to-human-readable-format/ function human_time_since($time) { $timediff = time() - $time; $tokens = array ( 31536000 => 'year', 2592000 => 'month', 604800 => 'week', 86400 => 'day', 3600 => 'hour', 60 => 'minute', 1 => 'second' ); foreach ($tokens as $unit => $text) { if ($timediff < $unit) continue; $numberOfUnits = floor($timediff / $unit); return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').' ago'; } } /////////////////////////////////////////// switch($_GET["action"]) { /* * _ _ _ * ___ __| (_) |_ * / _ \/ _` | | __| * | __/ (_| | | |_ * \___|\__,_|_|\__| * %edit% */ case "edit": if(!$editing) { http_response_code(203); header("location: index.php?page=$page"); } $filename = "$page.md"; $creatingpage = !isset($pageindex->$page); if((isset($_GET["newpage"]) and $_GET["newpage"] == "true") or $creatingpage) { $title = "Creating $page"; } else { $title = "Editing $page"; } $pagetext = ""; if(isset($pageindex->$page)) { $pagetext = file_get_contents($filename); } if((!$isloggedin and !$anonedits) or !$editing) { if(!$creatingpage) { //the page already exists - let the user view the page source exit(renderpage("Viewing source for $page", "")); } else { http_response_code(404); exit(renderpage("404 - $page", "The page
$page
does not exist, but you do not have permission to create it.If you haven't already, perhaps you should try logging in.
")); } } $content = "$title
"; if(!$isloggedin and $anonedits) { $content .= "Warning: You are not logged in! Your IP address may be recorded.
"; } $content .= ""; exit(renderpage("$title - $sitename", $content)); break; /* * * ___ __ ___ _____ * / __|/ _` \ \ / / _ \ * \__ \ (_| |\ V / __/ * |___/\__,_| \_/ \___| * %save% */ case "save": if(!$editing) { header("location: index.php?page=$page"); exit(renderpage("Error saving edit", "Editing is currently disabled on this wiki.
")); } if(!$isloggedin and !$anonedits) { http_response_code(403); header("refresh: 5; url=index.php?page=$page"); exit("You are not logged in, so you are not allowed to save pages on $sitename. Redirecting in 5 seconds...."); } if(!isset($_POST["content"])) { http_response_code(400); header("refresh: 5; url=index.php?page=$page"); exit("Bad request: No content specified."); } if(file_put_contents("$page.md", htmlentities($_POST["content"]), ENT_QUOTES) !== false) { //update the page index if(!isset($pageindex->$page)) { $pageindex->$page = new stdClass(); $pageindex->$page->filename = "$page.md"; } $pageindex->$page->size = strlen($_POST["content"]); $pageindex->$page->lastmodified = time(); if($isloggedin) $pageindex->$page->lasteditor = utf8_encode($user); else $pageindex->$page->lasteditor = utf8_encode("anonymous"); file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); if(isset($_GET["newpage"])) http_response_code(201); else http_response_code(200); header("location: index.php?page=$page"); exit(); } else { http_response_code(507); exit(renderpage("Error saving page - $sitename", "$sitename failed to write your changes to the disk. Your changes have not been saved, however you may be able to recover your edit by pressing the back button in your browser.
Please tell the administrator of this wiki (" . $admindetails["name"] . ") about this problem.
")); } break; /* * _ _ _ * | (_)___| |_ * | | / __| __| * | | \__ \ |_ * |_|_|___/\__| * %list% */ case "list": $title = "All Pages"; $content = "$title on $sitename
"; exit(renderpage("$title - $sitename", $content)); break; /* * _ _ _ * __| | ___| | ___| |_ ___ * / _` |/ _ \ |/ _ \ __/ _ \ * | (_| | __/ | __/ || __/ * \__,_|\___|_|\___|\__\___| * %delete% */ case "delete": if(!$isadmin) { exit(renderpage("Deleting $page - error", "
\n"; foreach($pageindex as $pagename => $pagedetails) { $content .= "\t\t Page Name Size Last Editor Last Edited Time Since Last Edit \n"; } $content .= " $pagename " . human_filesize($pagedetails->size) . " $pagedetails->lasteditor " . date("l jS \of F Y \a\\t h:ia T", $pagedetails->lastmodified) . " " . human_time_since($pagedetails->lastmodified) . " You tried to delete $page, but you are not an admin so you don't have permission to do that.
You should try logging in as an admin.
")); } if(!isset($_GET["delete"]) or $_GET["delete"] !== "yes") { exit(renderpage("Deleting $page", "You are about to delete $page. You can't undo this!
Click here to go back.")); } unset($pageindex->$page); //delete the page from the page index file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); //save the new page index unlink("./$page.md"); //delete the page from the disk exit(renderpage("Deleting $page - $sitename", "
$page has been deleted. Go back to the main page.
")); break; /* * __ __ * | \/ | _____ _____ * | |\/| |/ _ \ \ / / _ \ * | | | | (_) \ V / __/ * |_| |_|\___/ \_/ \___| * %move% */ case "move": if(!$isadmin) exit(renderpage("Moving $page - Error", "You tried to move $page, but you do not have permission to do that.
You should try logging in as an admin.
")); if(!isset($_GET["new_name"]) or strlen($_GET["new_name"]) == 0) exit(renderpage("Moving $page", "Moving $page
")); $new_name = makepathsafe($_GET["new_name"]); if(!isset($pageindex->$page)) exit(renderpage("Moving $page - Error", "You tried to move $page to $new_name, but the page with the name $page does not exist in the first place.
Nothing has been changed.
")); if($page == $new_name) exit(renderpage("Moving $page - Error", "You tried to move $page, but the new name you gave is the same as it's current name.
It is possible that you tried to use some characters in the new name that are not allowed and were removed.
Page names may only contain alphanumeric characters, dashes, and underscores.
")); //move the page in the page index $pageindex->$new_name = new stdClass(); foreach($pageindex->$page as $key => $value) { $pageindex->$new_name->$key = $value; } unset($pageindex->$page); file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT)); //move the page on the disk rename("$page.md", "$new_name.md"); exit(renderpage("Moving $page", "$page has been moved to $new_name successfully.
")); break; /* * _ _ * | |__ ___| |_ __ * | '_ \ / _ \ | '_ \ * | | | | __/ | |_) | * |_| |_|\___|_| .__/ * %help% |_| */ case "help": $title = "Help - $sitename"; $content = "$sitename Help
Welcome to $sitename!
$sitename is powered by Pepperminty wiki, a complete wiki in a box you can drop into your server.
Navigating
All the navigation links can be found in the top right corner, along with a box in which you can type a page name and hit enter to be taken to that page (if your site administrator has enabled it).
In order to edit pages on $sitename, you probably need to be logged in. If you do not already have an account you will need to ask $sitename's administrator for an account since there is not registration form. Note that the $sitename's administrator may have changed these settings to allow anonymous edits.
Editing
$sitename's editor uses a modified version of slimdown, a flavour of markdown that is implementated using regular expressions. See the credits page for more information and links to the original source for this. A quick reference can be found below:
"; exit(renderpage($title, $content)); break; /* * _ _ * | | ___ __ _(_)_ __ * | |/ _ \ / _` | | '_ \ * | | (_) | (_| | | | | | * |_|\___/ \__, |_|_| |_| * |___/ %login% */ case "login": $title = "Login to $sitename"; $content = "
Type This To get this _italics_
italics *bold*
bold # Heading
Heading
## Sub Heading
Sub Heading
[[Internal Link]]
Internal Link [[Display Text|Internal Link]]
Display Text [Display text](//google.com/)
Display Text ~~Strikethrough~~
Strikethough> Blockquote
> Some text Blockquote
Some text---
Login to $sitename
\n"; if(isset($_GET["failed"])) $content .= "\t\tLogin failed.
\n"; $content .= "\t\t"; exit(renderpage($title, $content)); break; /* * _ _ _ _ * ___| |__ ___ ___| | _| | ___ __ _(_)_ __ * / __| '_ \ / _ \/ __| |/ / |/ _ \ / _` | | '_ \ * | (__| | | | __/ (__| <| | (_) | (_| | | | | | * \___|_| |_|\___|\___|_|\_\_|\___/ \__, |_|_| |_| * %checklogin% |___/ */ case "checklogin": if(isset($_POST["user"]) and isset($_POST["pass"])) { //the user wants to log in $user = $_POST["user"]; $pass = $_POST["pass"]; if($users[$user] == hash("sha256", $pass)) { $isloggedin = true; $expiretime = time() + 60*60*24*30; //30 days from now setcookie($cookieprefix . "-user", $user, $expiretime, "/"); setcookie($cookieprefix . "-pass", hash("sha256", $pass), $expiretime, "/"); //redirect to wherever the user was going http_response_code(302); if(isset($_POST["goto"])) header("location: " . $_POST["returnto"]); else header("location: index.php"); exit(); } else { http_response_code(302); header("location: index.php?action=login&failed=yes"); exit(); } } else { http_response_code(302); header("location: index.php?action=login&failed=yes&badrequest=yes"); exit(); } break; /* * _ _ * | | ___ __ _ ___ _ _| |_ * | |/ _ \ / _` |/ _ \| | | | __| * | | (_) | (_| | (_) | |_| | |_ * |_|\___/ \__, |\___/ \__,_|\__| * |___/ %logout% */ case "logout": $isloggedin = false; unset($user); unset($pass); setcookie($cookieprefix . "-user", null, -1, "/"); setcookie($cookieprefix . "-pass", null, -1, "/"); exit(renderpage("Logout Successful", "Logout Successful
Logout Successful. You can login again here.
")); break; /* * _ _ _ * ___ _ __ ___ __| (_) |_ ___ * / __| '__/ _ \/ _` | | __/ __| * | (__| | | __/ (_| | | |_\__ \ * \___|_| \___|\__,_|_|\__|___/ * %credits% */ case "credits": $title = "Credits - $sitename"; $content = "$sitename credits
$sitename is powered by Pepperminty Wiki - an entire wiki packed inside a single file, which was built by Starbeamrainbowlabs, and can be found on github.
A slightly modified version of slimdown is used to parse text source into HTML. Slimdown is by Johnny Broadway, which can be found on github.
The default favicon is from Open Clipart by bluefrog23, and can be found here.
"; exit(renderpage($title, $content)); break; /* * _ _ * | |__ __ _ ___| |__ * | '_ \ / _` / __| '_ \ * | | | | (_| \__ \ | | | * |_| |_|\__,_|___/_| |_| * %hash% */ case "hash": if(!isset($_GET["string"])) { http_response_code(400); exit(renderpage("Bad request", "The
GET
parameterstring
must be specified.It is strongly recommended that you utilise this page via a private or incognito window.
")); } else { exit(renderpage("Hashed string", ""))); } break; /* * _ * __ _(_) _____ __ * \ \ / / |/ _ \ \ /\ / / * \ V /| | __/\ V V / * \_/ |_|\___| \_/\_/ * %view% */ case "view": default: //check to make sure that the page exists if(!isset($pageindex->$page)) { if($editing) { //editing is enabled, redirect to the editing page http_response_code(307); //temporary redirect header("location: index.php?action=edit&newpage=yes&page=" . rawurlencode($page)); exit(); } else { //editing is disabled, show an error message http_response_code(404); exit(renderpage("$page - 404 - $sitename", "
" . $_GET["string"] . "
→" . hash("sha256", $_GET["string"] . "
$page does not exist.
Since editing is currently disabled on this wiki, you may not create this page. If you feel that this page should exist, try contacting this wiki's Administrator.
")); } } $title = "$page - $sitename"; $content = "$page
"; $slimdown_start = microtime(true); $content .= Slimdown::render(file_get_contents("$page.md")); $content .= "\n\t\n"; if(isset($_GET["printable"]) and $_GET["printable"] === "yes") $minimal = true; else $minimal = false; exit(renderpage($title, $content, $minimal)); break; } ?>