From 22dad4cab3c92261a6f0e84931d283834788565c Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Thu, 5 Nov 2015 10:00:04 +0000
Subject: [PATCH] Begin work on access control. Add  variable and a setting,
 but they aren't used yet.

---
 core.php | 161 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 84 insertions(+), 77 deletions(-)

diff --git a/core.php b/core.php
index 15a163f..1ee043b 100644
--- a/core.php
+++ b/core.php
@@ -14,6 +14,13 @@ $env->user = "Anonymous";
 $env->is_logged_in = false;
 $env->is_admin = false;
 
+$paths = new stdClass();
+$paths->pageindex = "pageindex.json";
+$paths->searchindex = "invindex.json";
+$paths->idindex = "idindex.json";
+$paths->upload_file_prefix = "Files/";
+
+
 session_start();
 ///////// Login System /////////
 // Clear expired sessions
@@ -78,7 +85,7 @@ if($env->is_logged_in)
  * @summary	Converts a filesize into a human-readable string.
  * @source	http://php.net/manual/en/function.filesize.php#106569
  * @editor	Starbeamrainbowlabs
- * 
+ *
  * @param	$bytes		 - The number of bytes to convert.
  * @param	$decimals	 - The number of decimal places to preserve.
  */
@@ -92,9 +99,9 @@ function human_filesize($bytes, $decimals = 2)
  * @summary	Calculates the time sincce a particular timestamp and returns a
  * 			human-readable result.
  * @source	http://snippets.pro/snippet/137-php-convert-the-timestamp-to-human-readable-format/
- * 
+ *
  * @param $time - The timestamp to convert.
- * 
+ *
  * @returns {string} - The time since the given timestamp pas a human-readable string.
  */
 function human_time_since($time)
@@ -118,10 +125,10 @@ function human_time_since($time)
 
 /*
  * @summary A recursive glob() function.
- * 
+ *
  * @param $pattern - The glob pattern to use to find filenames.
  * @param $flags - The glob flags to use when finding filenames.
- * 
+ *
  * @returns {array} - An array of the filepaths that match the given glob.
  */
 // From http://in.php.net/manual/en/function.glob.php#106595
@@ -140,17 +147,17 @@ function glob_recursive($pattern, $flags = 0)
 
 /*
  * @summary Gets a list of all the sub pages of the current page.
- * 
+ *
  * @param $pageindex - The pageindex to use to search.
  * @param $pagename - The name of the page to list the sub pages of.
- * 
+ *
  * @returns An objectt containing all the subpages, and their respective distances from the given page name in the pageindex tree.
  */
 function get_subpages($pageindex, $pagename)
 {
 	$pagenames = get_object_vars($pageindex);
 	$result = new stdClass();
-	
+
 	$stem = "$pagename/";
 	$stem_length = strlen($stem);
 	foreach($pagenames as $entry => $value)
@@ -158,7 +165,7 @@ function get_subpages($pageindex, $pagename)
 		if(substr($entry, 0, $stem_length) == $stem)
 		{
 			// We found a subpage
-			
+
 			// Extract the subpage's key relative to the page that we are searching for
 			$subpage_relative_key = substr($entry, $stem_length, -3);
 			// Calculate how many times removed the current subpage is from the current page. 0 = direct descendant.
@@ -167,16 +174,16 @@ function get_subpages($pageindex, $pagename)
 			$result->$entry = $times_removed;
 		}
 	}
-	
+
 	unset($pagenames);
 	return $result;
 }
 
 /*
  * @summary Makes sure that a subpage's parents exist. Note this doesn't check the pagename itself.
- * 
+ *
  * @param The pagename to check.
- * 
+ *
  */
 function check_subpage_parents($pagename)
 {
@@ -187,14 +194,14 @@ function check_subpage_parents($pagename)
 		file_put_contents("./pageindex.json", json_encode($pageindex, JSON_PRETTY_PRINT));
 		return;
 	}
