|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
<?php
|
|
|
|
|
/** The Pepperminty Wiki core */
|
|
|
|
|
$start_time = microtime(true);
|
|
|
|
|
mb_internal_encoding("UTF-8");
|
|
|
|
|
|
|
|
|
@ -7,36 +8,61 @@ mb_internal_encoding("UTF-8");
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// Do not edit below this line unless you know what you are doing! //////
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/** The version of Pepperminty Wiki currently running. */
|
|
|
|
|
$version = "{version}";
|
|
|
|
|
/// Environment ///
|
|
|
|
|
$env = new stdClass(); // The environment object
|
|
|
|
|
$env->action = $settings->defaultaction; // The action requested by the user
|
|
|
|
|
$env->page = ""; // The page name
|
|
|
|
|
$env->page_filename = ""; // The filename that the page is stored in
|
|
|
|
|
$env->is_history_revision = false; // Whether we are looking at a history revision
|
|
|
|
|
$env->history = new stdClass(); // History revision information
|
|
|
|
|
$env->history->revision_number = -1; // The revision number of the current page
|
|
|
|
|
$env->history->revision_data = false; // The revision data object from the page index
|
|
|
|
|
$env->user = $settings->anonymous_user_name; // The user's name
|
|
|
|
|
$env->is_logged_in = false; // Whether the user is logged in
|
|
|
|
|
$env->is_admin = false; // Whether the user is an admin (moderator)
|
|
|
|
|
$env->user_data = new stdClass(); // A logged in user's data
|
|
|
|
|
$env->storage_prefix = $settings->data_storage_dir . DIRECTORY_SEPARATOR; // The data storage directory
|
|
|
|
|
$env->perfdata = new stdClass(); // Performance data
|
|
|
|
|
/** Holds information about the current request environment. */
|
|
|
|
|
$env = new stdClass();
|
|
|
|
|
/** The action requested by the user. */
|
|
|
|
|
$env->action = $settings->defaultaction;
|
|
|
|
|
/** The page name requested by the remote client. */
|
|
|
|
|
$env->page = "";
|
|
|
|
|
/** The filename that the page is stored in. */
|
|
|
|
|
$env->page_filename = "";
|
|
|
|
|
/** Whether we are looking at a history revision. */
|
|
|
|
|
$env->is_history_revision = false;
|
|
|
|
|
/** An object holding history revision information for the current request */
|
|
|
|
|
$env->history = new stdClass();
|
|
|
|
|
/** The revision number requested of the current page */
|
|
|
|
|
$env->history->revision_number = -1;
|
|
|
|
|
/** The revision data object from the page index for the requested revision */
|
|
|
|
|
$env->history->revision_data = false;
|
|
|
|
|
/** The user's name if they are logged in. Defaults to `$settings->anonymous_user_name` if the user isn't currently logged in. @var string */
|
|
|
|
|
$env->user = $settings->anonymous_user_name;
|
|
|
|
|
/** Whether the user is logged in */
|
|
|
|
|
$env->is_logged_in = false;
|
|
|
|
|
/** Whether the user is an admin (moderator) @todo Refactor this to is_moderator, so that is_admin can be for the server owner. */
|
|
|
|
|
$env->is_admin = false;
|
|
|
|
|
/** The currently logged in user's data. Please see $settings->users->username if you need to edit this - this is here for convenience :-) */
|
|
|
|
|
$env->user_data = new stdClass();
|
|
|
|
|
/** The data storage directory. Page filenames should be prefixed with this if you want their content. */
|
|
|
|
|
$env->storage_prefix = $settings->data_storage_dir . DIRECTORY_SEPARATOR;
|
|
|
|
|
/** Contains performance data statistics for the current request. */
|
|
|
|
|
$env->perfdata = new stdClass();
|
|
|
|
|
/// Paths ///
|
|
|
|
|
/**
|
|
|
|
|
* Contains a bunch of useful paths to various important files.
|
|
|
|
|
* None of these need to be prefixed with `$env->storage_prefix`.
|
|
|
|
|
*/
|
|
|
|
|
$paths = new stdClass();
|
|
|
|
|
$paths->pageindex = "pageindex.json"; // The pageindex
|
|
|
|
|
$paths->searchindex = "invindex.json"; // The inverted index used for searching
|
|
|
|
|
$paths->idindex = "idindex.json"; // The index that converts ids to page names
|
|
|
|
|
$paths->statsindex = "statsindex.json"; // The calculated statistics cache
|
|
|
|
|
/** The pageindex. Contains extensive information about all pages currently in this wiki. Individual entries for pages may be extended with arbitrary properties. */
|
|
|
|
|
$paths->pageindex = "pageindex.json";
|
|
|
|
|
/** The inverted index used for searching. Use the `search` class to interact with this - otherwise your brain might explode :P */
|
|
|
|
|
$paths->searchindex = "invindex.json";
|
|
|
|
|
/** The index that maps ids to page names. Use the `ids` class to interact with it :-) */
|
|
|
|
|
$paths->idindex = "idindex.json";
|
|
|
|
|
/** The cache of the most recently calculated statistics. */
|
|
|
|
|
$paths->statsindex = "statsindex.json";
|
|
|
|
|
|
|
|
|
|
// Prepend the storage data directory to all the defined paths.
|
|
|
|
|
foreach ($paths as &$path) {
|
|
|
|
|
$path = $env->storage_prefix . $path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$paths->settings_file = $settingsFilename; // The master settings file
|
|
|
|
|
$paths->upload_file_prefix = "Files/"; // The prefix to add to uploaded files
|
|
|
|
|
/** The master settings file @var string */
|
|
|
|
|
$paths->settings_file = $settingsFilename;
|
|
|
|
|
/** The prefix to add to uploaded files */
|
|
|
|
|
$paths->upload_file_prefix = "Files/";
|
|
|
|
|
|
|
|
|
|
session_start();
|
|
|
|
|
// Make sure that the login cookie lasts beyond the end of the user's session
|
|
|
|
@ -126,6 +152,7 @@ if($env->is_logged_in)
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/**
|
|
|
|
|
* Get the actual absolute origin of the request sent by the user.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param array $s The $_SERVER variable contents. Defaults to $_SERVER.
|
|
|
|
|
* @param bool $use_forwarded_host Whether to utilise the X-Forwarded-Host header when calculating the actual origin.
|
|
|
|
|
* @return string The actual origin of the user's request.
|
|
|
|
@ -145,6 +172,7 @@ function url_origin( $s = false, $use_forwarded_host = false )
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the full url, as requested by the client.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://stackoverflow.com/a/8891890/1460422 This Stackoverflow answer.
|
|
|
|
|
* @param array $s The $_SERVER variable. Defaults to $_SERVER.
|
|
|
|
|
* @param bool $use_forwarded_host Whether to take the X-Forwarded-Host header into account.
|
|
|
|
@ -157,8 +185,10 @@ function full_url( $s = false, $use_forwarded_host = false )
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a filesize into a human-readable string.
|
|
|
|
|
* From http://php.net/manual/en/function.filesize.php#106569
|
|
|
|
|
* Edited by Starbeamrainbowlabs.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://php.net/manual/en/function.filesize.php#106569 The original source
|
|
|
|
|
* @author rommel
|
|
|
|
|
* @author Edited by Starbeamrainbowlabs
|
|
|
|
|
* @param number $bytes The number of bytes to convert.
|
|
|
|
|
* @param number $decimals The number of decimal places to preserve.
|
|
|
|
|
* @return string A human-readable filesize.
|
|
|
|
@ -174,7 +204,8 @@ function human_filesize($bytes, $decimals = 2)
|
|
|
|
|
/**
|
|
|
|
|
* Calculates the time since a particular timestamp and returns a
|
|
|
|
|
* human-readable result.
|
|
|
|
|
* From http://goo.gl/zpgLgq.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://goo.gl/zpgLgq The original source. No longer exists, maybe the wayback machine caught it :-(
|
|
|
|
|
* @param integer $time The timestamp to convert.
|
|
|
|
|
* @return string The time since the given timestamp as
|
|
|
|
|
* a human-readable string.
|
|
|
|
@ -185,6 +216,7 @@ function human_time_since($time)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a given number of seconds as something that humans can understand more easily.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param int $seconds The number of seconds to render.
|
|
|
|
|
* @return string The rendered time.
|
|
|
|
|
*/
|
|
|
|
@ -208,7 +240,9 @@ function human_time($seconds)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A recursive glob() function.
|
|
|
|
|
* From http://in.php.net/manual/en/function.glob.php#106595
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://in.php.net/manual/en/function.glob.php#106595 The original source
|
|
|
|
|
* @author Mike
|
|
|
|
|
* @param string $pattern The glob pattern to use to find filenames.
|
|
|
|
|
* @param integer $flags The glob flags to use when finding filenames.
|
|
|
|
|
* @return array An array of the filepaths that match the given glob.
|
|
|
|
@ -229,6 +263,7 @@ function glob_recursive($pattern, $flags = 0)
|
|
|
|
|
/**
|
|
|
|
|
* Gets the name of the parent page to the specified page.
|
|
|
|
|
* @since 0.15
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $pagename The child page to get the parent
|
|
|
|
|
* page name for.
|
|
|
|
|
* @return string|bool
|
|
|
|
@ -241,6 +276,7 @@ function get_page_parent($pagename) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets a list of all the sub pages of the current page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param object $pageindex The pageindex to use to search.
|
|
|
|
|
* @param string $pagename The name of the page to list the sub pages of.
|
|
|
|
|
* @return object An object containing all the subpages and their
|
|
|
|
@ -275,6 +311,7 @@ function get_subpages($pageindex, $pagename)
|
|
|
|
|
/**
|
|
|
|
|
* Makes sure that a subpage's parents exist.
|
|
|
|
|
* Note this doesn't check the pagename itself.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param $pagename The pagename to check.
|
|
|
|
|
*/
|
|
|
|
|
function check_subpage_parents($pagename)
|
|
|
|
@ -309,6 +346,7 @@ function check_subpage_parents($pagename)
|
|
|
|
|
* Makes a path safe.
|
|
|
|
|
* Paths may only contain alphanumeric characters, spaces, underscores, and
|
|
|
|
|
* dashes.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $string The string to make safe.
|
|
|
|
|
* @return string A safe version of the given string.
|
|
|
|
|
*/
|
|
|
|
@ -327,6 +365,8 @@ function makepathsafe($string)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Hides an email address from bots by adding random html entities.
|
|
|
|
|
* @todo Make this moree clevererer :D
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $str The original email address
|
|
|
|
|
* @return string The mangled email address.
|
|
|
|
|
*/
|
|
|
|
@ -350,6 +390,7 @@ function hide_email($str)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Checks to see if $haystack starts with $needle.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $haystack The string to search.
|
|
|
|
|
* @param string $needle The string to search for at the beginning
|
|
|
|
|
* of $haystack.
|
|
|
|
@ -365,11 +406,12 @@ function starts_with($haystack, $needle)
|
|
|
|
|
/**
|
|
|
|
|
* Case-insensitively finds all occurrences of $needle in $haystack. Handles
|
|
|
|
|
* UTF-8 characters correctly.
|
|
|
|
|
* From http://www.pontikis.net/tip/?id=16, and
|
|
|
|
|
* based on http://www.php.net/manual/en/function.strpos.php#87061
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://www.pontikis.net/tip/?id=16 the source
|
|
|
|
|
* @see http://www.php.net/manual/en/function.strpos.php#87061 the source that the above was based on
|
|
|
|
|
* @param string $haystack The string to search.
|
|
|
|
|
* @param string $needle The string to find.
|
|
|
|
|
* @return array || false An array of match indices, or false if
|
|
|
|
|
* @return array|false An array of match indices, or false if
|
|
|
|
|
* nothing was found.
|
|
|
|
|
*/
|
|
|
|
|
function mb_stripos_all($haystack, $needle) {
|
|
|
|
@ -389,6 +431,7 @@ function mb_stripos_all($haystack, $needle) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tests whether a string starts with a specified substring.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $haystack The string to check against.
|
|
|
|
|
* @param string $needle The substring to look for.
|
|
|
|
|
* @return bool Whether the string starts with the specified substring.
|
|
|
|
@ -398,6 +441,7 @@ function startsWith($haystack, $needle) {
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Tests whether a string ends with a given substring.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $whole The string to test against.
|
|
|
|
|
* @param string $end The substring test for.
|
|
|
|
|
* @return bool Whether $whole ends in $end.
|
|
|
|
@ -408,6 +452,7 @@ function endsWith($whole, $end)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Replaces the first occurrence of $find with $replace.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $find The string to search for.
|
|
|
|
|
* @param string $replace The string to replace the search string with.
|
|
|
|
|
* @param string $subject The string ot perform the search and replace on.
|
|
|
|
@ -424,8 +469,10 @@ function str_replace_once($find, $replace, $subject)
|
|
|
|
|
/**
|
|
|
|
|
* Returns the system's mime type mappings, considering the first extension
|
|
|
|
|
* listed to be cacnonical.
|
|
|
|
|
* From http://stackoverflow.com/a/1147952/1460422 by chaos.
|
|
|
|
|
* Edited by Starbeamrainbowlabs.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://stackoverflow.com/a/1147952/1460422 From this stackoverflow answer
|
|
|
|
|
* @author chaos
|
|
|
|
|
* @author Edited by Starbeamrainbowlabs
|
|
|
|
|
* @return array An array of mime type mappings.
|
|
|
|
|
*/
|
|
|
|
|
function system_mime_type_extensions()
|
|
|
|
@ -450,8 +497,10 @@ function system_mime_type_extensions()
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a given mime type to it's associated file extension.
|
|
|
|
|
* From http://stackoverflow.com/a/1147952/1460422 by chaos.
|
|
|
|
|
* Edited by Starbeamrainbowlabs.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://stackoverflow.com/a/1147952/1460422 From this stackoverflow answer
|
|
|
|
|
* @author chaos
|
|
|
|
|
* @author Edited by Starbeamrainbowlabs
|
|
|
|
|
* @param string $type The mime type to convert.
|
|
|
|
|
* @return string The extension for the given mime type.
|
|
|
|
|
*/
|
|
|
|
@ -465,8 +514,10 @@ function system_mime_type_extension($type)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the system MIME type mapping of extensions to MIME types.
|
|
|
|
|
* From http://stackoverflow.com/a/1147952/1460422 by chaos.
|
|
|
|
|
* Edited by Starbeamrainbowlabs.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://stackoverflow.com/a/1147952/1460422 From this stackoverflow answer
|
|
|
|
|
* @author chaos
|
|
|
|
|
* @author Edited by Starbeamrainbowlabs
|
|
|
|
|
* @return array An array mapping file extensions to their associated mime types.
|
|
|
|
|
*/
|
|
|
|
|
function system_extension_mime_types()
|
|
|
|
@ -490,8 +541,10 @@ function system_extension_mime_types()
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Converts a given file extension to it's associated mime type.
|
|
|
|
|
* From http://stackoverflow.com/a/1147952/1460422 by chaos.
|
|
|
|
|
* Edited by Starbeamrainbowlabs.
|
|
|
|
|
* @package core
|
|
|
|
|
* @see http://stackoverflow.com/a/1147952/1460422 From this stackoverflow answer
|
|
|
|
|
* @author chaos
|
|
|
|
|
* @author Edited by Starbeamrainbowlabs
|
|
|
|
|
* @param string $ext The extension to convert.
|
|
|
|
|
* @return string The mime type associated with the given extension.
|
|
|
|
|
*/
|
|
|
|
@ -505,6 +558,7 @@ function system_extension_mime_type($ext) {
|
|
|
|
|
/**
|
|
|
|
|
* Figures out whether a given http accepts header contains a
|
|
|
|
|
* specified mime type.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $accept_header The accept header to search.
|
|
|
|
|
* @param string $mime_type The mime type to search for.
|
|
|
|
|
* @return bool Whether the specified mime type was found
|
|
|
|
@ -522,6 +576,7 @@ function accept_contains_mime($accept_header, $mime_type)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generates a stack trace.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param bool $log_trace Whether to send the stack trace to the error log.
|
|
|
|
|
* @param bool $full Whether to output a full description of all the variables involved.
|
|
|
|
|
* @return string A string prepresentation of a stack trace.
|
|
|
|
@ -552,6 +607,7 @@ function stack_trace($log_trace = true, $full = false)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Calls var_dump() and returns the output.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param mixed $var The thing to pass to var_dump().
|
|
|
|
|
* @return string The output captured from var_dump().
|
|
|
|
|
*/
|
|
|
|
@ -564,6 +620,7 @@ function var_dump_ret($var)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calls var_dump(), shortening the output for various types.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param mixed $var The thing to pass to var_dump().
|
|
|
|
|
* @return string A shortened version of the var_dump() output.
|
|
|
|
|
*/
|
|
|
|
@ -577,10 +634,13 @@ function var_dump_short($var)
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Polyfill getallheaders()
|
|
|
|
|
*/
|
|
|
|
|
if (!function_exists('getallheaders')) {
|
|
|
|
|
/**
|
|
|
|
|
* Polyfill for PHP's native getallheaders() function on platforms that
|
|
|
|
|
* don't have it.
|
|
|
|
|
* @package core
|
|
|
|
|
* @todo Identify which platforms don't have it and whether we still need this
|
|
|
|
|
*/
|
|
|
|
|
function getallheaders()
|
|
|
|
|
{
|
|
|
|
|
if (!is_array($_SERVER))
|
|
|
|
@ -597,6 +657,7 @@ if (!function_exists('getallheaders')) {
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a timestamp in HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param int $timestamp The timestamp to render.
|
|
|
|
|
* @return string HTML representing the given timestamp.
|
|
|
|
|
*/
|
|
|
|
@ -606,6 +667,7 @@ function render_timestamp($timestamp)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a page name in HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param object $rchange The recent change to render as a page name
|
|
|
|
|
* @return string HTML representing the name of the given page.
|
|
|
|
|
*/
|
|
|
|
@ -620,6 +682,7 @@ function render_pagename($rchange)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders an editor's or a group of editors name(s) in HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $editorName The name of the editor to render.
|
|
|
|
|
* @return string HTML representing the given editor's name.
|
|
|
|
|
*/
|
|
|
|
@ -630,6 +693,7 @@ function render_editor($editorName)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Saves the currently logged in uesr's data back to peppermint.json.
|
|
|
|
|
* @package core
|
|
|
|
|
* @return bool Whether the user's data was saved successfully. Returns false if the user isn't logged in.
|
|
|
|
|
*/
|
|
|
|
|
function save_userdata()
|
|
|
|
@ -648,6 +712,7 @@ function save_userdata()
|
|
|
|
|
/**
|
|
|
|
|
* Figures out the path to the user page for a given username.
|
|
|
|
|
* Does not check to make sure the user acutally exists.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $username The username to get the path to their user page for.
|
|
|
|
|
* @return string The path to the given user's page.
|
|
|
|
|
*/
|
|
|
|
@ -657,6 +722,7 @@ function get_user_pagename($username) {
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Extracts a username from a user page path.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $userPagename The suer page path to extract from.
|
|
|
|
|
* @return string The name of the user that the user page belongs to.
|
|
|
|
|
*/
|
|
|
|
@ -670,6 +736,7 @@ function extract_user_from_userpage($userPagename) {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sends a plain text email to a user, replacing {username} with the specified username.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $username The username to send the email to.
|
|
|
|
|
* @param string $subject The subject of the email.
|
|
|
|
|
* @param string $body The body of the email.
|
|
|
|
@ -700,6 +767,7 @@ function email_user($username, $subject, $body)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Sends a plain text email to a list of users, replacing {username} with each user's name.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string[] $usernames A list of usernames to email.
|
|
|
|
|
* @param string $subject The subject of the email.
|
|
|
|
|
* @param string $body The body of the email.
|
|
|
|
@ -822,11 +890,16 @@ $idindex = json_decode(file_get_contents($paths->idindex));
|
|
|
|
|
$env->perfdata->idindex_decode_time = round((microtime(true) - $idindex_decode_start)*1000, 3);
|
|
|
|
|
/**
|
|
|
|
|
* Provides an interface to interact with page ids.
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
class ids
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* @summary Gets the page id associated with the given pagename.
|
|
|
|
|
/**
|
|
|
|
|
* Gets the page id associated with the given page name.
|
|
|
|
|
* If it doesn't exist in the id index, it will be added.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $pagename The name of the page to fetch the id for.
|
|
|
|
|
* @return integer The id for the specified page name.
|
|
|
|
|
*/
|
|
|
|
|
public static function getid($pagename)
|
|
|
|
|
{
|
|
|
|
@ -842,8 +915,13 @@ class ids
|
|
|
|
|
return self::assign($pagename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @summary Gets the page name associated with the given page id.
|
|
|
|
|
/**
|
|
|
|
|
* Gets the page name associated with the given page id.
|
|
|
|
|
* Be warned that if the id index is cleared (e.g. when the search index is
|
|
|
|
|
* rebuilt from scratch), the id associated with a page name may change!
|
|
|
|
|
* @package core
|
|
|
|
|
* @param int $id The id to fetch the page name for.
|
|
|
|
|
* @return string The page name currently associated with the specified id.
|
|
|
|
|
*/
|
|
|
|
|
public static function getpagename($id)
|
|
|
|
|
{
|
|
|
|
@ -855,10 +933,13 @@ class ids
|
|
|
|
|
return $idindex->$id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @summary Moves a page in the id index from $oldpagename to $newpagename.
|
|
|
|
|
* Note that this function doesn't perform any special checks to
|
|
|
|
|
* make sure that the destination name doesn't already exist.
|
|
|
|
|
/**
|
|
|
|
|
* Moves a page in the id index from $oldpagename to $newpagename.
|
|
|
|
|
* Note that this function doesn't perform any special checks to make sure
|
|
|
|
|
* that the destination name doesn't already exist.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $oldpagename The old page name to move.
|
|
|
|
|
* @param string $newpagename The new pagee name to move the old page name to.
|
|
|
|
|
*/
|
|
|
|
|
public static function movepagename($oldpagename, $newpagename)
|
|
|
|
|
{
|
|
|
|
@ -870,9 +951,13 @@ class ids
|
|
|
|
|
file_put_contents($paths->idindex, json_encode($idindex));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @summary Removes the given page name from the id index. Note that this
|
|
|
|
|
* function doesn't handle multiple entries with the same name.
|
|
|
|
|
/**
|
|
|
|
|
* Removes the given page name from the id index.
|
|
|
|
|
* Note that this function doesn't handle multiple entries with the same
|
|
|
|
|
* name. Also note that it may get re-added during a search reindex if the
|
|
|
|
|
* page still exists.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $pagename The page name to delete from the id index.
|
|
|
|
|
*/
|
|
|
|
|
public static function deletepagename($pagename)
|
|
|
|
|
{
|
|
|
|
@ -887,7 +972,12 @@ class ids
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clears the id index completely. Will break the inverted search index!
|
|
|
|
|
* Clears the id index completely.
|
|
|
|
|
* Will break the inverted search index! Make sure you rebuild the search
|
|
|
|
|
* index (if the search module is installed, of course) if you want search
|
|
|
|
|
* to still work. Of course, note that will re-add all the pages to the id
|
|
|
|
|
* index.
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
public static function clear()
|
|
|
|
|
{
|
|
|
|
@ -900,9 +990,12 @@ class ids
|
|
|
|
|
$idindex = new stdClass();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @summary Assigns an id to a pagename. Doesn't check to make sure that
|
|
|
|
|
* pagename doesn't exist in the pageindex.
|
|
|
|
|
/**
|
|
|
|
|
* Assigns an id to a pagename. Doesn't check to make sure that
|
|
|
|
|
* pagename doesn't already exist in the id index.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $pagename The page name to assign an id to.
|
|
|
|
|
* @return integer The id assigned to the specified page name.
|
|
|
|
|
*/
|
|
|
|
|
protected static function assign($pagename)
|
|
|
|
|
{
|
|
|
|
@ -958,8 +1051,17 @@ if(makepathsafe($_GET["page"]) !== $_GET["page"])
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//////////////////////////////// HTML fragments ////////////////////////////////
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/**
|
|
|
|
|
* Renders the HTML page that is sent to the client.
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
class page_renderer
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The root HTML template that all pages are built from.
|
|
|
|
|
* @var string
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
public static $html_template = "<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
@ -976,7 +1078,11 @@ class page_renderer
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The main content template that is used to render normal wiki pages.
|
|
|
|
|
* @var string
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
public static $main_content_template = "{navigation-bar}
|
|
|
|
|
<h1 class='sitename'>{sitename}</h1>
|
|
|
|
|
<main>
|
|
|
|
@ -991,6 +1097,12 @@ class page_renderer
|
|
|
|
|
</footer>
|
|
|
|
|
{navigation-bar-bottom}
|
|
|
|
|
{all-pages-datalist}";
|
|
|
|
|
/**
|
|
|
|
|
* A specially minified content template that doesn't include the navbar and
|
|
|
|
|
* other elements not suiltable for printing.
|
|
|
|
|
* @var string
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
public static $minimal_content_template = "<main class='printable'>{content}</main>
|
|
|
|
|
<footer class='printable'>
|
|
|
|
|
<hr class='footerdivider' />
|
|
|
|
@ -1000,12 +1112,20 @@ class page_renderer
|
|
|
|
|
<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.
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
* @var array
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
protected static $part_processors = [];
|
|
|
|
|
|
|
|
|
|
// Registers a function as a part post processor.
|
|
|
|
|
/**
|
|
|
|
|
* Registers a function as a part post processor.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param function $function The part preprocessor to register.
|
|
|
|
|
*/
|
|
|
|
|
public static function register_part_preprocessor($function)
|
|
|
|
|
{
|
|
|
|
|
global $settings;
|
|
|
|
@ -1023,7 +1143,15 @@ class page_renderer
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders a HTML page with the content specified.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $title The title of the page.
|
|
|
|
|
* @param string $content The (HTML) content of the page.
|
|
|
|
|
* @param boolean $body_template The HTML content template to use.
|
|
|
|
|
* @return string The rendered HTML, ready to send to the client :-)
|
|
|
|
|
*/
|
|
|
|
|
public static function render($title, $content, $body_template = false)
|
|
|
|
|
{
|
|
|
|
|
global $settings, $start_time, $version;
|
|
|
|
@ -1090,15 +1218,34 @@ class page_renderer
|
|
|
|
|
$result = str_replace("{generation-time-taken}", round((microtime(true) - $start_time)*1000, 2), $result);
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a normal HTML page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $title The title of the page.
|
|
|
|
|
* @param string $content The content of the page.
|
|
|
|
|
* @return string The rendered page.
|
|
|
|
|
*/
|
|
|
|
|
public static function render_main($title, $content)
|
|
|
|
|
{
|
|
|
|
|
return self::render($title, $content, self::$main_content_template);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a minimal HTML page. Useful for printable pages.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $title The title of the page.
|
|
|
|
|
* @param string $content The content of the page.
|
|
|
|
|
* @return string The rendered page.
|
|
|
|
|
*/
|
|
|
|
|
public static function render_minimal($title, $content)
|
|
|
|
|
{
|
|
|
|
|
return self::render($title, $content, self::$minimal_content_template);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders the header HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @return string The rendered HTML that goes in the header.
|
|
|
|
|
*/
|
|
|
|
|
public static function get_header_html()
|
|
|
|
|
{
|
|
|
|
|
global $settings;
|
|
|
|
@ -1125,6 +1272,11 @@ class page_renderer
|
|
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders all the CSS as HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @return string The css as HTML, ready to be included in the HTML header.
|
|
|
|
|
*/
|
|
|
|
|
public static function get_css_as_html()
|
|
|
|
|
{
|
|
|
|
|
global $settings;
|
|
|
|
@ -1161,18 +1313,43 @@ class page_renderer
|
|
|
|
|
return "<style>$css</style>\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The javascript snippets that will be included in the page.
|
|
|
|
|
* @var string[]
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
private static $jsSnippets = [];
|
|
|
|
|
/**
|
|
|
|
|
* The urls of the external javascript files that should be referenced
|
|
|
|
|
* by the page.
|
|
|
|
|
* @var string[]
|
|
|
|
|
* @package core
|
|
|
|
|
*/
|
|
|
|
|
private static $jsLinks = [];
|
|
|
|
|
/**
|
|
|
|
|
* Adds the specified url to a javascript file as a reference to the page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $scriptUrl The url of the javascript file to reference.
|
|
|
|
|
*/
|
|
|
|
|
public function AddJSLink(string $scriptUrl)
|
|
|
|
|
{
|
|
|
|
|
static::$jsLinks[] = $scriptUrl;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Adds a javascript snippet to the page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $script The snippet of javascript to add.
|
|
|
|
|
*/
|
|
|
|
|
public function AddJSSnippet(string $script)
|
|
|
|
|
{
|
|
|
|
|
static::$jsSnippets[] = $script;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders the included javascript header for inclusion in the final
|
|
|
|
|
* rendered page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @return string The rendered javascript ready for inclusion in the page.
|
|
|
|
|
*/
|
|
|
|
|
private static function getJS()
|
|
|
|
|
{
|
|
|
|
|
$result = "<!-- Javascript -->\n";
|
|
|
|
@ -1184,15 +1361,23 @@ class page_renderer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ~
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The navigation bar divider.
|
|
|
|
|
* @package core
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
public static $nav_divider = "<span class='nav-divider inflexible'> | </span>";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders a navigation bar from an array of links. See
|
|
|
|
|
* $settings->nav_links for format information.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param array $nav_links The links to add to the navigation bar.
|
|
|
|
|
* @param array $nav_links_extra The extra nav links to add to
|
|
|
|
|
* the "More..." menu.
|
|
|
|
|
* @param string $class The class(es) to assign to the rendered
|
|
|
|
|
* navigation bar.
|
|
|
|
|
*/
|
|
|
|
|
public static function render_navigation_bar($nav_links, $nav_links_extra, $class = "")
|
|
|
|
|
{
|
|
|
|
@ -1256,6 +1441,12 @@ class page_renderer
|
|
|
|
|
$result .= "</nav>";
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Renders a username for inclusion in a page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $name The username to render.
|
|
|
|
|
* @return string The username rendered in HTML.
|
|
|
|
|
*/
|
|
|
|
|
public static function render_username($name)
|
|
|
|
|
{
|
|
|
|
|
global $settings;
|
|
|
|
@ -1272,7 +1463,12 @@ class page_renderer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ~
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Renders the datalist for the search box as HTML.
|
|
|
|
|
* @package core
|
|
|
|
|
* @return string The search box datalist as HTML.
|
|
|
|
|
*/
|
|
|
|
|
public static function generate_all_pages_datalist()
|
|
|
|
|
{
|
|
|
|
|
global $settings, $pageindex;
|
|
|
|
@ -1304,7 +1500,7 @@ if(!empty($settings->enable_math_rendering))
|
|
|
|
|
{
|
|
|
|
|
page_renderer::AddJSLink("https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML");
|
|
|
|
|
}
|
|
|
|
|
// alt+enter suport in the search box
|
|
|
|
|
// alt+enter support in the search box
|
|
|
|
|
page_renderer::AddJSSnippet('// Alt + Enter support in the top search box
|
|
|
|
|
window.addEventListener("load", function(event) {
|
|
|
|
|
document.querySelector("input[type=search]").addEventListener("keyup", function(event) {
|
|
|
|
@ -1388,8 +1584,13 @@ if($settings->require_login_view === true && // If this site requires a login in
|
|
|
|
|
// register themselves //
|
|
|
|
|
// or new pages. //
|
|
|
|
|
//////////////////////////
|
|
|
|
|
$modules = []; // List that contains all the loaded modules
|
|
|
|
|
// Function to register a module
|
|
|
|
|
/** A list of all the currentlyloaded modules. Not guaranteed to be populated until an action is executed. */
|
|
|
|
|
$modules = [];
|
|
|
|
|
/**
|
|
|
|
|
* Registers a module.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param array $moduledata The module data to register.
|
|
|
|
|
*/
|
|
|
|
|
function register_module($moduledata)
|
|
|
|
|
{
|
|
|
|
|
global $modules;
|
|
|
|
@ -1399,6 +1600,7 @@ function register_module($moduledata)
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Checks to see whether a module with the given id exists.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $id The id to search for.
|
|
|
|
|
* @return bool Whether a module is currently loaded with the given id.
|
|
|
|
|
*/
|
|
|
|
@ -1413,8 +1615,14 @@ function module_exists($id)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function to register an action handler
|
|
|
|
|
$actions = new stdClass();
|
|
|
|
|
/**
|
|
|
|
|
* Registers a new action handler.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $action_name The action to register.
|
|
|
|
|
* @param function $func The function to call when the specified
|
|
|
|
|
* action is requested.
|
|
|
|
|
*/
|
|
|
|
|
function add_action($action_name, $func)
|
|
|
|
|
{
|
|
|
|
|
global $actions;
|
|
|
|
@ -1423,6 +1631,7 @@ function add_action($action_name, $func)
|
|
|
|
|
/**
|
|
|
|
|
* Figures out whether a given action is currently registered.
|
|
|
|
|
* Only guaranteed to be accurate in inside an existing action function
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $action_name The name of the action to search for
|
|
|
|
|
* @return boolean Whether an action with the specified name exists.
|
|
|
|
|
*/
|
|
|
|
@ -1439,6 +1648,7 @@ $parsers = [
|
|
|
|
|
];
|
|
|
|
|
/**
|
|
|
|
|
* Registers a new parser.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $name The name of the new parser to register.
|
|
|
|
|
* @param function $parser_code The function to register as a new parser.
|
|
|
|
|
*/
|
|
|
|
@ -1450,6 +1660,14 @@ function add_parser($name, $parser_code)
|
|
|
|
|
|
|
|
|
|
$parsers[$name] = $parser_code;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Parses the specified page source using the parser specified in the settings
|
|
|
|
|
* into HTML.
|
|
|
|
|
* The specified parser may (though it's unilkely) render it to other things.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $source The source to render.
|
|
|
|
|
* @return string The source rendered to HTML.
|
|
|
|
|
*/
|
|
|
|
|
function parse_page_source($source)
|
|
|
|
|
{
|
|
|
|
|
global $settings, $parsers;
|
|
|
|
@ -1468,6 +1686,7 @@ $save_preprocessors = [];
|
|
|
|
|
/**
|
|
|
|
|
* Register a new proprocessor that will be executed just before
|
|
|
|
|
* an edit is saved.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param function $func The function to register.
|
|
|
|
|
*/
|
|
|
|
|
function register_save_preprocessor($func)
|
|
|
|
@ -1479,6 +1698,7 @@ function register_save_preprocessor($func)
|
|
|
|
|
$help_sections = [];
|
|
|
|
|
/**
|
|
|
|
|
* Adds a new help section to the help page.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $index The string to index the new section under.
|
|
|
|
|
* @param string $title The title to display above the section.
|
|
|
|
|
* @param string $content The content to display.
|
|
|
|
@ -1497,9 +1717,11 @@ if(!empty($settings->enable_math_rendering))
|
|
|
|
|
add_help_section("22-mathematical-mxpressions", "Mathematical Expressions", "<p>$settings->sitename supports rendering of mathematical expressions. Mathematical expressions can be included practically anywhere in your page. Expressions should be written in LaTeX and enclosed in dollar signs like this: <code>$x^2$</code>.</p>
|
|
|
|
|
<p>Note that expression parsing is done on the viewer's computer with javascript (specifically MathJax) and not by $settings->sitename directly (also called client side rendering).</p>");
|
|
|
|
|
|
|
|
|
|
/** An array of the currently registerd statistic calculators. Not guaranteed to be populated until the requested action function is called. */
|
|
|
|
|
$statistic_calculators = [];
|
|
|
|
|
/**
|
|
|
|
|
* Registers a statistic calculator against the system.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param array $stat_data The statistic object to register.
|
|
|
|
|
*/
|
|
|
|
|
function statistic_add($stat_data) {
|
|
|
|
@ -1508,6 +1730,7 @@ function statistic_add($stat_data) {
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Checks whether a specified statistic has been registered.
|
|
|
|
|
* @package core
|
|
|
|
|
* @param string $stat_id The id of the statistic to check the existence of.
|
|
|
|
|
* @return boolean Whether the specified statistic has been registered.
|
|
|
|
|
*/
|
|
|
|
|