mirror of
https://github.com/sbrl/Pepperminty-Wiki.git
synced 2024-12-22 13:45:02 +00:00
78 lines
3.5 KiB
PHP
78 lines
3.5 KiB
PHP
<?php
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
$parsers = [
|
|
"none" => [
|
|
"parser" => function() {
|
|
throw new Exception("No parser registered!");
|
|
},
|
|
"hash_generator" => function() {
|
|
throw new Exception("No parser registered!");
|
|
}
|
|
]
|
|
];
|
|
/**
|
|
* Registers a new parser.
|
|
* @package core
|
|
* @param string $name The name of the new parser to register.
|
|
* @param callable $parser_code The function to register as a new parser.
|
|
* @param callable $hash_generator A function that should take a single argument of the input source text, and return a unique hash for that content. The return value is used as the filename for cache entries, so should be safe to use as such.
|
|
*/
|
|
function add_parser($name, $parser_code, $hash_generator) {
|
|
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" => $parser_code,
|
|
"hash_generator" => $hash_generator
|
|
];
|
|
}
|
|
/**
|
|
* Parses the specified page source using the parser specified in the settings
|
|
* into HTML.
|
|
* The specified parser may (though it's unlikely) render it to other things.
|
|
* @package core
|
|
* @param string $source The source to render.
|
|
* @param bool $use_cache Whether to use the on-disk cache. Has no effect if parser caching is disabled in peppermint.json, or the source string is too small.
|
|
* @param bool $untrusted Whether the source string is 'untrusted' - i.e. a user comment. Untrusted source disallows HTML and protects against XSS attacks.
|
|
* @return string The source rendered to HTML.
|
|
*/
|
|
function parse_page_source($source, $untrusted = false, $use_cache = true) {
|
|
global $settings, $paths, $parsers, $version;
|
|
$start_time = microtime(true);
|
|
|
|
if(!$settings->parser_cache || strlen($source) < $settings->parser_cache_min_size) $use_cache = false;
|
|
|
|
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 " . hide_email($settings->admindetails_email, $settings->admindetails_name) . ", $settings->sitename's Administrator."));
|
|
|
|
/* Not needed atm because escaping happens when saving, not when rendering *
|
|
if($settings->clean_raw_html)
|
|
$source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
|
|
*/
|
|
|
|
$cache_id = $parsers[$settings->parser]["hash_generator"]($source);
|
|
$cache_file = "{$paths->cache_directory}/{$cache_id}.html";
|
|
|
|
$result = null;
|
|
if($use_cache && file_exists($cache_file)) {
|
|
$result = file_get_contents($cache_file);
|
|
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
|
}
|
|
if($result == null) {
|
|
$result = $parsers[$settings->parser]["parser"]($source, $untrusted);
|
|
// If we should use the cache and we failed to write to it, warn the admin.
|
|
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
|
|
if($use_cache && !file_put_contents($cache_file, $result))
|
|
error_log("[PeppermintyWiki/$settings->sitename/parser_engine] Warning: Failed to write to cache file $cache_file.");
|
|
|
|
$result .= "\n<!-- cache: " . ($use_cache ? "miss" : "n/a") . ", id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
|
}
|
|
|
|
return $result;
|
|
}
|