357 lines
11 KiB
PHP
357 lines
11 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 $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('#<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($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 = '<!DOCTYPE html>
|
|||
|
<html lang="' . $lang . '">
|
|||
|
<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="stylesheet" type="text/css" href="css/main.css">
|
|||
|
|
|||
|
<title>' . $title . '</title>
|
|||
|
<meta>' . $descriptions . '</meta>
|
|||
|
|
|||
|
</head>
|
|||
|
<body id="start">
|
|||
|
|
|||
|
<nav id="mainNav">
|
|||
|
<a href="#start">Top</a>
|
|||
|
<a href="#bottom"></a>
|
|||
|
</nav>
|
|||
|
|
|||
|
';
|
|||
|
$output .= $contents . '
|
|||
|
<footer id="bottom">
|
|||
|
<a href="pdf/' . $lang . '/brochure.pdf" class="buttonLike">PDF</a>
|
|||
|
</footer>
|
|||
|
</html>';
|
|||
|
|
|||
|
|
|||
|
return $output;
|
|||
|
|
|||
|
}
|
|||
|
?>
|