400 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			400 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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('#’#', '\'', $transform);
 | 
						||
    $transform = preg_replace('#' . chr(11) . '#', ' ', $transform);
 | 
						||
    $transform = preg_replace('#"#', '"', $transform);
 | 
						||
    $transform = preg_replace('#&#', '&', $transform);
 | 
						||
    $transform = preg_replace('#•#', '•', $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('#Ä#', 'Ä', $transform);
 | 
						||
    $transform = preg_replace('#À#', 'À', $transform);
 | 
						||
    $transform = preg_replace('#Á#', 'Á', $transform);
 | 
						||
    $transform = preg_replace('#à#', 'à', $transform);
 | 
						||
    $transform = preg_replace('#á#', 'á', $transform);
 | 
						||
    $transform = preg_replace('#ä#', 'ä', $transform);
 | 
						||
    $transform = preg_replace('#Ö#', 'Ö', $transform);
 | 
						||
    $transform = preg_replace('#Ò#', 'Ò', $transform);
 | 
						||
    $transform = preg_replace('#Ó#', 'Ó', $transform);
 | 
						||
    $transform = preg_replace('#ò#', 'ò', $transform);
 | 
						||
    $transform = preg_replace('#ó#', 'ó', $transform);
 | 
						||
    $transform = preg_replace('#ö#', 'ö', $transform);
 | 
						||
    $transform = preg_replace('#Ü#', 'Ü', $transform);
 | 
						||
    $transform = preg_replace('#Ù#', 'Ù', $transform);
 | 
						||
    $transform = preg_replace('#Ú#', 'Ú', $transform);
 | 
						||
    $transform = preg_replace('#ù#', 'ù', $transform);
 | 
						||
    $transform = preg_replace('#ú#', 'ú', $transform);
 | 
						||
    $transform = preg_replace('#ü#', 'ü', $transform);
 | 
						||
    $transform = preg_replace('#ß#', 'ß', $transform);
 | 
						||
    $transform = preg_replace('#Ç#', 'Ç', $transform);
 | 
						||
    $transform = preg_replace('#ç#', 'ç', $transform);
 | 
						||
    $transform = preg_replace('#’#', '´', $transform);
 | 
						||
    $transform = preg_replace('#é#', 'é', $transform);
 | 
						||
    $transform = preg_replace('#è#', 'è', $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;
 | 
						||
 | 
						||
}
 |