This repository has been archived on 2022-07-28. You can view files and clone it, but cannot push or open issues or pull requests.
md-cms/inc/functions.php
Joshua Ramon Enslin 768c0998aa Added whitelist for uploadable files.
Added greyscale mdlogo to git and set it as the default logo.
2018-06-18 21:42:14 +02:00

448 lines
13 KiB
PHP

<?PHP
/**
* Main file for functions.
*
* @file
*
* @author Joshua Ramon Enslin <joshua@jrenslin.de>
*/
require __DIR__ . "/standardHTML.php";
require __DIR__ . "/mdEmbeds.php";
/**
* Function ensureDir checks if a directory exists, and creates it if it does not yet.
*
* @param string $filepath File path.
*
* @return void
*/
function ensureDir(string $filepath) {
if (!is_dir($filepath)) mkdir($filepath);
}
/**
* Function ensureJson checks that a JSON file exists. If not, it creates an empty one at the specified location.
*
* @param string $filepath File path to the JSON file.
*
* @return void
*/
function ensureJson(string $filepath) {
if (!file_exists($filepath) or filesize($filepath) < 2) {
file_put_contents($filepath, "[]");
}
}
/**
* Function for ensuring the existence of an appropriate environment.
*
* @return void
*/
function ensureEnvironment() {
// Enable error reporting
error_reporting(E_ALL);
ini_set("display_errors", 1);
// Ensure existence of directories
foreach ([__DIR__ . "/../files", __DIR__ . "/../data", __DIR__ . "/../data/static", __DIR__ . "/../data/caches", __DIR__ . "/../js"] as $folder) {
ensureDir($folder);
}
// Ensure existence of settings files
foreach ([
__DIR__ . "/../data/settings.json",
__DIR__ . "/../data/caches/pages.json",
__DIR__ . "/../data/caches/publicPages.json",
__DIR__ . "/../data/users.json",
] as $jsonFile) {
ensureJson($jsonFile);
}
// Load settings
$settings = array_merge(
[
"startPage" => "1",
"pageTitle" => "md:cms",
"logo" => "/appFiles/mdlogo.png",
"url" => "",
"css" => "default",
"defaultLang" => "en",
"cacheRefreshInterval" => 0,
"mdVersion" => "https://rlp.museum-digital.de/",
"mdImgFolder" => "https://rlp.museum-digital.de/data/rlp/",
"hideInstitution" => 0,
"limitToInstitutions" => [],
"sendHTTPHeaders" => 1,
"CSPimageSources" => "",
"CSPobjectSources" => "",
"maxFileSize" => 300000,
],
json_decode(file_get_contents(__DIR__ . "/../data/settings.json"), true)
);
$GLOBALS['settings'] = $settings;
if ($settings['sendHTTPHeaders']) {
header('X-Content-Type-Options: nosniff');
header('X-XSS-Protection: 1; mode=block');
header('Strict-Transport-Security: max-age=31536000; preload');
header('Referrer-Policy: strict-origin');
}
}
/**
* Function for loading contents from cache.
*
* @return array
*/
function loadPages() {
$pages = json_decode(file_get_contents(__DIR__ . "/../data/caches/pages.json"), true);
return $pages;
}
/**
* Function for loading contents from cache.
*
* @return array
*/
function loadPublicPages() {
$pages = json_decode(file_get_contents(__DIR__ . "/../data/caches/publicPages.json"), true);
return $pages;
}
/**
* Query or cache pages.
*
* @param string $url URL to query.
* @param string $area The type of the queried page. If caching is enabled, renew cache every X seconds.
* @param array $settings Settings variable.
*
* @return array
*/
function queryCachePage(string $url, string $area = "", array $settings = ['cacheRefreshInterval' => 0]) {
// Ignore caching if cacheRefreshInterval equals zero.
if ($settings['cacheRefreshInterval'] == 0) {
return file_get_contents($url);
}
$fileDir = __DIR__ . "/../data/caches/$area";
ensureDir($fileDir);
$fileName = md5($url);
$filePath = "$fileDir/$fileName.json";
// Load from cache.
if (file_exists($filePath) && time() - filemtime($filePath) < $settings['cacheRefreshInterval']) {
return file_get_contents($filePath);
}
// Refresh cache.
$contents = file_get_contents($url);
file_put_contents($filePath, $contents, LOCK_EX);
return $contents;
}
/**
* Function scanDirConts is a wrapper around scandir(), which removes [".", ".."].
*
* @param string $folder Folder to scan.
*
* @return string[]
*/
function scanDirConts(string $folder):array {
return array_values(array_diff(scandir($folder), [".", "..", ".git"]));
}
/**
* Function printHiddenInputs takes an array, in which each entry stands for a new hidden input field.
* The key to the entry stands for the name attribute, the value for the value attribute.
*
* @param array $array Associative array containing all the variable names and corresponding values to print
* @param int $indent Integer describing how far each line in the returned string should be indented.
*
* @return string
*/
function printHiddenInputs(array $array, int $indent = 0):string {
$output = '';
$indentString = PHP_EOL;
for ($i = 0; $i < $indent; $i++) $indentString .= ' ';
foreach ($array as $name => $value) {
$output .= $indentString . '<input type="hidden" name="'.$name.'" value="'.$value.'" />';
}
return $output;
}
/**
* Function printHiddenInputsFromGlobalsSimple takes an array, in which each entry stands for a new hidden input field.
* The value stands for the name attribute of the input field and the key in $GLOBALS.
*
* @param array $array Input array.
* @param int $indent Number of spaces for indenting the output input fields in HTML. Optional.
*
* @return string
*/
function printHiddenInputsFromGlobalsSimple(array $array, int $indent = 0):string {
$output = '';
$indentString = PHP_EOL;
for ($i = 0; $i < $indent; $i++) $indentString .= ' ';
foreach ($array as $value) {
if (!isset($GLOBALS[$value])) continue;
$output .= $indentString . '<input type="hidden" name="'.$value.'" value="'.$GLOBALS[$value].'" />';
}
return $output;
}
/**
* Function write_get_vars prints checks for GET variables specified in the input array and returns them as a single string.
* Useful for avoiding long blocks of links working to write meaningful links.
*
* @param string[] $input Input array: both simple and associative arrays are accepted.
*
* @return string
*/
function write_get_vars(array $input):string {
// Check if keys have been specified in the array (in Python terms, if it is a dict or a list).
// If keys are not specified, write new working variable $vars with keys equaling the value.
// $str is the string that will eventually be returned.
$vars = array();
$str = '';
if (isset($input[0])) {
foreach ($input as $value) $vars[$value] = $value;
}
else $vars = $input;
// For each of the variables specified in $vars, check if a corresponding GET variable is set.
// If so, add that to the return string.
// The key is used in place of the original GET variable's name ($value),
// because some pages may have the same GET variables carry different names.
foreach ($vars as $key => $value) {
if (isset($GLOBALS['_GET'][$value])) $str .= '&'.$key.'='.$GLOBALS['_GET'][$value];
}
return ($str);
}
/**
* Function write_post_vars prints checks for POST variables specified in the input
* array and returns them as a single string.
* Useful for avoiding long blocks of links working to write meaningful links.
*
* @param string[] $input Input array: both simple and associative arrays are accepted.
*
* @return string
*/
function write_post_vars(array $input):string {
// Check if keys have been specified in the array (in Python terms, if it is a dict or a list).
// If keys are not specified, write new working variable $vars with keys equaling the value.
// $str is the string that will eventually be returned.
$vars = array();
$str = '';
if (isset($input[0])) {
foreach ($input as $value) $vars[$value] = $value;
}
else $vars = $input;
// For each of the variables specified in $vars, check if a corresponding GET variable is set.
// If so, add that to the return string. The key is used in place of the original POST variable's name ($value),
// because some pages may have the same GET variables carry different names.
foreach ($vars as $key => $value) {
if (isset($GLOBALS['_POST'][$value])) $str .= '&'.$key.'='.$GLOBALS['_POST'][$value];
}
return ($str);
}
/**
* Function write_common_vars prints checks for global variables specified in the input
* array and returns them as a single string.
* Useful for avoiding long blocks of links working to write meaningful links.
*
* @param string[] $input Input array: both simple and associative arrays are accepted.
*
* @return string
*/
function write_common_vars(array $input):string {
// Check if keys have been specified in the array (in Python terms, if it is a dict or a list).
// If keys are not specified, write new working variable $vars with keys equaling the value.
// $str is the string that will eventually be returned.
$vars = array();
$str = '';
if (isset($input[0])) {
foreach ($input as $value) $vars[$value] = $value;
}
else $vars = $input;
// For each of the variables specified in $vars, check if a corresponding GET variable is set.
// If so, add that to the return string. The key is used in place of the original GET variable's name ($value),
// because some pages may have the same GET variables carry different names.
foreach ($vars as $key => $value) {
if (isset($GLOBALS[$value])) $str .= '&'.$key.'='.$GLOBALS[$value];
}
return ($str);
}
/**
* Function for e.g. printing the navigation.
*
* @param array $pages Array of all pages to list.
* @param function $start Function to run on the called pages in case a new level is entered.
* @param function $end Function to run on the called pages in case a new level is entered.
* @param function $callbackSameLevel Function to run on the called pages of the current level.
* @param integer $higher Run the callback function on those entries where higher equals the given.
*
* @return string
*/
function buildPageOrder(
array $pages,
$start,
$end,
$callbackSameLevel,
int $higher = 0
):string {
$output = "";
$thisLevel = [];
foreach ($pages as $page) {
if ($page["higher"] != $higher) continue;
$output .= $callbackSameLevel($page, buildPageOrder($pages, $start, $end, $callbackSameLevel, $page["id"]));
}
if ($output) $output = $start() . $output . $end();
return $output;
}
/**
* Function for checking access to previews.
*
* @param bool $sessionStarted Optional parameter depending on the status of the session.
*
* @return bool
*/
function checkPreviewAccess($sessionStarted = false) {
if (!$sessionStarted) {
session_start();
}
if (isset($_SESSION['username'])) $output = true;
else $output = false;
if (!$sessionStarted) {
session_abort();
}
return $output;
}
/**
* Function checking if a string starts with another.
*
* @param string $haystack String to check.
* @param string $needle Potential start of $haystack.
*
* @return boolean
*/
function startswith(string $haystack, string $needle):bool {
if (substr($haystack, 0, strlen($needle)) == $needle) return (true);
else return (false);
}
/**
* Function checking if a string starts with any input from the input array.
*
* @param string $haystack String to check.
* @param string[] $needles Array containing potential start values of $haystack.
*
* @return boolean
*/
function startswithAny(string $haystack, array $needles):bool {
$output = false;
foreach ($needles as $needle) {
$output = startswith($haystack, $needle);
if ($output == true) return $output;
}
return $output;
}
/**
* Curling web pages.
* Function to check errors.
*
* @param string $url URL to query.
* @param string $host Authentication data. Optional.
*
* @return string
*/
function runCurl(string $url, string $host = ""):string {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
// curl_setopt($curl, CURLOPT_RESOLVE, ["www.example.com:443:172.16.1.1"]);
curl_setopt($curl, CURLOPT_ENCODING, '');
if ($host) curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: $host"));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
/**
* This function cuts down a string and adds a period in case it's longer than length to create a snippet.
*
* @param string $string Input text to cut down
* @param int $length Length of the snippet to create
*
* @return string
*/
function createTextSnippet($string, $length) {
if (strlen($string) > $length) {
$string = substr($string, 0, $length);
$string = substr($string, 0, strrpos($string, ' '));
$string .= ' ...';
}
return $string;
}
?>