feat: probelesen korrektur

This commit is contained in:
2023-03-29 19:07:27 +02:00
parent c0d8984cf4
commit eff6248883
13 changed files with 203 additions and 189 deletions

View File

@@ -2,31 +2,31 @@
\label{chap:umsetzung}
Infolge der Anforderungsanalyse befasst sich das Kapitel \enquote{Konzeption und Umsetzung}
mit der Implementation der Anforderungen in dem
Brown-Field Projekt \cite{bib:schwarzer-vorlesung-swa} in Form einer TYPO3-Extension.
Brown-Field Projekt \cite{bib:schwarzer-vorlesung-swa} in Form einer TYPO3-Erweiterung.
Es ist anzumerken, dass das aus \fullref{chap:anforderungserfassung} hervorgehende Pflichtenheft im Rahmen geplanter und
opportunistischer Gespräche mit dem \ac{PO} geringfügige Änderungen erfahren hat.
opportunistischer Gespräche mit dem \ac{PO} geringfügige Änderungen erfahren wird.
\section{Setup einer TYPO3-Extension}
TYPO3-Extensions werden via Composer installiert \break\cite{bib:typo3-docs-managing-extensions}.
Um eine TYPO3-Extension zu erstellen, muss also ein Composer-Paket erstellt werden.
\section{Setup einer TYPO3-Erweiterung}
TYPO3-Erweiterungs werden via Composer installiert \break\cite{bib:typo3-docs-managing-extensions}.
Um eine TYPO3-Erweiterung zu erstellen, muss also ein Composer-Paket erstellt werden.
Um vermeidbare Komplexität zu verhindern, wird das Composer-Paket, welches die hier betrachtete
TYPO3-Extension darstellt, lokal in den versionierten Ordner \enquote{packages} gelegt.
TYPO3-Erweiterung darstellt, lokal in den versionierten Ordner \enquote{packages} gelegt.
Dieses Verzeichnis wird als Quelle für Composer-Pakete in der
Haupt-composer.json-Datei hinterlegt.
Somit wird ein Composer-Paket nur für dieses Projekt bereitgestellt,
ohne den Aufwand zu betreiben, der üblicherweise mit dem Bereitstellen eines Paketes einhergeht.
\\
\\
Um das grundlegende Setup einer Extension effizient durchzuführen, wurde eine
existierende Extension mit vergleichbarem Funktionsumfang kopiert, umbenannt und eingefügt.
Spezifisch ist der \enquote{vergleichbare Funktionsumfang}, dass es Datenmodelle und hochpersonalisierte
Um das grundlegende Setup einer TYPO3-Erweiterung effizient durchzuführen, wurde eine
existierende Erweiterung mit vergleichbarem Funktionsumfang kopiert, umbenannt und eingefügt.
Spezifisch ist dieser \enquote{vergleichbare Funktionsumfang}, dass es ebenfalls Datenmodelle und hochpersonalisierte
Frontendlogik in Bezug auf die zuvor genannten Datenmodelle gibt.
\section{Digitization}
Die Phase der Digitizion nach Verhoef et al. befasst sich mit der digitalen Abbildung von Objekten aus der realen Welt
in einer Art und Weise, die ermöglicht, dass diese elektronisch weiterverarbeitet werden können\break\cite{bib:dougherty, bib:loebbecke}.
Des Weiteren befasst sich diese Phase mit der Automatisierung und Befüllung dieser Daten,
wie zum Beispiel Web-Formularen \cite{bib:verhoef}.
wie zum Beispiel durch Web-Formulare \cite{bib:verhoef}.
Das bedeutet, dass in dieser Phase Datenobjekte definiert und implementiert werden.
Ein Datenobjekt besteht nach firmeninternen Konventionen aus zumindest
vier Komponenten:
@@ -51,7 +51,7 @@ angefertigt und in Rücksprache mit dem \ac{PO} finalisiert.
\begin{nicepic}
\includegraphics[width=1\textwidth]{images/objektrelationen-weinlandmosel-einlieferungswerkzeug.png}
\captionof{figure}{Objektrelationen}
\caption*{Quelle: Eigene Darstellung}
\caption*{Quelle: Eigene Darstellung: Weinland Mosel Einlieferungswerkzeug}
\label{fig:objektrelationen}
\end{nicepic}
@@ -59,21 +59,21 @@ Nachdem in Erfahrung gebracht wurde, welche konkreten Datenobjekte benötigt wer
wurden Attribute dieser Objekte dem Pflichtenheft entnommen. Diese wurden in einem
formalen Klassendiagramm festgehalten und in Rücksprache mit dem \ac{PO}
weiter bis zu festen Datentypen und Auswahlmöglichkeiten konkretisiert.
Beispielsweise, dass Wettbewerbskategorien durch TYPO3-Categories repräsentiert werden sollen.
Beispielsweise, dass Wettbewerbskategorien durch TYPO3-Categories repräsentiert werden.
Das hat den Vorteil, dass TYPO3-Categories bereits native Bestandteile eines TYPO3-Redaktionssystemes sind
und alle relevanten Attribute anbieten. Diese sind ein Titel,
eine Parentkategorie und eine Beschreibung.
und alle relevanten Attribute anbieten. Diese sind Titel,
Parentkategorie und Beschreibung.
Das Parent-Attribut ist benötigt, da $n$ dieser Attribute einen Attributbaum bilden
\cite{bib:typo3-docs-sys-category}.
Somit ist es möglich, Unterkategorien zu erstellen. Beispiele hierfür sind die
Unterkategorien \enquote{Trockener Riesling} und \enquote{Halbtrockener Riesling} für die Überkategorie
\enquote{Riesling}.
Rebsorten, Geschmack, Weineigenschaften und Qualität sollen eigene Datentypen
Rebsorten, Geschmack, Weineigenschaften und Qualität sollen eigene Datentypen,
anstatt einfacher Zeichenfolgen sein.
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 im TYPO3-Backend pflegbar sind.
Weinlagen sind im Brown-Field-Projekt bereits vorhanden, also sollen hierfür existierende Daten
eingebunden werden.
wiederverwendet werden.
Je Wein sollen beliebig viele Weineigenschaften auswählbar sein. Wettbewerbskategorien,
Geschmacksrichtung, etc, sind jeweils nur ein Element.
Weitere Notizen zu diesem Gespräch sind im Anhang unter \fullref{chap:anhang-notizen-digitization}
@@ -93,15 +93,11 @@ da zu diesem Zeitpunkt keine erweiterte Auswahllogik für Datenbankanfragen ben
Wichtig ist hierbei, dass eine Repository-Klasse existiert. Alle unverzichtbaren
Schnittstellen werden über die Basisklasse \enquote{Repository} geerbt
\cite{bib:typo3-docs-extdev-tut-tea-repositories}.
Mit Abschluss der Phase der Digitization können alle Datenstrukturen im TYPO3-Backend händisch angelegt,
eingesehen, gelöscht und bearbeitet werden.
\subsection{Teilnehmerregistrierung}
Ein essenzieller Teil des Jahresauswahlprobenwerkzeuges ist die Registrierung von Teilnehmern.
Dieses Modul repräsentiert den ersten Berührungspunkt der Winzer mit dem System.
Hiervon profitiert \ac{WM}, weil registrierte Benutzer der Webseite eine Grundvorausetzung
für die Onlineregistrierung von Weinen zu Jahresauswahlproben sind.
Dem Pflichtenheft ist zu entnehmen, dass es zwei Kategorien von Teilnehmerregistrierungen gibt:
\begin{enumerate}
\item Nutzer ist \ac{WM}-Mitglied
@@ -109,29 +105,29 @@ Dem Pflichtenheft ist zu entnehmen, dass es zwei Kategorien von Teilnehmerregist
\end{enumerate}
Der primäre Unterschied zwischen Mitgliedern und Nicht-Mitgliedern ist, dass Mitglieder bereits einen
Stammdatensatz hinterlegt haben.
Dieser Stammdatensatz bildet die Angaben zum Weingut des zu digitalisierendem Anmeldeformulares ab.
Dieser Stammdatensatz bildet die Angaben zum Weingut des zu digitalisierenden Anmeldeformulares ab.
Nicht-Mitglieder sind dem System noch gänzlich unbekannt und müssen im Zuge der Registrierung ihres Nutzers
ihre Stammdaten angeben, während sich Mitglieder lediglich einloggen müssen und eine Schaltfläche
\enquote{Teilnehmer werden} betätigen.
Der mit dem \ac{PO} ausgearbeitete UX-Flow der Registrierung sieht vor, dass der Nutzer zunächst gefragt wird,
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 Loginformular, mit der Option zur Registrierung weitergeleitet.
Nach erfolgreichem Login, wird ein Teilnehmerobjekt erstellt.
Wählt der Nutzer \enquote{Nein, ich bin kein Mitglied} aus, wird er auf ein Registrierungsformular
Wählt der Nutzer \enquote{Nein, ich bin kein Mitglied}, wird er auf ein Registrierungsformular
weitergeleitet, um einen Nicht-Mitgliederaccount anzulegen. Im Zuge dieser Registrierung werden
Stammdaten zum Weingut angefragt.
Dieser Schritt übersetzt unter anderem den \enquote{Einreicher}-Teil des ursprünglichen Anmeldeformulares,
anbei in \fullref{chap:anhang-anmeldeformular}.
\begin{nicepic}
\includegraphics[width=0.9\textwidth]{images/ux-flow-registrierung.png}
\includegraphics[width=0.6\textwidth]{images/ux-flow-registrierung.png}
\captionof{figure}{UX-Flow: Registrierung}
\caption*{Quelle: Eigene Darstellung}
\label{fig:uxflow-registrierung}
\end{nicepic}
Da das Brown-Field-Projekt bereits Accountlogins und -registrierungen implementiert und nutzt,
werden auf diese Lösungen zurückgegriffen, um einen einheitlichen Workflow beizubehalten.
wird auf diese Lösungen zurückgegriffen, um einen einheitlichen Workflow beizubehalten.
Accountregistrierungen werden über den
\enquote{femanager} \cite{bib:typo3-docs-femanager} realisiert, während Logins via TYPO3s nativem
Frontend-Nutzer-Login gelöst werden. Das ist explizit von \enquote{femanager} so angedacht:
@@ -152,7 +148,7 @@ Diese Prozesse sehen wie folgt aus:
Ist ein Nutzer kein Mitglied, so muss er zunächst einen Account erstellen.
Anfangs wählt dieser Nutzer \enquote{Ich bin kein Mitglied} auf der Registrierungsseite aus.
Daraufhin navigiert der Browser zu einem Registrierungs-Formular.
Hierfür muss eine Email-Adresse und ein Passwort vergeben und den Nutzungsbestimmungen zugestimmt werden.
Hierfür muss eine Email-Adresse, ein Passwort vergeben und den Nutzungsbestimmungen zugestimmt werden.
Im Anschluss erhält der Nutzer eine Bestätigungsemail mit einem Aktivierungslink.
Wird dieser Link geöffnet, wird der Account freigeschalten und ein Login-Feld erscheint.
Nach erfolgreichem Login wird der Nutzer mit einem
@@ -160,6 +156,7 @@ Stammdatenformular konfrontiert. Dabei handelt es sich um Angaben zum teilnehmen
Wird dieses Formular abgeschickt, ist die Teilnehmerregistrierung abgeschlossen.
\subsubsection*{Mitglied, mit Konto}
\label{chap:umsetzung-mitglied-mit-konto}
Ist ein Nutzer ein \ac{WM}-Mitglied und hat bereits ein Mitgliedskonto, muss dieser auf der Registrierungsseite
\enquote{Ich bin ein Mitglied} auswählen. An dieser Stelle navigiert der Browser zu einem Login-Formular.
Hier kann sich das Mitglied anmelden. Tut es dies erfolgreich, erstellt der Controller einen neuen
@@ -171,10 +168,13 @@ Ist ein Nutzer ein Mitglied, hat aber kein Mitgliedskonto, muss dieser auf der R
\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.
Da der Nutzer noch keinen Account hat, muss dieser auf \enquote{Jetzt registrieren} klicken.
Daraufhin navigiert der Browser zu einem Registrierungsformular, das eine Email-Adresse, ein Passwort
Daraufhin navigiert der Browser zu einem Registrierungsformular, das eine Email-Adresse, eine Mitgliedsnummer, ein Passwort
und die Zustimmung zur Datenverarbeitung benötigt. Ist dieses Formular abgeschickt, erhält das Mitglied
eine Email mit einem Bestätigungslink. Wird dieser Bestätigungslink angeklickt, wird das Mitgliedskonto
freigegeben und es öffnet sich ein Login-Formular, beschrieben in \enpointy{Mitglied, mit Konto}.
eine Email mit einem Bestätigungslink. Wird dieser Bestätigungslink angeklickt,
öffnet sich ein Login-Formular, beschrieben in \enpointy{\textit{\nameref{chap:umsetzung-mitglied-mit-konto}}}.
Da es sich hierbei um einen Mitgliederzugang handelt, muss dieser zunächst von einem
\ac{WM}-Mitarbeiter freigegeben werden, bevor ein Login möglich ist.
\subsubsection*{Umsetzung}
Zunächst wurde ein simples Weichen-Content-Element erstellt.
@@ -183,29 +183,29 @@ Dieses Content-Element hat die Parameter \enquote{question}, \enquote{answ-1-lin
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
realisiert.
Anpassungen der versendeten Emails erfolgen durch Überschreiben der Email-Templates von Femanager.
Anpassungen der versendeten Emails erfolgen durch Überschreiben der Email-Templates von \enquote{femanager}.
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 können Weiterleitungen zu spezialisierten Seiten im Backend-UI festgelegt werden
\break\cite{bib:typo3-docs-felogin}.
Für alle funktionalen Belange wird ein TYPO3-Plugin registriert. Dieses Plugin verfügt über einen
ActionController, der Nutzeranfragen an PHP-Funktionen (\enquote{Actions})
bindet.
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 Repository-Objekten registriert
\break\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
der ActionController-Klasse über Methode übergeben \cite{bib:typo3-docs-di}.
der ActionController-Klasse über eine Methode übergeben \cite{bib:typo3-docs-di}.
Als problematisch erweisen sich hierbei bidirektionale Verbindungen zwischen Datenmodellen, wenn die Foreign Keys
über das SQL-Schlüsselwort \enquote{AUTO\_INCREMENT} in der Datenbank generiert werden.
Beispielsweise, muss ein MasterRecord, der Betriebsinformationen speichert, bidirektional an ein Teilnehmerobjekt
Beispielsweise, muss ein Masterrecord, der Betriebsinformationen speichert, bidirektional an ein Teilnehmerobjekt
gebunden werden. Hierzu wird jedem der Elemente jeweils der Foreign Key des anderen übergeben.
Als Foreign Keys werden hierfür die jeweiligen \acp{UID} herangezogen, da diese Werte durch
\enquote{AUTO\_INCREMENT} auf der Datenbankebene erzeugt werden und garantiert einzigartig je Datenbanktabelle sind
\cite{bib:w3schools-auto-increment}.
Es gilt also, dass ein MasterRecord $a$ die Teilnehmer\ac{UID} von einem Teilnehmer $b$ hält und dass
$b$ die MasterRecord\ac{UID} von $a$ hält.
Es gilt also, dass ein Masterrecord $a$ die Teilnehmer\ac{UID} von einem Teilnehmer $b$ hält und dass
$b$ die Masterrecord\ac{UID} von $a$ hält.
Die Problematik hierbei ist, dass diese \acp{UID} erst nach dem Persistieren in der Datenbank bekannt sind,
da diese Werte erst im Zuge der Persistierung erstellt werden \cite{bib:w3schools-auto-increment}.
Die Lösung hierfür ist, beide Elemente zu erstellen und zu persistieren und erst danach ihre \acp{UID} gegenseitig
@@ -214,14 +214,14 @@ bekannt zu machen um sie anschließend erneut zu persistieren.
\subsection{Weinregistrierung}
Ein Basismerkmal des Jahresauswahlprobenwerkzeuges ist die Möglichkeit, Weine zu Jahresauswahlproben
anzumelden. Dieser Schritt übersetzt unter anderem die verbleibenden Formfelder des
ursprünglichen Anmeldeformulares, anbei in \fullref{chap:anhang-anmeldeformular} in den digitalen Workflow.
ursprünglichen Anmeldeformulares, anbei in \fullref{chap:anhang-anmeldeformular}, in den digitalen Workflow.
Für die Weinanmeldung spielt die Mitgliedsschaft eines Teilnehmers keine Rolle. Es wird lediglich ein
Frontend-Nutzer der Nutzergruppe \enquote{Teilnehmer} benötigt. Dieser Nutzer hat, wenn angemeldet,
Zugriff auf eine Auflistung aller zeitlich freigegebenen Jahresauswahlproben.
Soweit der Registrierungszeitraum dieser Jahresauswahlprobe den aktuellen Zeitpunkt miteinschließt,
wird eine \enquote{Jetzt Wein anmelden}-Schaltfläche angeboten.
Dadurch, dass Anmeldeformulare elektronisch und automatisiert verarbeitet werden, sinkt der Aufwand,
der seitens \ac{WM} für Anmeldungen geleistet werden muss. Das ist so, da diese Formular nun nicht mehr von
der seitens \ac{WM} für Anmeldungen geleistet werden muss. Das ist so, da diese Formulare nun nicht mehr von
Mitarbeitern bearbeitet werden müssen. Davon profitiert \ac{WM}, da diese Zeit nun für andere Aufgaben genutzt werden kann.
\begin{nicepic}
@@ -238,8 +238,8 @@ auf der betroffenen Webseite (in diesem Beispiel der Weinanmeldungsseite) durchg
Das Verstecken der zugehörigen
Schaltfläche im Frontend dient lediglich der User-Experience und stellt keine Sicherheitsvorkehrung dar.
Das ist essenziell, da eine URL, auch wenn für sie keine Schaltfläche existiert, dennoch aufgerufen werden kann.
Da Jahresauswahlprobennummern (\acp{UID}) fortlaufend sind, ist es trivial URLs für Weinanmeldungen
beliebiger Jahresauswahlproben herzuleiten. Insofern ist es von großer Wichtigkeit sicherzustellen,
Da Jahresauswahlprobennummern, also \acp{UID}, fortlaufend sind, ist es trivial URLs für Weinanmeldungen
beliebiger Jahresauswahlproben herzuleiten. Insofern ist es von großer Wichtigkeit, sicherzustellen,
dass der Server solche Anfragen grundsätzlich selbst prüft und gegebenenfalls verneint.
\subsubsection*{Das Formular}
@@ -251,7 +251,7 @@ Grundsätzlich entstehen hierbei drei Kategorien von Werten, die es im Formular
\paragraph*{Inputfelder} sind triviale Formfelder, die nicht durch andere Datensätze beschränkt werden.
Beispiele für Inputfelder sind: Weinbeschreibung, Jahrgang und Alkoholgehalt.
Inputfelder wurden mit simplen Input-Tags umgesetzt und erhielten nach Bedarf \textit{required} und
Inputfelder werden mit simplen Input-Tags umgesetzt und erhalten nach Bedarf \textit{required} und
\textit{pattern}-Attribute. Diese Attribute beschreiben jeweils, ob ein Formfeld ein Pflichtfeld ist und
mit welcher Regular Expression der Formfeldinhalt abzugleichen ist \cite{bib:w3schools-input}.
Die Formfeldwerte können unverändert in der Datenbank persistiert werden.
@@ -263,40 +263,42 @@ Beispiele für SelectSingle-Formfelder sind: Weinlage, Qualitätsstufe, Rebsorte
\enquote{Select} akzeptiert eine Liste an Auswahlmöglichkeiten und erstellt selbstständig Option-HTML-Tags
für diese.
Die Formfeldwerte von SelectSingle-Formfeldern sind die
\acp{UID} des jeweils ausgewähltem Elementes \cite{bib:typo3-docs-fluid-form-viewhelpers}.
\acp{UID} des jeweils ausgewählten Elementes \cite{bib:typo3-docs-fluid-form-viewhelpers}.
\\
\\
Aufgrund dessen, dass das Weinlagen-Drop-Down-Menü über 170 Einträge führt, wurde eine Suchmöglichkeit implementiert. Diese ist lediglich ein Textfeld, das bei jeder Eingabe allen Option-Tags der Weinlage,
deren Anzeigewert nicht der Suche entspricht, das Stilattribut \enquote{display: none;} auferlegt.
Aufgrund dessen, dass das Weinlagen-Dropdown-Menü über 170 Einträge führt, wird eine Suchmöglichkeit implementiert.
Diese ist lediglich ein Textfeld, das bei jeder Eingabe allen Option-Tags der Weinlage,
deren Anzeigewert nicht dem Suchwert entspricht, das Stilattribut \enquote{display: none;} auferlegt.
Somit sind diese nicht mehr sichtbar.
\\
\\
Eine komplexe Ausnahme stellt das SelectSingle-Formfeld \enquote{Category} dar, da TYPO3-Kategorien
als Baumstrukturen abgebildet werden
\break\cite{bib:typo3-docs-sys-category}.
Um die Eltern-Kind-Beziehung der Baumstruktur erstichtlich zu machen, werden die Option-HTML-Tags einzeln rekursiv gerendert. Zunächst werden sämtliche Kategorien, deren
Um die Eltern-Kind-Beziehungen der
\break{}Baumstruktur erstichtlich zu machen, werden die Option-HTML-Tags rekursiv gerendert. Zunächst werden sämtliche Kategorien, deren
\ac{PID} 0 ist, dargestellt. Diese Elemente sind direkte Kinder des unsichtbaren Wurzelelementes. Für jede dieser Kategorien $a$ wird nun ein
Fluid-Partial aufgerufen,
das alle Kategorien $b$ darstellt, für die gilt: $b.pid = a.uid$. Diese Darstellung erfolgt durch einen erneuten rekursiven Aufruf dieses Partials.
In jeder Darstellung wird der Kategoriename, geprefixt mit
$n$ Leerzeichen, dargestellt, mit $n = Rekursionstiefe$. Somit entsteht ein Drop-Down-Menü, das
alle Kategorien in einer eindimensionalen Liste darstellt. Diese Liste ist nach einer Preorder-Traversierung
$n$ Leerzeichen, dargestellt, mit $n = Rekursionstiefe$. Somit entsteht ein Dropdown-Menü, das
alle Kategorien in einer eindimensionalen Liste darstellt. Diese Liste ist nach einer preorder-Traversierung
des Kategoriebaumes sortiert und desto tiefer ein Element im Baum ist, desto weiter ist es eingerückt.
Damit sieht das Drop-Down-Menü aus wie eine Baumstruktur.
Damit sieht das Dropdown-Menü aus wie eine Baumstruktur.
\\
\\
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.
Diese Herangehensweise erzeugt schlüssigen, lesbaren Programmcode und lässt sich unkompliziert umsetzen.
Das senkt Entwicklungskosten, wovon \ac{WM} profitiert.
Rekursiv aufgerufene For-Schleifen, die sich selbst erneut für alle Elemente aufrufen,
können zu einem Performanzproblem führen \cite{bib:schwarzer-vorlesung-alg}.
können zu Performanzproblemen führen \cite{bib:schwarzer-vorlesung-alg}.
Daher wird im Folgenden die Zeitkomplexität dieser Rekursionsfunktion betrachtet.
Für diese Funktion kann kein Master-Theorem angewandt werden,
da es sich hierbei nicht um einen Divide-and-Conquer-Algorithmus handelt.
da es sich hierbei nicht um einen \enquote{Divide-and-Conquer-Algorithmus} handelt.
Das ist so, da das in der Rekursion weitergereichte Problem nicht kleiner wird,
sondern gleich groß bleibt.
Das verletzt die Bedingung $b>1$ des Master-Theorems, definiert als $T(n) = a*T(\frac{n}{b})+f(n)$
\cite{bib:schwarzer-vorlesung-alg}.
Der Algorithmus besteht aus $m, m \in \mathbb{N}$ verschachtelten For-Schleifen
Der Algorithmus besteht aus $m \in \mathbb{N}$ verschachtelten For-Schleifen
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.
@@ -306,19 +308,18 @@ Somit ist die Zeitkomplexität $O(n^m)$. Normiert dargestellt beträgt die Zeitk
\caption*{Quelle: Eigene Darstellung}
\label{fig:timecomplexity-category}
\end{nicepic}
\clearpage
Auf Optgroup-HTML-Tags wurde bewusst verzichtetet.
Grund dafür ist, dass Optgroup-Elemente an sich nicht im Dropdown auswählbar sind.
Grund dafür ist, dass Optgroup-Elemente an sich nicht im Dropdown-Menü auswählbar sind.
Das stellt ein Problem dar, da beispielsweise die Kategorie \enquote{Riesling},
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
von Unterkategorien hindeutet \cite{bib:typo3-docs-sys-category}, womit eine Unterscheidung zwischen
Baumblättern und -Zweigen nicht ohne weiteres möglich wäre. 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.
\paragraph*{SelectMultiple} sind Formfelder, die dem Nutzer eine Auswahl aus $n$ verschiedenen Elementen aus einer anderen
Datenbanktabelle geben. Der Nutzer kann sich für eine beliebige Auswahl dieser, eingeschlossen keine, entscheiden.
Datenbanktabelle geben. Der Nutzer kann sich für eine beliebige Auswahl dieser, eingeschlossen keinen, entscheiden.
Ein Beispiel für SelectMultiple-Formfelder sind Weineigenschaften.
TYPO3-Fluid implementiert hierfür keinen ViewHelper
\break\cite{bib:typo3-docs-fluid-form-viewhelpers},
@@ -327,7 +328,7 @@ Für alle Elemente $a \in A$
wird ein Checkbox-Feld erstellt. Dieses Element trägt den Anzeigewert \enquote{<a.title>} und den
Wert \enquote{<formfeldname>-true}.
Ist also eine dieser Checkboxen angehakt, hat sie den zuvor genannten Wert. Falls nicht, trägt sie keinen Wert.
Weil alle angehakten Checkboxen dieses Formfeldes den selben Wert tragen, ist es PHP-Seitig trivial
Weil alle angehakten Checkboxen dieses Formfeldes den selben Wert tragen, ist es PHP-seitig trivial
eine Liste aller angehakten Checkbox-Ids dieses Formfeldes aus der Liste aller Formfeldparameter zu extrahieren.
Hierfür wird die eingebaute PHP-Funktion \enquote{array\_keys} verwendet. Diese Funktion gibt alle
Keys eines Arrays in Form eines numerisch indizierten Arrays zurück.
@@ -356,15 +357,15 @@ Der QR-Code beinhaltet lediglich die Wein-\ac{UID} anstatt einer vollständigen
die benötigte URL, 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 Gewinn zu erhöhen, wird der QR-Code zu einem Base64-kodiertem Bild gerendert.
Um effizient zu arbeiten, 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 Quell-URL eines
und erfordert somit keine nähere Konfiguration. Ebenfalls lässt sich ein base64-kodiertes Bild als Quell-URL eines
IMG-HTML-Tags angeben, womit das Bild eingebettet ist. Das spart Arbeitszeit,
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}.
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 mit \enquote{mpdf} erzeugt werden,
@@ -372,14 +373,14 @@ 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.
diese mit TYPO3-Fluid befüllt und in PHP gerendert wird, um eine HTML-Zeichenkette als Ergebnis zu erhalten.
Hierfür wird ein TYPO3-StandaloneView instanziiert, mit einem Pfad zur Template-Datei konfiguriert, Variablen angegeben,
die in Fluid verfügbar sein sollen und anschließend über die \enquote{render}-Methode zu einer Zeichenkette 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}.
Abschließend wird dem \enquote{mpdf}-Objekt das zuvor generierte HTML übergeben, über die Methode \enquote{OutputBinaryData}
in Form von 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. Diese Header sind Content-Type und Content-Length.
Abschließend werden als Response-Body die Bytes des generierten PDFs übertragen. Damit ist die Verbindung beendet und das
@@ -388,13 +389,13 @@ PDF zum Nutzer übertragen.
\subsection{Jahresauswahlproben- und Wein-Detailansichten}
Weine und Jahresauswahlproben sollen unter bestimmten Gegebenheiten einsehbar 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 auch eine Liste aller zur Einsicht berechtiger Weine
Jahresauswahlprobe zu öffnen. Hier wird neben Metadaten der Jahresauswahlprobe auch eine Liste aller zur Einsicht berechtigen Weine
angezeigt. Diese Weine sind anklickbar, um auf eine Detailansicht der Weine zu gelangen.
Die Detailansichten für Jahresauswahlproben und Weine benötigen spezielle 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.
Nach Abschluss ihrer 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 Jahresauswahlprobe auch.
@@ -407,6 +408,10 @@ zu anderen Ansichten generiert. Diese ViewHelper übergeben Parameter. Die hierf
Ansichten sind beispielsweise Wein-\acp{UID} und Jahresauswahlproben-\acp{UID}. Um Informationen über den angemeldeten Nutzer,
wie beispielsweise seiner Teilnehmernummer oder seiner Nutzergruppenzugehörigkeit, zu erlangen, wird sich
der Extbase-nativen Domain-Model-FrontendUser-Klasse bedient \cite{bib:typo3-ref-extbase-model-feuser}.
\\
\\
Mit Abschluss der Phase der Digitization können alle Datenstrukturen im TYPO3-Backend händisch angelegt,
eingesehen, gelöscht und bearbeitet werden.
\section{Digitalization}
@@ -417,7 +422,7 @@ implementierten Datenmodellen zu arbeiten. Im Folgenden werden die Umsetzungen d
erforderlichen Geschäftsprozesse beschrieben.
\subsection{Schnittstelle QR-Code-Scanner}
Es ist angedacht, dass Mitarbeiter über die App \enquote{QRBot} den QR-Code auf dem Einlieferungsschein einscannen.
Es ist angedacht, dass Mitarbeiter über die App \enquote{QRBot} den QR-Code auf dem Datenblatt 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
@@ -428,9 +433,9 @@ Das Nutzerkonto wird von Redakteuren oder Administratoren im TYPO3-Backend erste
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,
Sollte ein Wein bereits als \enquote{eingegangen} markiert sein, wird keine Email verschickt und dem Mitarbeiter kommuniziert,
dass keine Änderungen vorgenommen wurden.
Abschließend werden im Frontend allgemeine Daten über den Wein angezeigt, damit Mitarbeiter sich sicher sein können,
Abschließend werden im Frontend allgemeine Daten über den Wein angezeigt, damit sich Mitarbeiter sicher sein können,
den richtigen Wein eingescanned zu haben.
\subsection{CSV-Export}
@@ -464,7 +469,7 @@ um das fertig erzeugte CSV-Dokument als Zeichenkette in PHP zu erhalten. Das spa
Im Fluid-Template des Backendmoduls wird das generierte CSV-Dokument in einem nicht beschreibbaren Textarea-Feld präsentiert.
Um \ac{WM} weitere Arbeitszeit zu ersparen wird eine Download-Funktion für CSV-Dateien
angeboten. Das erspart das manuelle Kopieren und Abspeichern von CSV-Zeichenketten durch IT-Fachfremde, reduziert damit die Anzahl
an benötigten Übergangsschritte in weitere Prozesse und reduziert somit die Komplexität der Umstellung.
an benötigten Übergangsschritten in weitere Prozesse und reduziert somit die Komplexität der Umstellung.
Auch im Interesse, Arbeitszeit in der Umsetzung zu sparen,
wurde diese Downloadfunktion JavaScript-seitig umgesetzt.
Dadurch ist der Download in derselben Action, die CSV für das Textarea-Feld generiert, implementiert.