-	
+
 	$parent_pagename = substr($pagename, 0, strrpos($pagename, "/"));
 	$parent_page_filename = "$parent_pagename.md";
 	if(!file_exists($parent_page_filename))
 	{
 		// This parent page doesn't exist! Create it and add it to the page index.
 		touch($parent_page_filename, 0);
-		
+
 		$newentry = new stdClass();
 		$newentry->filename = $parent_page_filename;
 		$newentry->size = 0;
@@ -202,13 +209,13 @@ function check_subpage_parents($pagename)
 		$newentry->lasteditor = "none";
 		$pageindex->$parent_pagename = $newentry;
 	}
-	
+
 	check_subpage_parents($parent_pagename);
 }
 
 /*
  * @summary makes a path safe
- * 
+ *
  * @details paths may only contain alphanumeric characters, spaces, underscores, and dashes
  */
 function makepathsafe($string)
@@ -220,7 +227,7 @@ function makepathsafe($string)
 
 /*
  * @summary Hides an email address from bots by adding random html entities.
- * 
+ *
  * @returns The mangled email address.
  */
 function hide_email($str)
@@ -238,15 +245,15 @@ function hide_email($str)
 		else
 			$hidden_email .= "&#" . ord($str[$i]) . ";";
 	}
-	
+
 	return $hidden_email;
 }
 /*
  * @summary Checks to see if $haystack starts with $needle.
- * 
+ *
  * @param $haystack {string} The string to search.
  * @param $needle {string} The string to search for at the beginning of $haystack.
- * 
+ *
  * @returns {boolean} Whether $needle can be found at the beginning of $haystack.
  */
 function starts_with($haystack, $needle)
@@ -305,7 +312,7 @@ if(!file_exists("./pageindex.json"))
 	for($i = 0; $i < count($existingpages); $i++)
 	{
 		$pagefilename = $existingpages[$i];
-		
+
 		// Create a new entry
 		$newentry = new stdClass();
 		$newentry->filename = utf8_encode($pagefilename); // Store the filename
@@ -315,7 +322,7 @@ if(!file_exists("./pageindex.json"))
 		$newentry->lasteditor = utf8_encode("unknown"); // Set the editor to "unknown"
 		// Extract the name of the (sub)page without the ".md"
 		$pagekey = utf8_encode(substr($pagefilename, 0, -3));
-		
+
 		// Subpage parent checker
 		if(strpos($pagekey, "/") !== false)
 		{
@@ -334,7 +341,7 @@ if(!file_exists("./pageindex.json"))
 				$existingpages[] = $subpage_parent_filename;
 			}
 		}
-		
+
 		// Store the new entry in the new page index
 		$pageindex->$pagekey = $newentry;
 	}
@@ -362,30 +369,30 @@ class ids
 	public static function getid($pagename)
 	{
 		global $idindex;
-		
+
 		foreach ($idindex as $id => $entry)
 		{
 			if($entry == $pagename)
 				return $id;
 		}
-		
+
 		// This pagename doesn't have an id - assign it one quick!
 		return self::assign($pagename);
 	}
-	
+
 	/*
 	 * @summary Gets the page name associated with the given page id.
 	 */
 	public static function getpagename($id)
 	{
 		global $idindex;
-		
+
 		if(!isset($idindex->$id))
 			return false;
 		else
 			return $idindex->$id;
 	}
