assets
functions
functions.php
img
inc
mdAvailableLicenses
scripts
tests
values
.git.template
.gitignore
.gitmodules
.htaccess
composer.json
csv.php
favicon.ico
index.php
index3.php
index6.php
upload.php
zipit.php
290 lines
8.1 KiB
PHP
290 lines
8.1 KiB
PHP
<?PHP
|
|
/**
|
|
* Generic collection of functions used in CSVXML.
|
|
*
|
|
* @file
|
|
*
|
|
* @author
|
|
*/
|
|
declare(strict_types = 1);
|
|
|
|
/**
|
|
* Function lang_getfrombrowser gets the browser language based on HTTP headers.
|
|
*
|
|
* @param array $allowed_languages Array containing all the languages for which
|
|
* there are translations.
|
|
* @param string $default_language Default language of the instance of MD.
|
|
* @param string $lang_variable Currently set language variable. Optional.
|
|
* @param boolean $strict_mode Whether to demand "de-de" (true) or "de" (false) Optional.
|
|
*
|
|
* @return string
|
|
*/
|
|
function lang_getfrombrowser(array $allowed_languages, string $default_language, string $lang_variable = "", bool $strict_mode = true):string {
|
|
|
|
// $_SERVER['HTTP_ACCEPT_LANGUAGE'] verwenden, wenn keine Sprachvariable mitgegeben wurde
|
|
if ($lang_variable === "") {
|
|
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) $lang_variable = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
|
}
|
|
|
|
// wurde irgendwelche Information mitgeschickt?
|
|
if (empty($lang_variable)) {
|
|
// Nein? => Standardsprache zurückgeben
|
|
return $default_language;
|
|
}
|
|
|
|
// Den Header auftrennen
|
|
$accepted_languages = preg_split('/,\s*/', $lang_variable);
|
|
|
|
// Die Standardwerte einstellen
|
|
$current_lang = $default_language;
|
|
$current_q = 0;
|
|
|
|
// Nun alle mitgegebenen Sprachen abarbeiten
|
|
foreach ($accepted_languages as $accepted_language) {
|
|
|
|
// Alle Infos über diese Sprache rausholen
|
|
// phpcs:disable Generic.Strings.UnnecessaryStringConcat
|
|
$res = preg_match('/^([a-z]{1,8}(?:-[a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i', $accepted_language, $matches);
|
|
// phpcs:enable
|
|
|
|
// war die Syntax gültig?
|
|
if (!$res) {
|
|
// Nein? Dann ignorieren
|
|
continue;
|
|
}
|
|
|
|
// Sprachcode holen und dann sofort in die Einzelteile trennen
|
|
$lang_code = explode('-', $matches[1]);
|
|
|
|
// Wurde eine Qualität mitgegeben?
|
|
if (isset($matches[2])) {
|
|
// die Qualität benutzen
|
|
$lang_quality = (float)$matches[2];
|
|
} else {
|
|
// Kompabilitätsmodus: Qualität 1 annehmen
|
|
$lang_quality = 1.0;
|
|
}
|
|
|
|
// Bis der Sprachcode leer ist...
|
|
while (!empty($lang_code)) {
|
|
// mal sehen, ob der Sprachcode angeboten wird
|
|
if (in_array(strtolower(join('-', $lang_code)), $allowed_languages)) {
|
|
// Qualität anschauen
|
|
if ($lang_quality > $current_q) {
|
|
// diese Sprache verwenden
|
|
$current_lang = strtolower(join('-', $lang_code));
|
|
$current_q = $lang_quality;
|
|
// Hier die innere while-Schleife verlassen
|
|
break;
|
|
}
|
|
}
|
|
// Wenn wir im strengen Modus sind, die Sprache nicht versuchen zu minimalisieren
|
|
if ($strict_mode) {
|
|
// innere While-Schleife aufbrechen
|
|
break;
|
|
}
|
|
// den rechtesten Teil des Sprachcodes abschneiden
|
|
array_pop($lang_code);
|
|
}
|
|
}
|
|
|
|
// die gefundene Sprache zurückgeben
|
|
return $current_lang;
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for generating the HTML head.
|
|
*
|
|
* @param string $injected Additional code to inject into the head, e.g. a
|
|
* reference to JS files.
|
|
*
|
|
* @return string
|
|
*/
|
|
function printHTMLHead(string $injected = "") {
|
|
|
|
$output = '<!DOCTYPE HTML>
|
|
<html lang="en">
|
|
<head>
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
|
|
|
<meta name="theme-color" content="#FFF" />
|
|
<link rel="stylesheet" type="text/css" href="assets/css/csvxml.min.css" />
|
|
<link rel="shortcut icon" sizes="128x128" href="assets/img/mdlogo-csvxml.svg" />
|
|
<script src="assets/js/csvxml-overview.min.js" type="text/javascript" defer></script>
|
|
|
|
<title>CSVXML :: museum-digital</title>
|
|
|
|
<meta name="keywords" content="Imports, museum-digital" />
|
|
';
|
|
|
|
$output .= $injected;
|
|
|
|
$output .= '
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<h1>
|
|
<img src="assets/img/mdlogo-csvxml.svg" />
|
|
<span>museum-digital:csvxml</span>
|
|
</h1>
|
|
';
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
/**
|
|
* Function generateHelpTooltip returns a tooltip for hovering over using the common settings.
|
|
*
|
|
* @param string $identifier ID attribute of the tooltip.
|
|
* @param string $title Title of the tooltip.
|
|
* @param string $explica More in-depth explanation: body of the tooltip.
|
|
* @param boolean $setParagraph If set to true (default), the content of the tooltip will be put into a <p> element. Optional.
|
|
*
|
|
* @return array
|
|
*/
|
|
function generateHelpTooltip(string $identifier, string $title, string $explica, bool $setParagraph = true):array {
|
|
|
|
$outputTag = '<a class="newToolTipTag icons iconsHelp" data-for="' . $identifier . '" title="Help"></a>';
|
|
$output = '<span class="newToolTip" id="tooltip_' . $identifier . '" data-title="' . $title . '">';
|
|
if ($setParagraph) $output .= '<p class="toolTipCont">';
|
|
$output .= $explica;
|
|
if ($setParagraph) $output .= '</p>';
|
|
$output .= '</span>';
|
|
|
|
return [$output, $outputTag];
|
|
|
|
}
|
|
|
|
/**
|
|
* Outputs a DOMDocument with correct header and then aborts.
|
|
* Used mainly for debugging.
|
|
*
|
|
* @param DOMDocument $xmlDoc XML object.
|
|
*
|
|
* @return string
|
|
*/
|
|
function printDOMDocToXML(DOMDocument $xmlDoc):string {
|
|
|
|
return '<?xml version="1.0" encoding="UTF-8"?>' . $xmlDoc->saveXML($xmlDoc->documentElement);
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for creating a DOMElement with a text node inside.
|
|
*
|
|
* @param DOMDocument $xmlDoc XML document.
|
|
* @param string $tag Tag.
|
|
* @param string $content Text content.
|
|
*
|
|
* @return DOMElement
|
|
*/
|
|
function createTextDomElement(DOMDocument $xmlDoc, string $tag, string $content):DOMElement {
|
|
|
|
try {
|
|
$element = $xmlDoc->createElement($tag);
|
|
}
|
|
catch (DOMException $e) {
|
|
echo "Error at " . __FILE__ . ", line #" . __LINE__ . PHP_EOL . "<br/>";
|
|
echo "Cannot create DOM element for $tag / $content";
|
|
exit;
|
|
}
|
|
|
|
$element->appendChild($xmlDoc->createTextNode($content));
|
|
|
|
return $element;
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for creating a DOMDocument record channel.
|
|
*
|
|
* @return array
|
|
*/
|
|
function getBlankRecordChannel():array {
|
|
|
|
$xmlDoc = new DOMDocument("1.0", "UTF-8");
|
|
$xmlMainElem = $xmlDoc->createElement("record");
|
|
$record_node = $xmlDoc->appendChild($xmlMainElem); //add RSS element to XML node
|
|
|
|
return [$xmlDoc, $record_node];
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for removing a directory with all its contents.
|
|
*
|
|
* @param string $dir File path of the directory to remove.
|
|
*
|
|
* @return void
|
|
*/
|
|
function rrmdir(string $dir) {
|
|
if (is_dir($dir)) {
|
|
$objects = scandir($dir);
|
|
foreach ($objects as $object) {
|
|
if ($object != "." && $object != "..") {
|
|
if (filetype($dir . "/" . $object) == "dir") rrmdir($dir . "/" . $object); else unlink($dir . "/" . $object);
|
|
}
|
|
}
|
|
reset($objects);
|
|
rmdir($dir);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for checking if two arrays have identical values / contents.
|
|
*
|
|
* @param array $arrayA First array to compare.
|
|
* @param array $arrayB Second array to compare.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function identical_values(array $arrayA, array $arrayB):bool {
|
|
sort($arrayA);
|
|
sort($arrayB);
|
|
return $arrayA == $arrayB;
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for retrieving the anti-csrf token or generating it if need be.
|
|
*
|
|
* @return string
|
|
*/
|
|
function getAntiCsrfToken():string {
|
|
|
|
if (empty($_SESSION['csrf-token'])) {
|
|
$_SESSION['csrf-token'] = bin2hex(random_bytes(32));
|
|
}
|
|
|
|
return $_SESSION['csrf-token'];
|
|
|
|
}
|
|
|
|
/**
|
|
* Function for validating anti-csrf tokens. Each anti-csrf token is removed
|
|
* after use.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function validateAntiCsrfToken():bool {
|
|
|
|
$validity = false;
|
|
if (!empty($_POST['csrf-token'])
|
|
&& !empty($_SESSION['csrf-token'])
|
|
&& hash_equals($_SESSION['csrf-token'], $_POST['csrf-token']) === true
|
|
) {
|
|
$validity = true;
|
|
}
|
|
$_SESSION['csrf-token'] = null; unset($_SESSION['csrf-token']);
|
|
|
|
return $validity;
|
|
|
|
}
|
|
|