2014-12-25 20:31:01 +00:00
< ? php
$start_time = time ( true );
2014-12-26 11:06:37 +00:00
{ settings }
2014-12-25 20:31:01 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////// Do not edit below this line unless you know what you are doing! ///////////////
///////////////////////////////////////////////////////////////////////////////////////////////
2015-03-14 18:53:14 +00:00
$version = " 0.4 " ;
2015-01-10 10:52:03 +00:00
session_start ();
2014-12-25 20:31:01 +00:00
///////// Login System /////////
2015-01-10 10:52:03 +00:00
//clear expired sessions
2015-04-09 14:13:07 +00:00
if ( isset ( $_SESSION [ " $settings->sessionprefix -expiretime " ]) and
$_SESSION [ " $settings->sessionprefix -expiretime " ] < time ())
2015-01-10 10:52:03 +00:00
{
//clear the session variables
$_SESSION = [];
session_destroy ();
}
2015-04-09 14:13:07 +00:00
if ( ! isset ( $_SESSION [ $settings -> sessionprefix . " -user " ]) and
! isset ( $_SESSION [ $settings -> sessionprefix . " -pass " ]))
2014-12-25 20:31:01 +00:00
{
//the user is not logged in
$isloggedin = false ;
}
else
{
2015-04-09 14:13:07 +00:00
$user = $_SESSION [ $settings -> sessionprefix . " -user " ];
$pass = $_SESSION [ $settings -> sessionprefix . " -pass " ];
if ( $settings -> users [ $user ] == $pass )
2014-12-25 20:31:01 +00:00
{
//the user is logged in
$isloggedin = true ;
}
else
{
//the user's login details are invalid (what is going on here?)
2015-01-10 10:52:03 +00:00
//unset the session variables, treat them as an anonymous user, and get out of here
2014-12-25 20:31:01 +00:00
$isloggedin = false ;
unset ( $user );
unset ( $pass );
2015-01-10 10:52:03 +00:00
//clear the session data
$_SESSION = []; //delete al lthe variables
session_destroy (); //destroy the session
2014-12-25 20:31:01 +00:00
}
}
2014-12-26 18:14:38 +00:00
//check to see if the currently logged in user is an admin
$isadmin = false ;
if ( $isloggedin )
{
2015-04-09 14:13:07 +00:00
foreach ( $settings -> admins as $admin_username )
2014-12-26 18:14:38 +00:00
{
if ( $admin_username == $user )
{
$isadmin = true ;
break ;
}
}
}
2014-12-25 20:31:01 +00:00
/////// Login System End ///////
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// Security and Consistency Measures ////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
if ( ! file_exists ( " ./pageindex.json " ))
{
$existingpages = glob ( " *.md " );
$pageindex = new stdClass ();
foreach ( $existingpages as $pagefilename )
{
$newentry = new stdClass ();
$newentry -> 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 ));
2015-04-09 14:13:07 +00:00
unset ( $existingpages );
2014-12-25 20:31:01 +00:00
}
else
{
$pageindex = json_decode ( file_get_contents ( " ./pageindex.json " ));
}
/*
* @ summary makes a path safe
2014-12-25 20:48:14 +00:00
*
2014-12-25 20:31:01 +00:00
* @ 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 .
2014-12-25 20:48:14 +00:00
*
2014-12-25 20:31:01 +00:00
* @ 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 ]) . " ; " ;
}
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
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 );
2015-04-11 17:30:01 +00:00
header ( " location: index.php?action= $settings->defaultaction &page= $defaultpage " );
2014-12-25 20:31:01 +00:00
exit ();
}
//make sure that the action is set
if ( ! isset ( $_GET [ " action " ]))
$_GET [ " action " ] = " view " ;
if ( ! isset ( $_GET [ " page " ]) or strlen ( $_GET [ " page " ]) === 0 )
2015-04-09 14:13:07 +00:00
$_GET [ " page " ] = $settings -> defaultpage ;
2014-12-25 20:31:01 +00:00
//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 ();
}
2014-12-27 19:59:32 +00:00
$page = $_GET [ " page " ];
2014-12-25 20:31:01 +00:00
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// HTML fragments //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
function renderpage ( $title , $content , $minimal = false )
{
2015-04-09 14:13:07 +00:00
global $settings , $page , $user , $isloggedin , $isadmin , $start_time , $pageindex ;
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
$html = " <!DOCTYPE HTML>
< html >< head >
< meta charset = 'utf-8' />
< title > $title </ title >
2015-02-24 08:35:25 +00:00
< meta name = viewport content = 'width=device-width, initial-scale=1' />
2015-04-09 14:13:07 +00:00
< link rel = 'shortcut icon' href = '$settings->favicon' /> " ;
if ( preg_match ( " /^[^ \ /]* \ / \ /|^ \ // " , $settings -> css ))
2014-12-25 20:48:14 +00:00
{
2015-04-09 14:13:07 +00:00
$html .= " \n \t \t <link rel='stylesheet' href=' $settings->css ' /> \n " ;
2014-12-25 20:48:14 +00:00
}
else
{
2015-04-09 14:13:07 +00:00
$html .= " \n \t \t <style> $settings->css </style> \n " ;
2014-12-25 20:48:14 +00:00
}
$html .= " </head><body> \n " ;
2014-12-25 20:31:01 +00:00
//////////
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
if ( $minimal )
{
$html .= " $content
< hr class = 'footerdivider' />
2015-04-09 14:13:07 +00:00
< p >< em > From $settings -> sitename , which is managed by " . $settings->admindetails [ " name " ] . " .</ em ></ p >
2014-12-25 20:31:01 +00:00
< p >< em > Timed at " . date( " l jS \of F Y \a\\t h : ia T " ) . " .</ em ></ p >
< p >< em > Powered by Pepperminty Wiki </ em ></ p > " ;
}
else
{
$html .= " <nav> \n " ;
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
if ( $isloggedin )
2014-12-26 18:14:38 +00:00
{
$html .= " \t \t Logged in as " ;
if ( $isadmin )
2015-04-09 14:13:07 +00:00
$html .= $settings -> admindisplaychar ;
2014-12-26 18:14:38 +00:00
$html .= " $user . <a href='index.php?action=logout'>Logout</a>. | \n " ;
}
2014-12-25 20:31:01 +00:00
else
$html .= " \t \t Browsing as Anonymous. <a href='index.php?action=login'>Login</a>. | \n " ;
2015-04-09 14:13:07 +00:00
foreach ( $settings -> navlinks as $item )
2014-12-25 20:31:01 +00:00
{
2014-12-26 12:19:43 +00:00
if ( is_string ( $item ))
2014-12-25 20:31:01 +00:00
{
2014-12-26 12:19:43 +00:00
//the item is a string
switch ( $item )
{
//keywords
case " search " : //displays a search bar
$html .= " <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' /></form> " ;
break ;
//it isn't a keyword, so just output it directly
default :
$html .= $item ;
}
2014-12-25 20:31:01 +00:00
}
else
{
//output the display as a link to the url
2014-12-27 19:59:32 +00:00
$html .= " \t \t <a href=' " . str_replace ( " { page} " , $page , $item [ 1 ]) . " '> $item[0] </a> \n " ;
2014-12-25 20:31:01 +00:00
}
}
2014-12-26 12:19:43 +00:00
2014-12-25 20:31:01 +00:00
$html .= " </nav>
2015-04-09 14:13:07 +00:00
< h1 class = 'sitename' > $settings -> sitename </ h1 >
2014-12-25 20:31:01 +00:00
$content
< hr class = 'footerdivider' />
< footer >
2015-01-05 18:44:11 +00:00
< p > Powered by Pepperminty Wiki , which was built by < a href = '//starbeamrainbowlabs.com/' > Starbeamrainbowlabs </ a >. Send bugs to 'bugs at starbeamrainbowlabs dot com' or open an issue < a href = '//github.com/sbrl/Pepperminty-Wiki' > on github </ a >.</ p >
2015-04-09 14:13:07 +00:00
< p > Your local friendly administrators are " . implode( " , " , $settings->admins ) . " .
< p > This wiki is managed by < a href = 'mailto:" . hide_email($settings->admindetails["email"]) . "' > " . $settings->admindetails [ " name " ] . " </ a >.</ p >
2014-12-25 20:31:01 +00:00
</ footer >
< datalist id = 'allpages' > \n " ;
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
foreach ( $pageindex as $pagename => $pagedetails )
{
$html .= " \t \t <option value=' $pagename ' /> \n " ;
}
$html .= " \t </datalist> " ;
}
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
//////////
$gentime = microtime ( true ) - $start_time ;
$html .= " \n \t <!-- Took $gentime seconds to generate -->
2015-01-05 18:50:51 +00:00
</ body ></ html > " ;
2014-12-25 20:48:14 +00:00
2014-12-25 20:31:01 +00:00
return $html ;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// Slimdown /////////////////////////////////////////
2014-12-29 13:51:06 +00:00
////////////////////////////////////////////////////////////////////////////// %slimdown% //
2014-12-25 20:31:01 +00:00
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Slimdown - A very basic regex - based Markdown parser . Supports the
* following elements ( and can be extended via Slimdown :: add_rule ()) :
*
* - Headers
* - Links
* - Bold
* - Emphasis
* - Deletions
* - Quotes
* - Inline code
* - Blockquotes
* - Ordered / unordered lists
* - Horizontal rules
*
* Author : Johnny Broadway < johnny @ johnnybroadway . com >
* Website : https :// gist . github . com / jbroadway / 2836900
* License : MIT
*/
/**
* Modified by Starbeamrainbowlabs ( starbeamrainbowlabs )
2014-12-25 20:48:14 +00:00
*
2014-12-25 20:31:01 +00:00
* Changed bold to use single asterisks
* Changed italics to use single underscores
* Added one to add the heading levels ( no < h1 > tags allowed )
* Added wiki style internal link parsing
* Added wiki style internal link parsing with display text
*/
class Slimdown {
public static $rules = array (
'/\r\n/' => " \n " , // new line normalisation
'/(#+)(.*)/' => 'self::header' , // headers
'/(\*)(.*?)\1/' => '<strong>\2</strong>' , // bold
'/(_)(.*?)\1/' => '<em>\2</em>' , // emphasis
'/\[\[([a-zA-Z0-9\_\- ]+)\|([a-zA-Z0-9\_\- ]+)\]\]/' => '<a href=\'index.php?page=\1\'>\2</a>' , //internal links with display text
'/\[\[([a-zA-Z0-9\_\- ]+)\]\]/' => '<a href=\'index.php?page=\1\'>\1</a>' , //internal links
'/\[([^\[]+)\]\(([^\)]+)\)/' => '<a href=\'\2\' target=\'_blank\'>\1</a>' , // links
'/\~\~(.*?)\~\~/' => '<del>\1</del>' , // del
'/\:\"(.*?)\"\:/' => '<q>\1</q>' , // quote
'/`(.*?)`/' => '<code>\1</code>' , // inline code
2014-12-29 13:51:06 +00:00
'/\n\s*(\*|-)(.*)/' => 'self::ul_list' , // ul lists
2014-12-25 20:31:01 +00:00
'/\n[0-9]+\.(.*)/' => 'self::ol_list' , // ol lists
'/\n(>|\>)(.*)/' => 'self::blockquote' , // blockquotes
'/\n-{3,}/' => " \n <hr /> " , // horizontal rule
'/\n([^\n]+)\n\n/' => 'self::para' , // add paragraphs
'/<\/ul>\s?<ul>/' => '' , // fix extra ul
'/<\/ol>\s?<ol>/' => '' , // fix extra ol
'/<\/blockquote><blockquote>/' => " \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 <p>%s</p> \n " , $trimmed );
}
private static function ul_list ( $regs ) {
2014-12-29 13:51:06 +00:00
$item = $regs [ 2 ];
2014-12-25 20:31:01 +00:00
return sprintf ( " \n <ul> \n \t <li>%s</li> \n </ul> " , trim ( $item ));
}
private static function ol_list ( $regs ) {
$item = $regs [ 1 ];
return sprintf ( " \n <ol> \n \t <li>%s</li> \n </ol> " , trim ( $item ));
}
private static function blockquote ( $regs ) {
$item = $regs [ 2 ];
return sprintf ( " \n <blockquote>%s</blockquote> " , trim ( $item ));
}
private static function header ( $regs ) {
list ( $tmp , $chars , $header ) = $regs ;
$level = strlen ( $chars );
return sprintf ( '<h%d>%s</h%d>' , $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
2015-04-09 19:16:17 +00:00
//edited by Starbeamrainbowlabs
2014-12-25 20:31:01 +00:00
function human_filesize ( $bytes , $decimals = 2 )
{
2015-04-09 14:29:29 +00:00
$sz = [ " B " , " KB " , " MB " , " GB " , " TB " , " PB " , " EB " , " YB " , " ZB " ];
2014-12-25 20:31:01 +00:00
$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' ;
}
}
///////////////////////////////////////////
2015-04-11 17:30:01 +00:00
//////////////////////////
/// Module functions ///
//////////////////////////
// These functions are //
// used by modules to //
// register themselves //
// or new pages. //
//////////////////////////
$modules = []; // list that contains all the loaded modules
// function to register a module
function register_module ( $moduledata )
2014-12-25 20:31:01 +00:00
{
2015-04-11 17:30:01 +00:00
$modules [] = $moduledata ;
}
2014-12-26 12:44:03 +00:00
2015-04-11 17:30:01 +00:00
// function to register an action handler
$actions = new stdClass ();
function add_action ( $action_name , $func )
{
$actions -> $action_name = $func ;
}
2014-12-27 19:59:32 +00:00
2015-04-11 17:30:01 +00:00
//////////////////////////////////////////////////////////////////
2014-12-29 11:41:43 +00:00
2015-04-11 17:30:01 +00:00
// %next_module% //
2014-12-29 11:41:43 +00:00
2015-04-11 17:30:01 +00:00
// execute each module's code
foreach ( $modules as $moduledata )
{
$moduledata [ " code " ]();
}
// make sure that the credits page exists
if ( ! isset ( $actions [ " credits " ]))
{
exit ( renderpage ( " Error - $settings -> $sitename " , " <p>No credits page detected. The credits page is a required module!</p> " ))
}
2014-12-28 10:28:07 +00:00
2015-04-11 17:30:01 +00:00
// Perform the appropriate action
if ( isset ( $actions [ strtolower ( $_GET [ " action " ])]))
{
$req_action = strtolower ( $_GET [ " action " ]);
$req_action_data = $action_name -> $req_action ;
$req_action_data [ " code " ]();
}
else
{
exit ( renderpage ( " Error - $settings->sitename " , " ,p>No action called " . strtolower ( $_GET [ " action " ]) . " has been registered. Perhaps you are missing a module?</p> " ));
2014-12-25 20:31:01 +00:00
}
?>