-	
+
 	/*
 	 * @summary Assigns an id to a pagename. Doesn't check to make sure that
 	 * 			pagename doesn't exist in the pageindex.
@@ -393,18 +400,18 @@ class ids
 	protected static function assign($pagename)
 	{
 		global $idindex;
-		
+
 		$nextid = count(array_keys(get_object_vars($idindex)));
-		
+
 		if(isset($idindex->$nextid))
 			throw new Exception("The pageid is corrupt! Pepperminty Wiki generated the id $nextid, but that id is already in use.");
-		
+
 		// Update the id index
 		$idindex->$nextid = utf8_encode($pagename);
-		
+
 		// Save the id index
 		file_put_contents("idindex.json", json_encode($idindex));
-		
+
 		return $nextid;
 	}
 }
@@ -464,13 +471,13 @@ class page_renderer
 	</body>
 </html>
 ";
-	
+
 	public static $main_content_template = "{navigation-bar}
 		<h1 class='sitename'>{sitename}</h1>
 		<main>
 		{content}
 		</main>
-		
+
 		<footer>
 			<p>{footer-message}</p>
 			<p>Powered by Pepperminty Wiki {version}, which was built by <a href='//starbeamrainbowlabs.com/'>Starbeamrainbowlabs</a>. Send bugs to 'bugs at starbeamrainbowlabs dot com' or <a href='//github.com/sbrl/Pepperminty-Wiki' title='Github Issue Tracker'>open an issue</a>.</p>
@@ -487,17 +494,17 @@ class page_renderer
 			<p><em>Timed at {generation-date}</em></p>
 			<p><em>Powered by Pepperminty Wiki {version}.</em></p>
 		</footer>";
-	
+
 	// An array of functions that have been registered to process the
 	// find / replace array before the page is rendered. Note that the function
 	// should take a *reference* to an array as its only argument.
 	protected static $part_processors = [];
-	
+
 	// Registers a function as a part post processor.
 	public static function register_part_preprocessor($function)
 	{
 		global $settings;
-		
+
 		// Make sure that the function we are about to register is valid
 		if(!is_callable($function))
 		{
@@ -506,19 +513,19 @@ class page_renderer
 			$admin_email = hide_email($settings->admindetails["email"]);
 			exit(page_renderer::render("$settings->sitename - Module Error", "<p>$settings->sitename has got a misbehaving module installed that tried to register an invalid HTML handler with the page renderer. Please contact $settings->sitename's administrator $admin_name at <a href='mailto:$admin_email'>$admin_email</a>."));
 		}
-		
+
 		self::$part_processors[] = $function;
-		
+
 		return true;
 	}
-	
+
 	public static function render($title, $content, $body_template = false)
 	{
 		global $settings, $start_time, $version;
-		
+
 		if($body_template === false)
 			$body_template = self::$main_content_template;
-		
+
 		if(strlen($settings->logo_url) > 0)
 		{
 			// A logo url has been specified
@@ -535,50 +542,50 @@ class page_renderer
 					throw new Exception("Invalid logo_position '$settings->logo_position'. Valid values are either \"left\" or \"right\" and are case sensitive.");
 			}
 		}
-		
+
 		$parts = [
 			"{body}" => $body_template,
-			
+
 			"{sitename}" => $logo_html,
 			"{version}" => $version,
 			"{favicon-url}" => $settings->favicon,
 			"{header-html}" => self::get_css_as_html(),
-			
+
 			"{navigation-bar}" => self::render_navigation_bar($settings->nav_links, $settings->nav_links_extra, "top"),
 			"{navigation-bar-bottom}" => self::render_navigation_bar($settings->nav_links_bottom, [], "bottom"),
-			
+
 			"{admin-details-name}" => $settings->admindetails["name"],
 			"{admin-details-email}" => $settings->admindetails["email"],
-			
+
 			"{admins-name-list}" => implode(", ", $settings->admins),
-			
+
 			"{generation-date}" => date("l jS \of F Y \a\\t h:ia T"),
-			
+
 			"{all-pages-datalist}" => self::generate_all_pages_datalist(),
-			
+
 			"{footer-message}" => $settings->footer_message,
-			
+
 			/// Secondary Parts ///
-			
+
 			"{content}" => $content,
 			"{title}" => $title,
 		];
-		
+
 		// Pass the parts through the part processors
 		foreach(self::$part_processors as $function)
 		{
 			$function($parts);
 		}
-		
+
 		$result = self::$html_template;
-		
+
 		$result = str_replace(array_keys($parts), array_values($parts), $result);
-		
+
 		$result = str_replace([
-			
+
 		], [
 		], $result);
-		
+
 		$result = str_replace("{generation-time-taken}", microtime(true) - $start_time, $result);
 		return $result;
 	}
@@ -590,24 +597,24 @@ class page_renderer
 	{
 		return self::render($title, $content, self::$minimal_content_template);
 	}
-	
-	
+
+
 	public static function get_css_as_html()
 	{
 		global $settings;
-		
+
 		if(preg_match("/^[^\/]*\/\/|^\//", $settings->css))
 			return "<link rel='stylesheet' href='$settings->css' />";
 		else
 			return "<style>$settings->css</style>";
 	}
-	
+
 	public static $nav_divider = "<span class='nav-divider inflexible'> | </span>";
-	
+
 	/*
 	 * @summary Function to render a navigation bar from an array of links. See
 	 * 			$settings->nav_links for format information.
-	 * 
+	 *
 	 * @param $nav_links - The links to add to the navigation bar.
 	 * @param $nav_links_extra - The extra nav links to add to the "More..."
 	 * 							 menu.
@@ -616,7 +623,7 @@ class page_renderer
 	{
 		global $settings, $env;
 		$result = "<nav class='$class'>\n";
-		
+
 		// Loop over all the navigation links
 		foreach($nav_links as $item)
 		{
@@ -636,22 +643,22 @@ class page_renderer
 						else
 							$result .= "<span class='inflexible'>Browsing as Anonymous.</span>" . /*page_renderer::$nav_divider . */"<span><a href='index.php?action=login'>Login</a></span>" . page_renderer::$nav_divider;
 						break;
