*/ /** * Browsersprache ermitteln * * @param array $allowed_languages Array of allowed languages * @param string $default_language Language code of the default language * @param string $lang_variable Already set language variable * @param bool $strict_mode Whether to demand de (false) or de-de * * @return string */ function lang_getfrombrowser($allowed_languages, $default_language, $lang_variable = null, $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($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($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($transform) { $transform = preg_replace('#
#', ' ', $transform); $transform = preg_replace('#
#', ' ', $transform); $transform = preg_replace('#
#', ' ', $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($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($from, $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($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($folder, $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 boolean $title Title of the overall output. * @param boolean $lang Language. Optional. * @param boolean $debug Enables/disables debug mode. Optional. * * @return void */ function runPDF($folder, $texFilename, $filename, $title, $lang = "de", $debug = false) { if (!is_dir("./tmp")) mkdir("./tmp"); /* Eine eindeutige ID, beispielsweise: 4b3403665fea6 */ $uniqid = uniqid("PDF_"); copyFolder("$folder", "./tmp/$uniqid"); copy("brochure.tex", "./tmp/$uniqid/brochure.tex"); $generateUserSettings = function($lang, $title) { $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($title) . '}' . PHP_EOL; }; $userSettings = $generateUserSettings($lang, $title); 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 $texFilename.tex"); ensureDir(__DIR__ . "/pdf/$lang"); // Move output file to PDF directory. if (file_exists(__DIR__ . "/pdf/$lang/brochure.pdf")) unlink(__DIR__ . "/pdf/$lang/brochure.pdf"); rename("brochure.pdf", __DIR__ . "/pdf/$lang/brochure.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 string $descriptions Page description. Optional. * * @return string */ function printHTMLPage(string $title, string $contents, string $lang = "en", string $descriptions = "") { $output = ' ' . $title. ' '; $output .= $contents . ' '; return $output; } ?>