generated from leonetienne/LaTeX-Paper-template
Compare commits
7 Commits
d1f6345306
...
151c2fa7d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
151c2fa7d7
|
|||
|
e8371e4a6c
|
|||
|
dc14ac7592
|
|||
|
12548fdf9d
|
|||
|
57061dc0c7
|
|||
|
85276999a3
|
|||
|
d18f0f197c
|
@@ -101,9 +101,8 @@ Die wichtigsten Erkenntnisse des Interviews sind:
|
|||||||
und in der Einzelansicht der \acp{JAP} sollen alle Weine aufgelistet sein, die dieser \ac{JAP} angehören.
|
und in der Einzelansicht der \acp{JAP} sollen alle Weine aufgelistet sein, die dieser \ac{JAP} angehören.
|
||||||
Diese Weine sind ebenso anklickbar und führen zu einer Einzelansicht der Weine.
|
Diese Weine sind ebenso anklickbar und führen zu einer Einzelansicht der Weine.
|
||||||
\item[Genaue Nutzerführung für Teilnehmer]\hfill\\
|
\item[Genaue Nutzerführung für Teilnehmer]\hfill\\
|
||||||
Die exakten Schritte, die ein Teilnehmer durchlaufen muss, um einen Prozess zu durchlaufen.
|
Die exakten Schritte, die ein Teilnehmer tätigen muss, um verschiedene Prozess zu durchlaufen.
|
||||||
Hierbei betrachten wir den Registrerungsprozess, um ein Teilnehmer zu werden und den Anmeldeprozess
|
Diese Prozesse sind detailliert in \fullref{chap:umsetzung} beschrieben.
|
||||||
eines Weines. Diese Prozesse sind detailliert in \fullref{chap:umsetzung} beschrieben.
|
|
||||||
\item[Nutzerführung für \ac{WM}-Angestellte]\hfill\\
|
\item[Nutzerführung für \ac{WM}-Angestellte]\hfill\\
|
||||||
Gescanne QR-Codes von Weinen sollen den Wein als eingegangen markieren und anschließend dem
|
Gescanne QR-Codes von Weinen sollen den Wein als eingegangen markieren und anschließend dem
|
||||||
Mitarbeiter zeigen, welcher Wein eingechecked wurde. Somit dient das Scannen eines Codes ebenso zur
|
Mitarbeiter zeigen, welcher Wein eingechecked wurde. Somit dient das Scannen eines Codes ebenso zur
|
||||||
|
|||||||
@@ -65,30 +65,30 @@ Unterkategorien \enquote{Trockener Riesling} und \enquote{Halbtrockener Riesling
|
|||||||
\enquote{Riesling}.
|
\enquote{Riesling}.
|
||||||
Rebsorten, Geschmack, Weineigenschaften und Qualität sollen eigene Datentypen
|
Rebsorten, Geschmack, Weineigenschaften und Qualität sollen eigene Datentypen
|
||||||
anstatt einfacher Zeichenfolgen sein.
|
anstatt einfacher Zeichenfolgen sein.
|
||||||
Ziel davon ist, dass sich Nutzer für einen vorgefertigten, nominalen Eintrag in einem Dropdown-Menü
|
Ziel dessen ist, dass sich Nutzer für einen vorgefertigten, nominalen Eintrag in einem Dropdown-Menü
|
||||||
entscheiden müssen und diese Auswahlmöglichkeiten immer noch im TYPO3-Backend pflegbar sind.
|
entscheiden müssen und diese Auswahlmöglichkeiten immer noch im TYPO3-Backend pflegbar sind.
|
||||||
Weinlagen sind im Brown-Field-Projekt bereits vorhanden, also sollen hierfür existierenden Daten
|
Weinlagen sind im Brown-Field-Projekt bereits vorhanden, also sollen hierfür existierenden Daten
|
||||||
eingebunden werden.
|
eingebunden werden.
|
||||||
Pro Wein sollen beliebig viele Weineigenschaften auswählbar sein, Wettbewerbskategorien,
|
Je Wein sollen beliebig viele Weineigenschaften auswählbar sein, Wettbewerbskategorien,
|
||||||
Geschmacksrichtung, etc, jeweils nur ein Element.
|
Geschmacksrichtung, etc, jeweils nur ein Element.
|
||||||
Weitere Notizen zu diesem Gespräch sind im Anhang unter \fullref{chap:anhang-notizen-digitization}
|
Weitere Notizen zu diesem Gespräch sind im Anhang unter \fullref{chap:anhang-notizen-digitization}
|
||||||
zu finden.
|
zu finden.
|
||||||
\\
|
\\
|
||||||
\\
|
\\
|
||||||
Da das Klassendiagramm gegeben lesbare Schrift nicht auf eine Textseite passt,
|
Da das Klassendiagramm nicht auf eine Textseite passt,
|
||||||
befindet es sich vollseitig im Anhang unter \fullref{chap:anhang-class-diagram}.
|
befindet es sich vollseitig im Anhang unter \fullref{chap:anhang-class-diagram}.
|
||||||
Die weitere Implementation der Datenobjekte ist unkompliziert und besteht hauptsächlich aus
|
Die weitere Implementation der Datenobjekte ist unkompliziert und besteht hauptsächlich aus
|
||||||
repetitivem Schreiben von SQL-Tabellen, Domain-Model-Klassen und \acp{TCA}.
|
repetitivem Schreiben von SQL-Tabellen, Domain-Model-Klassen und \acp{TCA}.
|
||||||
Um $m,n$-Beziehungen wie Beispielsweise der Menge der für eine Probe zugelassenen Kategorien
|
Um $m,n$-Beziehungen, wie beispielsweise der Menge der für eine Probe zugelassenen Kategorien
|
||||||
\enquote{allowedCategories} zwischen $m$ \enquote{Jahresauswahlprobe}-Objekten und
|
\enquote{allowedCategories}, zwischen $m$ \enquote{Jahresauswahlprobe}-Objekten und
|
||||||
$n$ \enquote{Category}-Objekten zu ermöglichen, werden MM-Tabellen (many-to-many) benötigt,
|
$n$ \enquote{Category}-Objekten zu ermöglichen, werden MM-Tabellen (many-to-many) benötigt,
|
||||||
diese Beziehungen in Form zweier Foreign Keys speichern.
|
um diese Beziehungen in Form zweier Foreign Keys zu speichern.
|
||||||
Die Repository-Klassen können \enquote{leer} gelassen werden,
|
Die Repository-Klassen können \enquote{leer} gelassen werden,
|
||||||
da zu diesem Zeitpunkt keine erweiterte Auswahllogik für Datenbankanfragen benötigt wird.
|
da zu diesem Zeitpunkt keine erweiterte Auswahllogik für Datenbankanfragen benötigt wird.
|
||||||
Wichtig ist hierbei, dass eine Repository-Klasse existiert. Alle unverzichtbaren
|
Wichtig ist hierbei, dass eine Repository-Klasse existiert. Alle unverzichtbaren
|
||||||
Schnittstellen werden über die Basisklasse \enquote{Repository} geerbt
|
Schnittstellen werden über die Basisklasse \enquote{Repository} geerbt
|
||||||
\cite{bib:typo3-docs-extdev-tut-tea-repositories}.
|
\cite{bib:typo3-docs-extdev-tut-tea-repositories}.
|
||||||
Mit Abschluss der Digitization können alle Datenstrukturen im TYPO3-Backend händisch angelegt,
|
Mit Abschluss der Phase der Digitization können alle Datenstrukturen im TYPO3-Backend händisch angelegt,
|
||||||
eingesehen, gelöscht und bearbeitet werden.
|
eingesehen, gelöscht und bearbeitet werden.
|
||||||
|
|
||||||
|
|
||||||
@@ -119,8 +119,8 @@ Der mit dem \ac{PO} ausgearbeitete UX-Flow der Registrierung sieht vor, dass der
|
|||||||
ob er Mitglied sei oder nicht. Hierzu gibt es je einen Button. Ist der Nutzer ein Mitglied,
|
ob er Mitglied sei oder nicht. Hierzu gibt es je einen Button. Ist der Nutzer ein Mitglied,
|
||||||
wird er auf ein Loginform, mit der Option zur Registrierung weitergeleitet.
|
wird er auf ein Loginform, mit der Option zur Registrierung weitergeleitet.
|
||||||
Nach erfolgreichem Login, wird ein Teilnehmerobjekt erstellt.
|
Nach erfolgreichem Login, wird ein Teilnehmerobjekt erstellt.
|
||||||
Wählt der Nutzer \enquote{Nein, ich bin kein Mitglied} aus, würde er auf ein Registrierungsformular
|
Wählt der Nutzer \enquote{Nein, ich bin kein Mitglied} aus, wird er auf ein Registrierungsformular
|
||||||
weitergeleitet, auf um sich einen Nicht-Mitgliederaccount anzulegen. Im Zuge dieser Registrierung werden
|
weitergeleitet, um einen Nicht-Mitgliederaccount anzulegen. Im Zuge dieser Registrierung werden
|
||||||
Stammdaten zum Weingut angefragt.
|
Stammdaten zum Weingut angefragt.
|
||||||
Dieser Schritt übersetzt unter anderem den \enquote{Einreicher}-Teil des ursprünglichen Anmeldeformulares,
|
Dieser Schritt übersetzt unter anderem den \enquote{Einreicher}-Teil des ursprünglichen Anmeldeformulares,
|
||||||
anbei in \fullref{chap:anhang-anmeldeformular}.
|
anbei in \fullref{chap:anhang-anmeldeformular}.
|
||||||
@@ -138,7 +138,6 @@ werden auf diese Lösungen zurückgegriffen, um einen einheitlichen Workflow bei
|
|||||||
Frontend-Nutzer-Login gelöst werden. Das ist explizit von femanager so angedacht:
|
Frontend-Nutzer-Login gelöst werden. Das ist explizit von femanager so angedacht:
|
||||||
\quotecite{Note: Login and a I forgot my password function is part of the core and not part of femanager.}
|
\quotecite{Note: Login and a I forgot my password function is part of the core and not part of femanager.}
|
||||||
\cite{bib:typo3-docs-femanager}.
|
\cite{bib:typo3-docs-femanager}.
|
||||||
|
|
||||||
Im Folgenden wird der Registrierungsprozess im Detail beschrieben:\\
|
Im Folgenden wird der Registrierungsprozess im Detail beschrieben:\\
|
||||||
Grundlegend gibt es drei relevante Nutzerzustände vor der Registrierung:
|
Grundlegend gibt es drei relevante Nutzerzustände vor der Registrierung:
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
@@ -167,7 +166,7 @@ Teilnehmer-Eintrag für den Frontend-Nutzer und fügt den Frontend-Nutzer der Nu
|
|||||||
Damit ist die Teilnehmerregistrierung abgeschlossen.
|
Damit ist die Teilnehmerregistrierung abgeschlossen.
|
||||||
|
|
||||||
\subsubsection*{Mitglied, ohne Konto}
|
\subsubsection*{Mitglied, ohne Konto}
|
||||||
Ist ein Nutzer ein Mitglied und hat noch kein Mitgliedskonto, muss dieser auf der Registrierungsseite
|
Ist ein Nutzer ein Mitglied, hat aber kein Mitgliedskonto, muss dieser auf der Registrierungsseite
|
||||||
\enquote{Ich bin ein Mitglied} auswählen. An dieser Stelle navigiert der Browser zu einem Login-Formular.
|
\enquote{Ich bin ein Mitglied} auswählen. An dieser Stelle navigiert der Browser zu einem Login-Formular.
|
||||||
Auf diesem Login-Formular existiert ein Button \enquote{Jetzt registrieren}, sowie ein Hinsweistext dazu.
|
Auf diesem Login-Formular existiert ein Button \enquote{Jetzt registrieren}, sowie ein Hinsweistext dazu.
|
||||||
Da der Nutzer noch keinen Account hat, muss dieser auf \enquote{Jetzt registrieren} klicken.
|
Da der Nutzer noch keinen Account hat, muss dieser auf \enquote{Jetzt registrieren} klicken.
|
||||||
@@ -180,34 +179,34 @@ freigegeben und es öffnet sich ein Login-Formular, beschrieben in \enpointy{Mit
|
|||||||
Zunächst wurde ein simples Weichen-Content-Element erstellt.
|
Zunächst wurde ein simples Weichen-Content-Element erstellt.
|
||||||
Dieses Content-Element hat die Parameter \enquote{question}, \enquote{answ-1-link}, \enquote{answ-1-text},
|
Dieses Content-Element hat die Parameter \enquote{question}, \enquote{answ-1-link}, \enquote{answ-1-text},
|
||||||
\enquote{answ-2-link} sowie \enquote{answ-2-text}.
|
\enquote{answ-2-link} sowie \enquote{answ-2-text}.
|
||||||
Der Zweck dieses Content-Elementes ist es, Nutzer basierend auf einer ausformilierten Frage auf eine
|
Der Zweck dieses Content-Elementes ist es, Nutzer basierend auf einer ausformulierten Frage auf eine
|
||||||
von zwei Seiten weiterzuleiten. Anschließend wurden Registrierungen über Femanager-Plugin-Content-Elemente
|
von zwei Seiten weiterzuleiten. Anschließend wurden Registrierungen über Femanager-Plugin-Content-Elemente
|
||||||
realisiert.
|
realisiert.
|
||||||
Anpassungen der versendeten Emails erfolgen durch Überschreiben der Email-Templates von Femanager.
|
Anpassungen der versendeten Emails erfolgen durch Überschreiben der Email-Templates von Femanager.
|
||||||
Weiterleitungen zu bestimmten Seiten nachdem ein Nutzer spezielle Events ausgelöst hat können über TypoScript
|
Weiterleitungen zu bestimmten Seiten, nachdem ein Nutzer spezielle Events ausgelöst hat, können über TypoScript
|
||||||
konfiguriert werden \cite{bib:typo3-docs-femanager}. Logins werden über das TYPO3-Native Loginformular
|
konfiguriert werden \cite{bib:typo3-docs-femanager}. Logins werden über das TYPO3-Native Loginformular
|
||||||
gelöst. Im TYPO3-Loginformular kann man Weiterleitungen zu spezialisierten Seiten im Backend-UI festlegen
|
gelöst. Im TYPO3-Loginformular können Weiterleitungen zu spezialisierten Seiten im Backend-UI festgelegt werden.
|
||||||
\cite{bib:typo3-docs-felogin}.
|
\cite{bib:typo3-docs-felogin}.
|
||||||
Für alle funktionalen Belange wurde ein TYPO3-Plugin registriert. Dieses Plugin verfügt über einen
|
Für alle funktionalen Belange wird ein TYPO3-Plugin registriert. Dieses Plugin verfügt über einen
|
||||||
ActionController, der Nutzeranfragen an PHP-Funktionen (\enquote{Actions})
|
ActionController, der Nutzeranfragen an PHP-Funktionen (\enquote{Actions})
|
||||||
bindet.
|
bindet.
|
||||||
In diesen Actions wird Fehlerbehandlung durchgeführt, Datenmodelle der Domäne erstellt und in der
|
In diesen Actions werden Fehlerbehandlungen durchgeführt, Datenmodelle der Domäne erstellt und in der
|
||||||
Datenbank persistiert sowie Daten für die Anzeige im Frontend aufbereitet \cite{bib:typo3-docs-extbase}.
|
Datenbank persistiert, sowie Daten für die Anzeige im Frontend aufbereitet \cite{bib:typo3-docs-extbase}.
|
||||||
Neue Datenobjekte werden in Repositories registriert \cite{bib:typo3-docs-extdev-tut-tea-repositories}. Diese Repositories sind Aggregate des Controllers,
|
Neue Datenobjekte werden in Repositories registriert \cite{bib:typo3-docs-extdev-tut-tea-repositories}. Diese Repositories sind Aggregate des Controllers,
|
||||||
werden jedoch nach dem \enquote{Inversion of Control}-Prinzip via Dependency Injection instanziiert und
|
werden jedoch nach dem \enquote{Inversion of Control}-Prinzip via Dependency Injection instanziiert und
|
||||||
der ActionController-Klasse über Methode übergeben \cite{bib:typo3-docs-di}.
|
der ActionController-Klasse über Methode übergeben \cite{bib:typo3-docs-di}.
|
||||||
Als problematisch erweisen sich bidirektionale Verbindungen zwischen Datenmodellen, wenn die Foreign Keys
|
Als problematisch erweisen sich hierbei bidirektionale Verbindungen zwischen Datenmodellen, wenn die Foreign Keys
|
||||||
über das SQL-Schlüsselwort \enquote{AUTO\_INCREMENT} in der Datenbank definiert werden.
|
über das SQL-Schlüsselwort \enquote{AUTO\_INCREMENT} in der Datenbank generiert werden.
|
||||||
In diesem Fall wollen wir
|
Beispielsweise, muss ein MasterRecord, der Betriebsinformationen speichert, bidirektional an ein Teilnehmerobjekt
|
||||||
einen MasterRecord, der Betriebsinformationen speichert, bidirektional an ein Teilnehmerobjekt linken.
|
gebunden werden. Hierzu wird jedem der Elemente jeweils der Foreign Key des anderen übergeben.
|
||||||
Als ForeignKeys werden hierfür ihre jeweiligen Uids herangezogen, da diese Werte durch
|
Als Foreign Keys werden hierfür die jeweiligen \acp{UID} herangezogen, da diese Werte durch
|
||||||
\enquote{AUTO\_INCREMENT} auf der Datenbankebene gehandhabt werden.
|
\enquote{AUTO\_INCREMENT} auf der Datenbankebene erzeugt werden und garantiert einzigartig je Datenbanktabelle sind
|
||||||
Es gilt also, dass ein MasterRecord $a$ die TeilnehmerUid von einem Teilnehmer $b$ hält und dass
|
\cite{bib:w3schools-auto-increment}.
|
||||||
$b$ die MasterRecordUid von $a$ hält.
|
Es gilt also, dass ein MasterRecord $a$ die Teilnehmer\ac{UID} von einem Teilnehmer $b$ hält und dass
|
||||||
Die Problematik hierbei ist, dass diese Uids erst nach dem persistieren in der Datenbank bekannt sind,
|
$b$ die MasterRecord\ac{UID} von $a$ hält.
|
||||||
da diese Werte erst im Zuge der Persistierung erstellt werden. Das ist so, da das
|
Die Problematik hierbei ist, dass diese \acp{UID} erst nach dem Persistieren in der Datenbank bekannt sind,
|
||||||
\enquote{AUTO\_INCREMENT}-Schlüsselwort lediglich zu SQL gehört und SQL nur von der Datenbank ausgeführt wird.
|
da diese Werte erst im Zuge der Persistierung erstellt werden \cite{bib:w3schools-auto-increment}.
|
||||||
Die Lösung hierfür ist es, beide Elemente zu erstellen und zu persistieren, danach ihre Uids gegenseitig
|
Die Lösung hierfür ist, beide Elemente zu erstellen und zu persistieren, erst danach ihre \acp{UID} gegenseitig
|
||||||
bekannt machen um sie danach erneut zu persistieren.
|
bekannt machen um sie danach erneut zu persistieren.
|
||||||
|
|
||||||
\subsection{Weinregistrierung}
|
\subsection{Weinregistrierung}
|
||||||
@@ -286,14 +285,15 @@ Damit sieht das Drop-Down-Menü aus wie eine Baumstruktur.
|
|||||||
Diese Herangehensweise erzeugt schlüssigen und lesbaren Programmcode und lässt sich unkompliziert umsetzen.
|
Diese Herangehensweise erzeugt schlüssigen und lesbaren Programmcode und lässt sich unkompliziert umsetzen.
|
||||||
Das senkt Entwicklungskosten und erhöht den Profit des Endkunden, da hierdurch weniger Zeit aufgewandt wird.
|
Das senkt Entwicklungskosten und erhöht den Profit des Endkunden, da hierdurch weniger Zeit aufgewandt wird.
|
||||||
Rekursiv aufgerufene For-Schleifen, die sich selbst erneut für alle Elemente aufrufen,
|
Rekursiv aufgerufene For-Schleifen, die sich selbst erneut für alle Elemente aufrufen,
|
||||||
können jedoch zu einem Performanzproblem führen \cite{bib:schwarzer-vorlesung-alg}.
|
können zu einem Performanzproblem führen \cite{bib:schwarzer-vorlesung-alg}.
|
||||||
Daher wird im Folgenden die Zeitkomplexität dieser Rekursionsfunktion betrachtet.
|
Daher wird im Folgenden die Zeitkomplexität dieser Rekursionsfunktion betrachtet.
|
||||||
Grundlegend, kann für diese Funktion kein Master-Theorem angewandt werden,
|
Grundlegend, kann für diese Funktion kein Master-Theorem angewandt werden,
|
||||||
da es sich hierbei nicht um einen Divide-and-Conquer-Algorithmus handelt \cite{bib:schwarzer-vorlesung-alg}.
|
da es sich hierbei nicht um einen Divide-and-Conquer-Algorithmus handelt.
|
||||||
Das ist so, da das in der Rekursion weitergereichte Problem nicht kleiner wird,
|
Das ist so, da das in der Rekursion weitergereichte Problem nicht kleiner wird,
|
||||||
sondern gleich groß bleibt.
|
sondern gleich groß bleibt.
|
||||||
Das verletzt die Bedingung $b>1$ des Master-Theorem, dargestellt als\\$T(n) = a*T(\frac{n}{b})+f(n)$.
|
Das verletzt die Bedingung $b>1$ des Master-Theorem, definiert als $T(n) = a*T(\frac{n}{b})+f(n)$
|
||||||
Betrachten wir den Algortihmus, besteht er aus $m, m \in \mathbb{N}$ verschachtelten For-Schleifen
|
\cite{bib:schwarzer-vorlesung-alg}.
|
||||||
|
Der Algortihmus besteht aus $m, m \in \mathbb{N}$ verschachtelten For-Schleifen
|
||||||
gleicher Länge.
|
gleicher Länge.
|
||||||
Somit ist die Zeitkomplexität $O(n^m)$. Normiert dargestellt beträgt die Zeitkomplexität $O(n^2)$. Das lässt sich experimentell bestätigen.
|
Somit ist die Zeitkomplexität $O(n^m)$. Normiert dargestellt beträgt die Zeitkomplexität $O(n^2)$. Das lässt sich experimentell bestätigen.
|
||||||
|
|
||||||
@@ -306,12 +306,12 @@ Somit ist die Zeitkomplexität $O(n^m)$. Normiert dargestellt beträgt die Zeitk
|
|||||||
|
|
||||||
|
|
||||||
Auf Optgroup-HTML-Tags wurde bewusst verzichtetet.
|
Auf Optgroup-HTML-Tags wurde bewusst verzichtetet.
|
||||||
Grund dafür ist, dass Optgroup-Titel an sich nicht als Option auswählbar sind.
|
Grund dafür ist, dass Optgroup-Elemente an sich nicht im Dropdown auswählbar sind.
|
||||||
Das stellt ein Problem dar, da beispielsweise die Kategorie \enquote{Riesling},
|
Das stellt ein Problem dar, da beispielsweise die Kategorie \enquote{Riesling},
|
||||||
die die Unterkategorien \enquote{Trockener Riesling} und \enquote{Halbtrockener Riesling} beinhalten könnte,
|
die die Unterkategorien \enquote{Trockener Riesling} und \enquote{Halbtrockener Riesling} beinhalten könnte,
|
||||||
auch direkt auswählbar sein sollte. Zudem besitzen Kategorie-Elemente kein Attribut das auf die Präsenz
|
auch direkt auswählbar sein sollte. Zudem besitzen Kategorie-Elemente kein Attribut das auf die Präsenz
|
||||||
von Unterkategorien hindeutet \cite{bib:typo3-docs-sys-category}, womit eine Unterscheidung zwischen
|
von Unterkategorien hindeutet \cite{bib:typo3-docs-sys-category}, womit eine Unterscheidung zwischen
|
||||||
Baumblättern und -Zweigen nicht ohne weiteres möglich ist. Diese Entscheidung wäre jedoch
|
Baumblättern und -Zweigen nicht ohne weiteres möglich wäre. Diese Entscheidung wäre jedoch
|
||||||
benötigt, um zwischen einem Optgroup-Tag und einem Option-Tag abzuwägen.
|
benötigt, um zwischen einem Optgroup-Tag und einem Option-Tag abzuwägen.
|
||||||
|
|
||||||
\paragraph*{SelectMultiple} sind Formfelder, die dem Nutzer eine Auswahl aus $n$ Elementen aus einer anderen
|
\paragraph*{SelectMultiple} sind Formfelder, die dem Nutzer eine Auswahl aus $n$ Elementen aus einer anderen
|
||||||
@@ -329,10 +329,95 @@ Hierfür wird die eingebaute PHP-Funktion \enquote{array\_keys} verwendet. Diese
|
|||||||
Keys eines Arrays in Form eines numerisch indizierten Arrays zurück.
|
Keys eines Arrays in Form eines numerisch indizierten Arrays zurück.
|
||||||
Der optionale Parameter \enquote{filter\_values} bestimmt, dass ausschließlich die Keys
|
Der optionale Parameter \enquote{filter\_values} bestimmt, dass ausschließlich die Keys
|
||||||
der Key-Value-Pairs, die einen bestimmten
|
der Key-Value-Pairs, die einen bestimmten
|
||||||
Wert tragen, extrahiert werden. D.h., der Funktionsaufruf filtert alle Keys und somit alle Formfeld-IDs des Formfeldparameter-Arrays heraus, die den Wert \enquote{<formfeldname>-true} haben. Das ist eine Liste
|
Wert tragen, extrahiert werden \cite{bib:php-array-keys}. D.h., der Funktionsaufruf filtert alle Keys und somit alle
|
||||||
|
Formfeld-IDs des Formfeldparameter-Arrays heraus, die den Wert \enquote{<formfeldname>-true} haben. Das ist eine Liste
|
||||||
aller Formfeld-IDs der Checkboxen des SelectMultiples, die angehakt wurden.
|
aller Formfeld-IDs der Checkboxen des SelectMultiples, die angehakt wurden.
|
||||||
Mit der eingebauten PHP-Funktion \enquote{array\_map} wenden wir nun eine Operation auf alle Schlüssel
|
Mit der eingebauten PHP-Funktion \enquote{array\_map} wird nun eine Operation auf alle Schlüssel
|
||||||
der Liste an, die \enquote{strlen('formfeldname-')} Zeichen, von links ausgehend, von der Formfeld-ID
|
der Liste angewandt, die \enquote{strlen('formfeldname-')} Zeichen, von links ausgehend, von der Formfeld-ID
|
||||||
entfernt. Somit wird beispielsweise die Formfeld-ID \enquote{winekind-18} zu \enquote{18} transformiert. Übrig bleiben die \acp{UID} aller angehakten Elemente $a$, in Form einer Zeichenkente.
|
entfernt. Somit wird beispielsweise die Formfeld-ID \enquote{winekind-18} zu \enquote{18} transformiert. Übrig bleiben die \acp{UID} aller angehakten Elemente $a$, in Form einer Zeichenkente.
|
||||||
Über die eingebaute PHP-Funktion \enquote{intval} ist es trivial diese zu Zahlen zu übersetzen,
|
Über die eingebaute PHP-Funktion \enquote{intval} ist es trivial diese zu Zahlen zu übersetzen,
|
||||||
wodurch die tatsächlichen Objekte aus der Datenbank angefragt werden können.
|
wodurch die tatsächlichen Objekte aus der Datenbank angefragt werden können.
|
||||||
|
|
||||||
|
\subsection{PDF- und QR-Code-Generierung}
|
||||||
|
Das dynamische Erstellen und Ausgeben des Versandbeilageblattes als PDF ist ein essenzieller Bestandteil des
|
||||||
|
Jahresauswahlprobenwerkzeuges, da dieses PDF die Schnittstelle zwischen ankommenden Weinen und dem System darstellt.
|
||||||
|
Daher ist der Profit, der durch dieses Werkzeug generiert wird, ohne dieses PDF stark eingeschränkt, da
|
||||||
|
einkommende Weine händisch, von Mitarbeitern, zugeordnet werden müssten.
|
||||||
|
Wie im \fullref{chap:stand-der-forschung} erläutert, werden für die dynamische
|
||||||
|
Generierung dieses PDFs die Bibliotheken \enquote{chillerlan/php-qrcode} und
|
||||||
|
\enquote{mpdf/mpdf} herangezogen und über Composer installiert.
|
||||||
|
|
||||||
|
\subsubsection{QR-Code-Generierung}
|
||||||
|
Der QR-Code beinhaltet lediglich die Wein-\ac{UID} anstatt einer vollständigen URL. Hintergrund dessen ist, dass
|
||||||
|
die URL, die benötigt ist, um einen Wein einzuscannen, bis auf die Wein-\ac{UID} immer identisch ist.
|
||||||
|
Somit wird redundanz vermieden.
|
||||||
|
Es ist Aufgabe der QR-Code-App, die den Code einscannt, aus der Wein-\ac{UID} eine vollständige URL herzuleiten.
|
||||||
|
Um Resourcen zu sparen und somit den Profit zu erhöhen, wird der QR-Code zu einem Base64-kodiertem Bild gerendert.
|
||||||
|
Das ist der Standardrückgabewert des QR-Code-Generators
|
||||||
|
und erfordert somit keine nähere Konfiguration. Ebenfalls lässt sich ein Base64-kodiertes Bild als Quellurl eines
|
||||||
|
IMG-HTML-Tags angeben, womit das Bild eingebettet ist. Hier wird der Profit erhöht, indem Arbeitszeit gespart wird,
|
||||||
|
die sonst in das anderweitige Einbetten eines Bildes in einem PDF mit \enquote{mpdf} fließen müsste.
|
||||||
|
Die QR-Codegenerierung funktioniert konkret, indem ein neues QRCode-Objekt der QRCode-Klasse erstellt wird.
|
||||||
|
Diese Klasse nimmt ein QROptions-Objekt im Konstruktor, das in diesem Falle einige Stilattribute mit sich trägt.
|
||||||
|
Das QRCode-Objekt bietet nun eine Methode \enquote{render} an, die, sofern nicht anders konfiguriert, den QR-Code als
|
||||||
|
Base64-kodiertes Bild zurückgibt \cite{bib:chillerlan-php-qrcode}.
|
||||||
|
|
||||||
|
\subsubsection{PDF-Generierung}
|
||||||
|
Firmenintern ist es Standard das Aussehen sowie die Inhalte der PDF-Dokumente, die \enquote{mpdf} erzeugt, mit HTML zu definieren,
|
||||||
|
das an \enquote{mpdf} gereicht wird. Um die Gestaltung und die Präsentation von Variablen in der HTML-Zeichenfolge technisch
|
||||||
|
kontinuierlich mit dem restlichen Projekt zu halten und um eine gute Wartbarkeit zu gewährleisten,
|
||||||
|
wird diese HTML-Zeichenfolge mit TYPO3-Fluid getemplated. Das heißt, dass eine HTML-Templatedatei bereitgestellt wird,
|
||||||
|
diese mit TYPO3-Fluid befüllt wird und in PHP gerendert wird, um eine HTML-Zeichenkette als Ergebnis zu erhalten.
|
||||||
|
Hierfür wird ein TYPO3-StandaloneView des instanziiert, mit einem Pfad zur Template-Datei ausgestattet, Variablen angegeben,
|
||||||
|
die in Fluid verfügbar sein sollen und anschließend über die \enquote{render}-Methode zu einem String gerendert
|
||||||
|
\cite{bib:typo3-ref-standalone-view}.
|
||||||
|
Anschließend wird ein \enquote{mpdf}-Objekt erstellt und mit einer rudimentären Konfiguration in Form eines Arrays im Konstruktor
|
||||||
|
konfiguriert. Diese Konfiguration definiert in diesem Falle Seitenabstände, Papierformat, Zeichenkodierung und Schriftarten.
|
||||||
|
Abschließend wird dem \enquote{mpdf}-Objekt das zuvor generierte HTML übergeben und über die Methode \enquote{OutputBinaryData}
|
||||||
|
als Bytes zurückgegeben und in einer Variable gespeichert \cite{bib:mpdf-ref}.
|
||||||
|
Um dieses PDF-Dokument über die Verbindung an den Nutzer zu übertragen, wird ein TYPO3-Response-Objekt erstellt.
|
||||||
|
Über dieses Response-Objekt werden einige Header gesetzt und direkt übertragen. Dieser Header sind Content-Type und Content-Length.
|
||||||
|
Abschließend werden als Response-Body die Bytes des generierten PDFs abgeschickt. Damit ist die Verbindung beendet und das
|
||||||
|
PDF zum Nutzer übertragen.
|
||||||
|
|
||||||
|
\subsection{Schnittstelle QR-Code-Scanner}
|
||||||
|
Es ist angedacht, dass Mitarbeiter über die App \enquote{QRBot} den QR-Code auf dem Einlieferungsschein einscannen.
|
||||||
|
Diese App ermöglicht es Nutzern für jeden eingescannten Code eine URL zu öffnen und den Wert des QR-Codes anstelle eines Platzhalters
|
||||||
|
in der URL einzufügen.
|
||||||
|
Hierfür bietet das Jahresauswahlprobenwerkzeug eine Schnittstelle bzw. eine Seite an, die eine Wein-\ac{UID} als
|
||||||
|
URL-kodierten GET-Parameter annimmt und diesen Wein als \enquote{eingegangen} markiert.
|
||||||
|
Um sicherzustellen, dass Weine nicht unautorisiert markiert werden, müssen sich Mitarbeiter mit einem Nutzerkonto
|
||||||
|
authentifizieren. Dieses Nutzerkonto muss Teil einer Mitarbeiter-Nutzergruppe sein.
|
||||||
|
Das Nutzerkonto wird von Redakteuren oder Administratoren im TYPO3-Backend erstellt und benötigt keiner Registrierung.
|
||||||
|
Nach einer Anmeldung bleibt diese Sitzung aktiv und verfällt erst nach längerer Inaktivität.
|
||||||
|
Wird ein Wein als \enquote{eingegangen} markiert, wird der betroffene Teilnehmer per Email informiert.
|
||||||
|
Hierzu wird die FluidEmail-Klasse des TYPO3-Cores herangezogen.
|
||||||
|
Sollte ein Wein bereits als \enquote{eingegangen} markiert sein, wird keine Email verschickt und dem Mitarbeiter wird kommuniziert,
|
||||||
|
dass keine Änderungen vorgenommen wurden.
|
||||||
|
Abschließend werden im Frontend allgemeine Daten über den Wein angezeigt, damit Mitarbeiter sich sicher sein können,
|
||||||
|
den richtigen Wein eingescanned zu haben.
|
||||||
|
|
||||||
|
\subsection{Jahresauswahlproben- und Wein-Detailansichten}
|
||||||
|
Weine und Jahresauswahlproben sollen unter bestimmten Gegebenheiten einsichtig sein.
|
||||||
|
Hierzu gibt es eine Auflistung aller Jahresauswahlproben. Diese sind anklickbar, um eine Detailansicht der ausgewählten
|
||||||
|
Jahresauswahlprobe zu öffnen. Hier wird neben Metadaten der Jahresauswahlprobe eine Liste aller zur Einsicht berechtiger Weine
|
||||||
|
angezeigt. Diese Weine sind anklickbar, um auf eine Detailansicht der Weine zu gelangen.
|
||||||
|
Die Detailansichten für Jahresauswahlproben und Weine benötigen spezieller Autorisierung.
|
||||||
|
Diese sind: Jahresauswahlproben sind nur einsichtig, wenn sich das aktuelle Datum innerhalb des
|
||||||
|
Sichtbarkeitszeitraumes der Jahresauswahlprobe befindet.
|
||||||
|
Detailansichten für Weine sind immer für den zugehörigen Teilnehmer einsichtig.
|
||||||
|
Nach Abschluss einer Jahresauswahlprobe sind alle ihr angehörigen Weine öffentlich einsichtig.
|
||||||
|
Das hat den Hintergrund, dass Jahresauswahlproben Blindverkostungen sind
|
||||||
|
und niemand die Möglichkeit haben sollte, im Voraus Informationen über die teilnehmenden Weine in Erfahrung zu bringen.
|
||||||
|
Die Ergebnisse der Jahresauswahlproben sind öffentlich, also sind es die Weine nach Abschluss einer \ac{JAP} auch.
|
||||||
|
Mitarbeiter von Weinland Mosel, wenn mit einem solchen Account angemeldet, haben immer Einsicht in Wein-Detailansichten.
|
||||||
|
Die Wein-Detailseite verfügt außerdem über einen \enquote{Versandetikett drucken}-Button, der auf das Versand-PDF verlinkt.
|
||||||
|
Dieser Button ist nur für den zugehörigen Teilnehmer und Mitarbeiter verfügbar.
|
||||||
|
Diese Daten, Fakten und Restriktionen werden serverseitig kontrolliert, um Manipulationen des Nutzers auszuschließen.
|
||||||
|
Um das zu realisieren werden Daten mit Fluid-Templates konditionell dargestellt und über Fluid-ViewHelper Links
|
||||||
|
zu anderen Ansichten generiert. Diese ViewHelper übergeben Parameter. Die hierfür relevanten Parameter der verschiedenen
|
||||||
|
Ansichten sind beispielsweise Wein-\acp{UID} und \ac{JAP}-\acp{UID}. Um Informationen über den angemeldeten Nutzer,
|
||||||
|
wie beispielsweise seiner Teilnehmernummer oder seiner Nutzergruppenzugehörigkeit, zu erlangen, wird sich
|
||||||
|
der Extbase-nativej Domain-Model-FrontendUser-Klasse bedient \cite{bib:typo3-ref-extbase-model-feuser}.
|
||||||
|
|
||||||
|
\subsection{CSV-Export}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
\newcommand{\cfgDocClassification}{Abschlussarbeit}
|
\newcommand{\cfgDocClassification}{Abschlussarbeit}
|
||||||
|
|
||||||
% Document version
|
% Document version
|
||||||
\newcommand{\cfgDocVersion}{1.3}
|
\newcommand{\cfgDocVersion}{1.5}
|
||||||
|
|
||||||
% Last modification date
|
% Last modification date
|
||||||
\newcommand{\cfgDateLastModification}{22. Dezember 2022}
|
\newcommand{\cfgDateLastModification}{22. Dezember 2022}
|
||||||
|
|||||||
@@ -162,6 +162,15 @@
|
|||||||
note = {Zugriff: Januar 2023}
|
note = {Zugriff: Januar 2023}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@misc{bib:w3schools-auto-increment,
|
||||||
|
author = {{W3Schools}},
|
||||||
|
howpublished = "\url{https://www.w3schools.com/sql/sql_autoincrement.asp}",
|
||||||
|
title = {{SQL AUTO INCREMENT Field}},
|
||||||
|
year = {2023},
|
||||||
|
note = {Zugriff: März 2023}
|
||||||
|
}
|
||||||
|
|
||||||
@misc{bib:larsjung-jquery-qrcode,
|
@misc{bib:larsjung-jquery-qrcode,
|
||||||
author = {Lars Jung},
|
author = {Lars Jung},
|
||||||
howpublished = "\url{https://github.com/lrsjng/jquery-qrcode/blob/master/README.md}",
|
howpublished = "\url{https://github.com/lrsjng/jquery-qrcode/blob/master/README.md}",
|
||||||
@@ -319,6 +328,14 @@
|
|||||||
note = {Zugriff: März 2023}
|
note = {Zugriff: März 2023}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{bib:mpdf-ref,
|
||||||
|
author = {{Mpdf Contributors}},
|
||||||
|
howpublished = "\url{https://mpdf.github.io/reference/mpdf-functions/overview.html}",
|
||||||
|
title = {{Overview mPDF Functions by Category}},
|
||||||
|
year = {2023},
|
||||||
|
note = {Zugriff: März 2023}
|
||||||
|
}
|
||||||
|
|
||||||
@misc{bib:qrbot,
|
@misc{bib:qrbot,
|
||||||
author = {{TeaCapps}},
|
author = {{TeaCapps}},
|
||||||
howpublished = "\url{https://qrbot.net}",
|
howpublished = "\url{https://qrbot.net}",
|
||||||
@@ -335,6 +352,14 @@
|
|||||||
note = {Zugriff: März 2023}
|
note = {Zugriff: März 2023}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{bib:php-array-keys,
|
||||||
|
author = {{The PHP Group}},
|
||||||
|
howpublished = "\url{https://www.php.net/manual/en/function.array-keys.php}",
|
||||||
|
title = {{PHP: array-keys - Manual}},
|
||||||
|
year = {2023},
|
||||||
|
note = {Zugriff: März 2023}
|
||||||
|
}
|
||||||
|
|
||||||
@misc{bib:typo3-fluid,
|
@misc{bib:typo3-fluid,
|
||||||
author = {{TYPO3 Association}},
|
author = {{TYPO3 Association}},
|
||||||
howpublished = "\url{https://typo3.org/fluid}",
|
howpublished = "\url{https://typo3.org/fluid}",
|
||||||
@@ -438,3 +463,19 @@
|
|||||||
year = {2023},
|
year = {2023},
|
||||||
note = {Zugriff: März 2023}
|
note = {Zugriff: März 2023}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{bib:typo3-ref-standalone-view,
|
||||||
|
author = {{TYPO3 Contributors}},
|
||||||
|
howpublished = "\url{https://api.typo3.org/10.4/class_t_y_p_o3_1_1_c_m_s_1_1_fluid_1_1_view_1_1_standalone_view.html}",
|
||||||
|
title = {{TYPO3\\CMS\\Fluid\\View\\StandaloneView Class Reference}},
|
||||||
|
year = {2023},
|
||||||
|
note = {Zugriff: März 2023}
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{bib:typo3-ref-extbase-model-feuser,
|
||||||
|
author = {{TYPO3 Contributors}},
|
||||||
|
howpublished = "\url{https://api.typo3.org/10.4/class_t_y_p_o3_1_1_c_m_s_1_1_extbase_1_1_domain_1_1_model_1_1_frontend_user.html}",
|
||||||
|
title = {{TYPO3\\CMS\\Extbase\\Domain\\Model\\FrontendUser Class Reference}},
|
||||||
|
year = {2023},
|
||||||
|
note = {Zugriff: März 2023}
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 312 KiB |
@@ -156,6 +156,8 @@ class Jahresauswahlprobe #IMPLEMENTED_COLOR {
|
|||||||
-dateAllowRegistration_end: Date
|
-dateAllowRegistration_end: Date
|
||||||
-dateAllowShow_start: Date
|
-dateAllowShow_start: Date
|
||||||
-dateAllowShow_end: Date
|
-dateAllowShow_end: Date
|
||||||
|
-date_start: Date
|
||||||
|
-date_end: Date
|
||||||
+getAllowedCategories(): List<Category>
|
+getAllowedCategories(): List<Category>
|
||||||
+setAllowedCategories(allowedCategories: List<Category>): void
|
+setAllowedCategories(allowedCategories: List<Category>): void
|
||||||
+getName(): String
|
+getName(): String
|
||||||
@@ -170,6 +172,10 @@ class Jahresauswahlprobe #IMPLEMENTED_COLOR {
|
|||||||
+setDateAllowShowStart(dateAllowShowStart: Date): void
|
+setDateAllowShowStart(dateAllowShowStart: Date): void
|
||||||
+getDateAllowShowEnd(): Date
|
+getDateAllowShowEnd(): Date
|
||||||
+setDateAllowShowEnd(dateAllowShowEnd: Date): void
|
+setDateAllowShowEnd(dateAllowShowEnd: Date): void
|
||||||
|
+getDateStart(): Date
|
||||||
|
+setDateStart(dateStart: Date): void
|
||||||
|
+getDateEnd(): Date
|
||||||
|
+setDateEnd(dateEnd: Date): void
|
||||||
+getUid(): Int
|
+getUid(): Int
|
||||||
+setUid(uid: Int): void
|
+setUid(uid: Int): void
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user