diff options
Diffstat (limited to 'templater_common.php')
| -rw-r--r-- | templater_common.php | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/templater_common.php b/templater_common.php new file mode 100644 index 0000000..7f6a684 --- /dev/null +++ b/templater_common.php @@ -0,0 +1,567 @@ +<?php +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +?> +<? +/* vim: set ts=4 sw=4 et : */ + +require_once __DIR__ . "/lookup.php"; +require_once __DIR__ . "/lookup_more.php"; + +(function () use ($mysqli, $sql, $payload_sql, $independent_payload_sql, $payload_sql_order, $independent_payload_sql_order, $isemail, $post_sql) { +global $abschlusskombis, $studiengaenge, $signaturen; + +$stips_sql = "SELECT Person FROM Stipendien WHERE Jahr >= 2001 AND Förderbeginn > '2000-01-01' GROUP BY Person;"; +$stmt = $mysqli->prepare($stips_sql); +$stmt->bind_result($stips_persid); +$stmt->execute(); +$stips = []; +while ($stmt->fetch()) { + $stips[$stips_persid] = 1; +} +$stmt->reset(); +?> +<script> +var Stips = {}; +try { + Stips = JSON.parse('<? echo str_replace("'", "\'", str_replace("\\", "\\\\", json_encode($stips))); ?>'); +} catch (e) { ; } +</script> +<? + +$prefs_sql = "SELECT persid, salutation FROM Personen_Prefs WHERE userid=?;"; +$stmt = $mysqli->prepare($prefs_sql); +$stmt->bind_param("i", $_SESSION['auth_userid']); +$stmt->bind_result($prefs_persid, $prefs_salutation); +$stmt->execute(); +$prefs = []; +while ($stmt->fetch()) { + $prefs[$prefs_persid] = $prefs_salutation; +} +$stmt->reset(); +?> +<script> +var Prefs = {}; +try { + Prefs = JSON.parse('<? echo str_replace("'", "\'", str_replace("\\", "\\\\", json_encode($prefs))); ?>'); +} catch (e) { ; } +</script> +<? + +$ids = explode(',', $_POST['ids']); + +$ids_in = "("; +$first = true; +foreach ($ids as $i) { + if (!$first) $ids_in .= ', '; + $first = false; + $ids_in .= "'" . $i . "'"; +} +$ids_in .= ")"; + +$sql = $sql . ' ' . $ids_in; +$sql = $sql . ' ' . $post_sql; + +if ($isemail && isset($_SESSION['singleemail'])) { +?> + <div style="border: 1px solid grey; padding: .2em; margin-top: .5em; max-width: 700px;"> + <b>Einzel-E-Mail-Modul ist aktiv. Alle Adressaten werden zusammengefasst und sind direkter Adressat (To) der E-Mail.</b> Da sich damit alle Adressaten gegenseitig sehen können, sollte diese Funktion nur verwendet werden, wenn dies datenschutzrechtlich unbedenklich ist. Individualisierung durch Templateauszeichnungen ist selbstredent nicht möglich. + <br /> + <button class="small" style="background: lightcoral;" onclick="$.ajaxSetup({async:false}); $.post('/db/main/nosingleemail.php'); location.reload(); return false;">Einzel-E-Mail-Modus beenden</button> + </div> +<? + $sql = "SELECT GROUP_CONCAT(q.Email) AS Email FROM (" . $sql . ") q"; +} + +$stmt = $mysqli->prepare($sql); +$stmt->execute(); +$r = $stmt->get_result(); +echo $mysqli->error; + +$data = []; +$i = 0; +while (($l = $r->fetch_object())) { + $e = []; + foreach ($l as $k => $v) { + $e[$k] = $v; + if ($k == 's2' || $k == 's3' || $k == 's4' || $k == 's5' || $k == 's6' || $k == 'data') + $e[$k] = json_decode($v); + } + $e['index'] = $i; + $data[] = $e; + $i++; +} +$stmt->reset(); + +if ($payload_sql) { + $payload_sql = $payload_sql . $ids_in; + if ($payload_sql_order) + $payload_sql .= " ORDER BY " . $payload_sql_order; + $stmt = $mysqli->prepare($payload_sql); + $stmt->execute(); + $r = $stmt->get_result(); + echo $mysqli->error; + + $payload = []; + $i = 0; + while (($l = $r->fetch_object())) { + $e = []; + foreach ($l as $k => $v) { + $e[$k] = $v; + } + $e['index'] = $i; + $payload[] = $e; + $i++; + } + $stmt->reset(); +} + +if ($independent_payload_sql) { + if ($independent_payload_sql_order) + $independent_payload_sql .= " ORDER BY " . $independent_payload_sql_order; + $stmt = $mysqli->prepare($independent_payload_sql); + $stmt->execute(); + $r = $stmt->get_result(); + echo $mysqli->error; + + $independent_payload = []; + $i = 0; + while (($l = $r->fetch_object())) { + $e = []; + foreach ($l as $k => $v) { + $e[$k] = $v; + } + $e['index'] = $i; + $independent_payload[] = $e; + $i++; + } + $stmt->reset(); +} +?> + +<h3 style="margin-bottom: 0;">Template <i style="cursor: pointer;" onclick="$('#template_info').toggle();" class="fas fa-info-circle"></i></h3> + +<p id="template_info" style="display: none;" class="explain"> + Felder mit <code class="explain">{{ d.pfad.feld }}</code> auszeichnen, z.B. <code class="example">{{ d.s2.Nachname }}</code> – oder unten aktuell verfügbare Felder klicken zum Einfügen an Cursorposition + <br /> + Zeilenumbruch statt Absatz mit <code class="explain">Umschalt-Enter</code> oder besser nachvollziehbar mit <code class="example">[br]</code> + <br /> + Seitenumbruch im PDF mit <code class="explain">[formfeed]</code> + <br /> + HTML-Tags mit <code class="explain">[]</code> umschließen, z.B. <code class="example">[hr]</code> (für horizontale Trennlinie) oder <code class="example">[div style="border: 1px solid black;"]Box[/div]</code> (für div-Element mit 1px Rand) + <br /> + Fallunterscheidung: <code class="explain">{{ d.Jahr == '2013' ? 'Ja, 2013.' : 'Nein, nicht das Jahr 2013' }}</code> + <br /> + Signatur: <code class="explain">{{ 'Hagemann' | signatur }}</code> + <br /> + Automatische Anrede: <code class="explain">{{ 'informal' | autoanrede }}</code> oder <code class="explain">{{ 'formal' | autoanrede }}</code> + <br /> + Filter: <code class="explain">{{ d.Feld | filter }}</code>. Verfügbar: + <br /> + - <code class="explain">filter</code> (generischer Filter, filtert Liste auf <span style="color: lightcoral;">Wert</span> in <span style="color: darkgoldenrod;">Attribut</span>. Bsp.: <code class="example">{{ p | filter:<span style="color: darkgoldenrod;">'persid'</span>:<span style="color: lightcoral;">d.ID</span> }}</code>) + <br /> + - <code class="explain">event</code> (Teilnahmelink zum Event, <code class="example">{{ d.token | event }}</code>) + <br /> + - <code class="explain">eventlist</code> (Ausgabe Eventliste samt Anmeldelink für Person aus Menge gewählter Events, bei der die jew. Person eingetragen ist; <code class="example">{{ d.ID | eventlist }}</code>, optionale Parameter: minPartID, CatID, Reihenfolge umdrehen (<code class="example">{{ d.ID | eventlist:0:0:1 }}</code>) + <br /> + - <code class="explain">studiengang</code> (Studiengang anhand ID aus Abschlusskombis, z.B. <code class="example">{{ d.s3.studiengang | studiengang }}</code>, für alte Studiengänge: <code class="example">studiengang_alt</code>) + <br /> + - <code class="explain">my</code> (Link zum Persönlichen Bereich DS anhand UID) + <br /> + - <code class="explain">mysocial</code> (Link zum Persönlichen Bereich Sozialstipendium anhand UID) + <br /> + - <code class="explain">mylue</code> (Link zum Persönlichen Bereich Leistungsüberprüer anhand PersID) + <br /> + - <code class="explain">lue24</code> (Teilnahmelink Leistungsüberprüfung 2024 anhand UID) + <br /> + - <code class="explain">dscontinue</code> (Fortführlink DS anhand UID) + <br /> + - <code class="explain">socialcontinue</code> (Fortführlink Sozialstipendium anhand UID) + <br /> + - <code class="explain">dsnachreichung</code> (Link Nachreichungsbereich DS anhand UID) + <br /> + - <code class="explain">alumni21</code> (Link Alumni-Umfrage 2021 anhand PersID) + <br /> + - <code class="explain">komm21</code> (Link Kommissionsmitglieder-Umfrage 2021 anhand PersID) + <br /> + - <code class="explain">{{ x | stiplist:y:z:fb }}</code> (Stipendiatenliste. Parameter: x→FoerdID, y→Förderart (0=alle,5=Sozial), z→Art der Ausgabe (0/1=kompakt, 2=mit Förderzeitraum, 3=mit Förderzeitraum und Förderart, 4=mit Förderzeitraum und vereinfachter Förderart (DS/Sozial), 5=mit Teilnahme bei Event (Niklas muss das vorher explizit einstellen!), fb→erst ab Förderbeginn JJJJ-MM-TT Bsp.: <code class="example">{{ d.FoerdID | stiplist:0:4:'2023-04-01' }}</code> + <br /> + Verfügbare Felder: +<? +foreach ($data[0] as $k => $v) { +?> + <a style="text-decoration: underline; color: #0c8ab3 !important; cursor: pointer;" onclick="quill.focus(); quill.insertText(quill.getSelection(true), '{{ d[\'<?=$k?>\'] }}');">d.<?=$k?></a> +<? + if (is_object($data[0][$k])) { + foreach ($data[0][$k] as $kk => $v) { +?> + <small>.<a style="text-decoration: underline; cursor: pointer;" onclick="quill.focus(); quill.insertText(quill.getSelection(true), '{{ d[\'<?=$k?>\'][\'<?=$kk?>\'] }}');"><?=$kk?></a></small> +<? + } + } +} +?> +</p> + +<div class="editorcontainer" style="background: white; color: black;"> + <div id="editor"><? if ($isemail) {?>{{ '<?=$_SESSION['auth_user']?>' | signatur }}<? } ?></div> +</div> + +<? +(function () use ($mysqli) { + $sql = " +SELECT id, title +FROM pages +WHERE visible = 1 AND oid = 2 +ORDER BY title +"; + $stmt = $mysqli->prepare($sql); + $stmt->bind_result($pid, $ptitle); + $stmt->execute(); +?> + <textarea style="display: none;" class="htmlcontainer" style="background: darkbeige !important; color: grey; height: 1em; width: 3em;"></textarea> + +<? +})(); +?> + +<script> +<? minStart(); ?> + +var Delta = Quill.import('delta'); +var Break = Quill.import('blots/break'); +var Embed = Quill.import('blots/embed'); + +function lineBreakMatcher() { + var newDelta = new Delta(); + newDelta.insert({'break': ''}); + return newDelta; +} + +class SmartBreak extends Break { + length () { + return 1; + } + value () { + return '\n'; + } + insertInto(parent, ref) { + Embed.prototype.insertInto.call(this, parent, ref); + } +} +SmartBreak.blotName = 'break'; +SmartBreak.tagName = 'BR' +Quill.register(SmartBreak); + +var quill = new Quill('#editor', { + theme: 'snow', + modules: { + toolbar: [ + [{ header: [1, 2, 3, false] }], + [{'size': ['small', false, 'large', 'huge']}], + ['bold', 'italic', 'underline', 'strike'], + [{ 'color': [] }, { 'background': [] }], + ['link', 'blockquote', 'image'], + [{'list': 'ordered'}, {'list': 'bullet'}], + [{'script': 'sub'}, {'script': 'super'}], + [{'indent': '-1'}, {'indent': '+1'}], + [{'align': []}], + ['clean'] + ], + clipboard: { + matchers: [ + ['BR', lineBreakMatcher] + ] + }, + keyboard: { + bindings: { + linebreak: { + key: 13, + shiftKey: true, + handler: function (range) { + var currentLeaf = this.quill.getLeaf(range.index)[0]; + var nextLeaf = this.quill.getLeaf(range.index + 1)[0]; + + this.quill.insertEmbed(range.index, 'break', true, 'user'); + + if (nextLeaf === null || (currentLeaf.parent !== nextLeaf.parent)) { + this.quill.insertEmbed(range.index, 'break', true, 'user'); + } + + this.quill.setSelection(range.index + 1, Quill.sources.SILENT); + } + } + } + } + } +}); + +function redoRows(row, d, pum, index, dindex) { + if (typeof row === 'undefined') + return; + + if (typeof data !== 'object') + return; + + if (data[dindex].__done) { + row.classList.add('email_success'); + row.classList.remove('email_failed'); + } + if (data[dindex].__failed) { + row.classList.add('email_failed'); + row.classList.remove('email_success'); + } + if (data[dindex].__skip) { + row.classList.add('validated'); + row.classList.remove('email_failed'); + row.classList.remove('email_success'); + } +} + +<? minEnd(); ?> +</script> + +<h3 style="margin-bottom: 0;">Vorschau</h3> + +<style> + #preview h1, #preview h2, #preview h3, #preview h4, #preview p, #preview * { font-family: "Arial Narrow", "Arial", sans-serif; } + #preview ul, #preview ol, #preview li, #preview strong, #preview em, #preview i, #preview b, #preview u, #preview s, #preview span, #preview sub, #preview sup { font-family: "Arial Narrow", "Arial", sans-serif; } + #preview blockquote { font-family: "Arial Narrow", "Arial", sans-serif; } + + #preview .ql-size-small { font-size: 70%; } + #preview .ql-size-normal { font-size: 100%; } + #preview .ql-size-large { font-size: 130%; } + #preview .ql-size-huge { font-size: 180%; } + + #preview a { color: blue; text-color: blue; } + .ql-editor { padding: 0; } +</style> + +<div id="previewcontainer" style="background: white; color: black; border: 1px solid lightgrey; padding: .5em;"> + <div id="preview" ng-controller="previewCtrl"></div> +</div> + +<h3 style="margin-bottom: 0;">Adressaten <i onclick="$('#recipient_info').toggle();" class="fas fa-info-circle"></i></h3> + +<div id="recipient_info" style="display: none;"> +<p>Mit Klick auf blaue RUID/UID/ID die Vorschau zum entsprechenden Adressaten wechseln.</p> +<p>Bei Mehrfachverknüpfungen (bspw. Person bei Orga) RUID/UID verwenden, ansonsten wird die Vorschau nur für das angeklickte Merkmal angepasst.</p> +</div> + +<? +(function () use ($mysqli, $sql) { + $stmt = $mysqli->prepare($sql); + $stmt->execute(); + $r = $stmt->get_result(); + $id = "email"; + $order = '[]'; + $noautolinks = true; + $nodefaultlinks = true; + $links = [ + '#' => '#', + 'RUID' => '#', + 'ruid' => '#', + 'UID' => '#', + 'uid' => '#', + 'ID' => '#', + 'id' => '#', + ]; + $rowcallback = "redoRows"; + $norefresh = true; + include __DIR__ . '/autotable.php'; + $stmt->reset(); +})(); +?> + +<script> + +window.data = JSON.parse('<?php echo str_replace("'", "\'", str_replace("\\", "\\\\", json_encode($data))); ?>'); +window.payload = JSON.parse('<?php echo str_replace("'", "\'", str_replace("\\", "\\\\", json_encode($payload))); ?>'); +window.independent_payload = JSON.parse('<?php echo str_replace("'", "\'", str_replace("\\", "\\\\", json_encode($independent_payload))); ?>'); +window.pivot = data[0]; +window.count_s = 0; +window.count_f = 0; + +function bP() { + $('.consignee .changeable').parent().parent().css('background', 'unset'); + + var dd = $('#editor .ql-editor').html(); + dd = dd.replace(/┌/g, '<').replace(/┐/g, '>'); + $('#previewcontainer').html('<div id="preview">' + dd + '</div>'); + angular.bootstrap($('#preview'), ['previewApp']); + angular.element('#preview').scope().d = pivot; + angular.element('#preview').scope().p = payload; + angular.element('#preview').scope().ip = independent_payload; + angular.element('#preview').scope().$apply(); + + var a = $('#preview').html(); + a = a.replace(/\[/g, '<').replace(/\]/g, '>'); + $('#preview').html(a); + + try { $('input[name=organisation]').val(pivot.organisation || pivot.Organisation); } catch (e) { } + try { $('input[name=anrede]').val(pivot.anrede || pivot.Anrede); } catch(e) { } + try { $('input[name=anrede_briefkopf]').val(pivot.anrede_briefkopf); } catch (e) { } + try { $('input[name=titel]').val(pivot.titel || pivot.Titel); } catch (e) { } + try { $('input[name=vorname]').val(pivot.vorname || pivot.Vorname); } catch (e) { } + try { $('input[name=nachname]').val(pivot.nachname || pivot.Nachname); } catch (e) { } + try { $('input[name=strasse]').val(pivot.strasse || pivot.Strasse || pivot.Straße); } catch (e) { } + try { $('input[name=adresszusatz]').val(pivot.adresszusatz || pivot.Adresszusatz); } catch (e) { } + try { $('input[name=plz]').val(pivot.plz || pivot.PLZ); } catch (e) { } + try { $('input[name=template]').val(pivot.hochschule || pivot.Hochschule); } catch (e) { } + try { $('input[name=ort]').val(pivot.ort || pivot.Ort); } catch (e) { } + try { $('input[name=uid]').val(pivot.genuid || pivot.RUID || pivot.ruid || pivot.ID || pivot.id || pivot.UID || pivot.uid); } catch (e) { } + try { $('input[name=email_to]').val(pivot.email || pivot.Email); } catch (e) { } + try { $('input[name=email_id]').val(pivot.uid || pivot.ID || pivot.id); } catch (e) { } + try { $('input[name=data]').val(pivot.data || JSON.stringify(pivot)); } catch (e) { } +} + +$(document).ready(function () { + window.preview = angular.module('previewApp', []); + window.previewCtrl = preview.controller('previewCtrl', ['$scope', function ($scope) { + $scope.d = data[0]; + }]); + + $('textarea.htmlcontainer').on('input change', function () { + if ($('textarea.htmlcontainer').val().length > 10) { + $('.editorcontainer').hide(); + $('#previewcontainer').hide(); + return; + } + $('.editorcontainer').show(); + $('#previewcontainer').show(); + }); + + $('.consignee .changeable').on('input change', function () { + $(this).parent().parent().css('background', 'yellow'); + }); + + preview.filter('autoanrede', function () { + return function (x) { + var persid = ""; + + if (typeof pivot.PersID !== 'undefined') persid = pivot.PersID; + else if (typeof pivot.persid !== 'undefined') persid = pivot.persid; + else if (typeof pivot.ID !== 'undefined') persid = pivot.ID; + else if (typeof pivot.id !== 'undefined') persid = pivot.id; + + var titel = pivot.Titel; + if (titel == null) titel = ""; + + var anrede = pivot.Anrede; + if (anrede == null) anrede = ""; + + var r = ""; + + try { + + if ((x === 'informal' && Prefs[persid] !== 1) || Prefs[persid] === 2 || Prefs[persid] === 3 || (Prefs[persid] !== 1 && Stips[persid] === 1)) { + if (pivot.Geschlecht.charAt(0) === 'm') { + r += "Lieber "; + } else if (pivot.Geschlecht.charAt(0) === 'w') { + r += "Liebe "; + } else { + r += "Hallo "; + } + if (Prefs[persid] !== 3 && Stips[persid] !== 1) { + if (pivot.Geschlecht.charAt(0) === 'm') { + r += "Herr "; + } else if (pivot.Geschlecht.charAt(0) === 'w') { + r += "Frau "; + } + } + if (Prefs[persid] === 3 || Stips[persid] === 1) { + r += pivot.Vorname; + } else { + if (titel.indexOf('Prof') !== -1) { + if (pivot.Geschlecht.charAt(0) == 'w') { + r += "Professorin "; + } else { + r += "Professor "; + } + } else if (titel.indexOf('Dr.') !== -1) { + r += "Dr. "; + } else if (titel != ""){ + r += titel + " "; + } + r += pivot.Nachname; + } + r += ','; + + if (anrede.indexOf("Eheleute") !== -1 || anrede.indexOf("Ehepaar") !== -1) { + r = pivot['informale Ansprache'] + " " + pivot.Nachname + ","; + } + } else if (x === 'formal' || Prefs[persid] == 1) { + if (pivot.Geschlecht.charAt(0) === 'm') { + r += "Sehr geehrter Herr "; + } else if (pivot.Geschlecht.charAt(0) === 'w') { + r += "Sehr geehrte Frau "; + } + + if (titel.indexOf('Prof') !== -1) { + r += "Professor "; + } else if (titel.indexOf('Dr.') !== -1) { + r += "Dr. "; + } else if (titel != ""){ + r += titel + " "; + } + r += pivot.Nachname; + r += ','; + + if (anrede.indexOf("Eheleute") !== -1 || anrede.indexOf("Ehepaar") !== -1) { + r = pivot.Ansprache + " " + pivot.Nachname + ","; + } + } + + } catch (e) { + r = "Hallo " + pivot.Vorname + " " + pivot.Nachname + ","; + } + + return r; + } + }); + + preview.filter('filter', function () { + return function (x, y, z) { + var d = $.grep(x, function (v, i) { + return v[y] == z; + }); + return d; + } + }); + + quill.on('text-change', bP); + bP(); +}); + +$(window).on('hashchange', function () { + var r = $.grep(data, function (e) { + return (e.ruid == location.hash.substr(1) || e.RUID == location.hash.substr(1) || e.uid == location.hash.substr(1) || e.UID == location.hash.substr(1) || e.ID == location.hash.substr(1) || e.id == location.hash.substr(1)); + }); + pivot = r[0]; + bP(); +}); + +</script> + +<style> +::placeholder { + color: lightgrey; +} +.mand:placeholder-shown { + border: 1px solid red; + padding: 1px; +} +</style> + +<? +})(); +?> |
