This repository has been archived on 2023-10-25. You can view files and clone it, but cannot push or open issues or pull requests.
about-brochure/functions.php

400 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?PHP
/**
* Main functions file.
*
* @author Joshua Ramon Enslin <joshua@jrenslin.de>
*/
/**
* Browsersprache ermitteln
*
* @param array $allowed_languages Array of allowed languages.
* @param string $default_language Language code of the default language.
* @param string|null $lang_variable Already set language variable.
* @param boolean $strict_mode Whether to demand de (false) or de-de.
*
* @return string
*/
function lang_getfrombrowser(array $allowed_languages, string $default_language, $lang_variable = null, bool $strict_mode = true) {
// $_SERVER['HTTP_ACCEPT_LANGUAGE'] verwenden, wenn keine Sprachvariable mitgegeben wurde
if ($lang_variable === null) {
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
$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
);
// 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 (count($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 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 ensuring the existence of all required files and folders.
*
* @return void
*/
function ensureEnvironment() {
$dirs = [
"contents",
"pdf",
"tex"
];
foreach ($dirs as $dir) {
ensureDir(__DIR__ . "/$dir");
}
}
/**
* Function transform escapes a string for printing in TeX
*
* @param string $transform String to transform.
*
* @return string
*/
function transform(string $transform):string {
$transform = preg_replace('#<br>#', ' ', $transform);
$transform = preg_replace('#</br>#', ' ', $transform);
$transform = preg_replace('#<br />#', ' ', $transform);
$transform = preg_replace('#&rsquo;#', '\'', $transform);
$transform = preg_replace('#' . chr(11) . '#', ' ', $transform);
$transform = preg_replace('#&quot;#', '"', $transform);
$transform = preg_replace('#&amp;#', '&', $transform);
$transform = preg_replace('#•#', '&#8226;', $transform);
$transform = preg_replace('#' . chr(9) . '#', '', $transform);
$transform = str_replace('&', '\\&', $transform);
$transform = str_replace('{', '\\{', $transform);
$transform = str_replace('}', '\\}', $transform);
$transform = str_replace('_', '\\_', $transform);
$transform = preg_replace('#Ä#', '&#196;', $transform);
$transform = preg_replace('#À#', '&#192;', $transform);
$transform = preg_replace('#Á#', '&#193;', $transform);
$transform = preg_replace('#à#', '&#224;', $transform);
$transform = preg_replace('#á#', '&#225;', $transform);
$transform = preg_replace('#ä#', '&#228;', $transform);
$transform = preg_replace('#Ö#', '&#214;', $transform);
$transform = preg_replace('#Ò#', '&#210;', $transform);
$transform = preg_replace('#Ó#', '&#211;', $transform);
$transform = preg_replace('#ò#', '&#242;', $transform);
$transform = preg_replace('#ó#', '&#243;', $transform);
$transform = preg_replace('#ö#', '&#246;', $transform);
$transform = preg_replace('#Ü#', '&#220;', $transform);
$transform = preg_replace('#Ù#', '&#217;', $transform);
$transform = preg_replace('#Ú#', '&#218;', $transform);
$transform = preg_replace('#ù#', '&#249;', $transform);
$transform = preg_replace('#ú#', '&#250;', $transform);
$transform = preg_replace('#ü#', '&#252;', $transform);
$transform = preg_replace('#ß#', '&#223;', $transform);
$transform = preg_replace('#Ç#', '&#199;', $transform);
$transform = preg_replace('#ç#', '&#231;', $transform);
$transform = preg_replace('##', '&#180;', $transform);
$transform = preg_replace('#é#', '&#233;', $transform);
$transform = preg_replace('#è#', '&#232;', $transform);
foreach (array("[", "]") as $toescape)
$transform = str_replace ($toescape, "$" . $toescape . "$", $transform);
$transform = html_entity_decode($transform, ENT_QUOTES, "utf-8" );
return $transform;
}
/**
* Function scanDirConts is a wrapper around scandir(), which removes [".", ".."].
*
* @param string $folder Folder to scan.
*
* @return string[]
*/
function scanDirConts(string $folder) {
return array_values(array_diff(scandir($folder), [".", "..", ".git"]));
}
// Generating PDFs
/**
* Function copyFolder copies a folder including all its contents.
*
* @param string $from Source location.
* @param string $to Target location.
*
* @return void
*/
function copyFolder(string $from, string $to) {
mkdir($to);
foreach (array_diff(scandir("$from"), [".", ".."]) as $file) {
copy("$from/$file", "$to/$file");
}
}
/**
* Function removeFolder deletes a folder including all its contents.
*
* @param string $folder Folder location.
*
* @return void
*/
function removeFolder(string $folder) {
foreach (array_diff(scandir("$folder"), [".", ".."]) as $file) {
if (is_dir("$folder/$file")) removeFolder("$folder/$file");
else unlink("$folder/$file");
}
rmdir($folder);
}
/**
* Function removeFolder deletes a folder including all its contents.
* It stops if a subfolder is younger than 60 seconds
*
* @param string $folder Folder location.
* @param string $exclude Folder for which time should not be checked.
*
* @return boolean
*/
function removeFolderGently(string $folder, string $exclude) {
foreach (array_diff(scandir("$folder"), [".", ".."]) as $file) {
if (time() - filemtime("$folder/$file") < 10 and $file != $exclude) continue;
if (is_dir("$folder/$file")) $output = removeFolder("$folder/$file");
else if (!is_dir("$folder/$file")) unlink("$folder/$file");
}
if (count(array_diff(scandir("$folder"), [".", ".."])) == 0) rmdir($folder);
return $output;
}
/**
* Function runPDF runs LaTeX to generate a PDF file and then serves said file.
* It also does the subsequent cleanup by deleting the folder the PDF was generated in afterwards.
*
* @param string $folder Determines the folder (say, template) to use for PDF generation.
* @param string $texFilename Name of the TeX file. Used without its ending.
* @param string $filename Filename as it should be shown to the user.
* @param array $pdfSettings Additional parameters to use \def for.
* @param string $lang Language. Optional.
* @param boolean $debug Enables/disables debug mode. Optional.
*
* @return void
*/
function runPDF(string $folder, string $texFilename, string $filename, array $pdfSettings, string $lang = "de", bool $debug = false) {
if (!is_dir("./tmp")) mkdir("./tmp");
/* Eine eindeutige ID, beispielsweise: 4b3403665fea6 */
$uniqid = uniqid("PDF_");
copyFolder("$folder", "./tmp/$uniqid");
copy("$texFilename.tex", "./tmp/$uniqid/$texFilename.tex");
$generateUserSettings = function($lang, $pdfSettings) {
$babelPackages = [
"en" => "english",
"de" => "german",
"es" => "spanish",
"hu" => "hungarian"
];
if (in_array($lang, $babelPackages)) $lan = $lang;
else $lan = "en";
return '\\usepackage[' . $babelPackages[$lan] . ']{babel}
\\def \\pageTitle {' . transform($pdfSettings['title']) . '}' . PHP_EOL . '
\\def \\pageTitleImg {' . transform($pdfSettings['bgImg']) . '}' . PHP_EOL;
};
$userSettings = $generateUserSettings($lang, $pdfSettings);
file_put_contents("./tmp/$uniqid/pdfSettings.tex", $userSettings);
chdir("./tmp/$uniqid");
// Right now, pdflatex needs to be used. Once new packages are available, xelatex is to be preferred.
exec("pdflatex -interaction nonstopmode -pdf -pv $texFilename.tex");
ensureDir(__DIR__ . "/pdf/$lang");
// Move output file to PDF directory.
if (file_exists(__DIR__ . "/pdf/$lang/$filename.pdf")) unlink(__DIR__ . "/pdf/$lang/$filename.pdf");
rename("$filename.pdf", __DIR__ . "/pdf/$lang/$filename.pdf");
# header("Content-type:application/pdf");
# header("Content-Disposition:inline;filename=$filename");
# readfile ("$texFilename.pdf");
chdir(__DIR__);
if (!$debug) removeFolderGently("./tmp", $uniqid);
}
// HTML Stuff
/**
* Function getHTMLHead returns the HTML for the top of the page.
*
* @param string $title Title of the page.
* @param string $contents Page contents.
* @param string $lang Language. Optional.
* @param array $availableLangs Page description. Optional.
* @param string $descriptions Page description. Optional.
* @param string $pdfLink Link to brochure. Optional.
*
* @return string
*/
function printHTMLPage(string $title, string $contents, string $lang = "en", array $availableLangs = ["en"], string $descriptions = "", string $pdfLink = "brochure"):string {
$output = '<!DOCTYPE html>
<html lang="' . $lang . '" id="' . str_replace(":", "", str_replace(" ", "", $title)) . '">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta charset="UTF-8" />
<link rel="shortcut icon" sizes="16x16 32x32" href="./media/mdlogo-32px.png" />
<link rel="shortcut icon" sizes="64x64" href="./media/mdlogo-64px.png" /><link rel="stylesheet" type="text/css" href="css/main.css">
<meta name="twitter:title" content="' . $title . '" />
<meta property="og:title" content="' . $title . '" />
<title>' . $title . '</title>
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@museumdigital" />
<meta name="description" content="' . $descriptions . '" />
<meta name="twitter:description" content="' . $descriptions . '" />
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body id="start">
<nav id="mainNav">
<a href="./?t=about#start">About</a>
<a href="./?t=press#start">Pressespiegel</a>
<a href="#bottom"></a>
</nav>
';
$output .= $contents . '
<footer id="bottom">
<a href="pdf/' . $lang . '/' . $pdfLink . '.pdf" class="buttonLike">PDF</a>
</footer>
<footer id="optionsFooter">
<div>
</div>
<div>
<ul id="optionsLangs">
';
foreach ($availableLangs as $tLang) {
$output .= "
<li><a href='./?lang=$tLang'>$tLang</a></li>
";
}
$output .= '
</ul>
</div>
</footer>
<script src="./js/tracking.js"></script>
<noscript><p><img src="https://www.jrenslin.de/museum-digital/piwik/piwik.php?idsite=1" /></p></noscript>
</html>';
return $output;
}