-					
+
 					case "search": // Displays a search bar
 						$result .= "<span class='inflexible'><form method='get' action='index.php' style='display: inline;'><input type='search' name='page' list='allpages' placeholder='Type a page name here and hit enter' /><input type='hidden' name='search-redirect' value='true' /></form></span>";
 						break;
-					
+
 					case "divider": // Displays a divider
 						$result .= page_renderer::$nav_divider;
 						break;
-					
+
 					case "menu":
 						$result .= "<span class='inflexible nav-more'><label for='more-menu-toggler'>More...</label>
 <input type='checkbox' class='off-screen' id='more-menu-toggler' />";
 						$result .= page_renderer::render_navigation_bar($nav_links_extra, [], "nav-more-menu");
 						$result .= "</span>";
 						break;
-					
+
 					// It isn't a keyword, so just output it directly
 					default:
 						$result .= "<span>$item</span>";
@@ -663,7 +670,7 @@ class page_renderer
 				$result .= "<span><a href='" . str_replace("{page}", $env->page, $item[1]) . "'>$item[0]</a></span>";
 			}
 		}
-		
+
 		$result .= "</nav>";
 		return $result;
 	}
@@ -674,21 +681,21 @@ class page_renderer
 		if(in_array($name, $settings->admins))
 			$result .= $settings->admindisplaychar;
 		$result .= $name;
-		
+
 		return $result;
 	}
-	
+
 	public static function generate_all_pages_datalist()
 	{
 		global $pageindex;
-		
+
 		$result = "<datalist id='allpages'>\n";
 		foreach($pageindex as $pagename => $pagedetails)
 		{
 			$result .= "\t\t\t<option value='$pagename' />\n";
 		}
 		$result .= "\t\t</datalist>";
-		
+
 		return $result;
 	}
 }
@@ -745,7 +752,7 @@ function add_parser($name, $parser_code)
 	global $parsers;
 	if(isset($parsers[$name]))
 		throw new Exception("Can't register parser with name '$name' because a parser with that name already exists.");
-	
+
 	$parsers[$name] = $parser_code;
 }
 function parse_page_source($source)
@@ -753,7 +760,7 @@ function parse_page_source($source)
 	global $settings, $parsers;
 	if(!isset($parsers[$settings->parser]))
 		exit(page_renderer::render_main("Parsing error - $settings->sitename", "<p>Parsing some page source data failed. This is most likely because $settings->sitename has the parser setting set incorrectly. Please contact <a href='mailto:" . hide_email($settings->admindetails["email"]) . "'>" . $settings->admindetails["name"] . "</a>, your $settings->sitename Administrator."));
-	
+
 /* Not needed atm because escaping happens when saving, not when rendering *
 	if($settings->clean_raw_html)
 		$source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
