Zum Inhalt springen

Problem mit tableMapping auf ein MySQL View und FAL (Bilder und Dokumente)

Erstellt am 26. Januar 2018 · 2 Antworten · letzte Antwort am 29. Januar 2018

Tags: Dateien & FAL, Datenbank, Frage

finnegan ·

Typo3 7.6

Hallo,

ich habe eine Extbase-Extension entwickelt, die eine Eltern-Tabelle und eine Kind-Tabelle mit m:n-Relation implementiert. Die Eltern-Tabelle enthält 2 Felder für Bilder und Dokumente. Das funktioniert wunderbar.

Nun muss die Listen-Ausgabe der Elterntabelle nach Kriterien von Kind-Elementen gefiltert werden. Aus Performance-Gründen habe ich ein MySQL-View gebaut, das alle Felder der Elterntabelle enthält.

Dazu habe ich gemäß Doku im TS Setup meiner Extension ein Table-Mapping vorgenommen, so dass Extbase nicht die originale Extension-Elterntabelle einliest, sondern der davon abgeleitete MySQL-View.

Die Listenausgabe dieses DB-Views funktioniert wie gewünscht.

Mein Problem:

In der Detailansicht (Extbase detail view) jedoch sind die Bilder und Dokumente nicht in der Model Class enthalten (in der Listenansicht womöglich auch nicht, aber dort gebe ich keine Bilder aus).

Zugehörige Elemente aus der Kind-Tabelle meiner Extension werden dagegen in der Detailansicht wie geplant ausgegeben.

Sobald ich in der Detailansicht das TableMapping im TS Setup auskommentiere und auf die Original-Elterntabelle zugreife, sind die Bildreferenzen in der Model Class wie erwartet vorhanden.
Und - wie gesagt - mein MySQL-View hat identische Felder/Feldnamen wie die Ausgangstabelle. Die Tabellenreferenzen auf die FAL-Tabellen sind also in meinem DB View genauso vorhanden wie in der Ausgangstabelle. Zudem werden alle anderen Daten korrekt ausgegeben.

Eine TCA-Konfiguration für meinen DB View ist natürlich auch vorhanden.

Hat von euch jemand einen Tipp? Oder funktioniert in Extbase die FAL-Referenzierung bei tableMapping nicht korrekt?

Bin für jeden Hinweis dankbar.

Viele Grüße

finnegan

finnegan ·

Ich konnte das Problem lösen.
Für die Nachwelt:

1. Ich finde keine Hinweise im Web zur Verwendung von Datenbank-Views und Extbase. Daher sollte man das lieber lassen. Warum ich es doch getan habe, habe ich oben dargestellt.

2. Nun zur Analyse:

Referenziert eine Extbase-Tabelle Bilder, wird diese m:n-Relation in der Tabelle sys_file_reference gespeichert.
In der TCA ist das Feld der Extbase-Tabelle, das die Bildverweise enthält, vom Typ inline.
sys_file_reference enthält das Feld tablenames, in das das Backend den Elterntabellennamen einträgt, dem ein Bild (oder ein anderes Dokument) zugeordnet ist.

Um die Inline-Konfiguration für die TCA der Elterntabelle zu generieren, stellt Typo3 die Funktion \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig([Parameter ...]) zur Verfügung.

Die resultierende TCA enhält im [config]-Abschnitt des Bildfeldes der Elterntabelle

foreign_table_field = tablenames

Benutzt man für die Frontend-Ausgabe ein Extbase-Model, erstellt Extbase für den Zugriff auf die Bilder, also auf sys_file_reference, eine WHERE-Klausel:

SELECT sys_file_reference.* FROM sys_file_reference WHERE ((((sys_file_reference.uid_foreign = [UID der Elterntabelle]
AND sys_file_reference.tablenames = 'tx_myextension_domain_model_mytable') .....

Wenn man nun, wie ich es tat, aus der Elterntabelle tx_myextension_domain_model_mytable ein Datenbank-View tx_myextension_domain_model_myview ableitet und über das Table Mapping Extbase anweist, statt der Elterntabelle den DB-View zu benutzen, wird Extbase beim Zugriff auf die Bilder in die o.g. WHERE-Klauses 'tx_myextension_domain_model_myview' statt 'tx_myextension_domain_model_mytable' einsetzen. Die logische Folge: SELECT * FROM sys_file_reference .... findet keine Datensätze. Bilder werden nicht angezeigt.

3. Meine Lösung:

Innerhalb der möglichen TCA-Konfigurationsparameter für den Typ "inline" gibt es den Parameter foreign_match_fields (siehe https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/Inline/Index.html). Ich fand ein praktisches Beispiel von Helmut Hummel: https://github.com/helhum/upload_example/blob/master/Configuration/TCA/tx_uploadexample_domain_model_example.php

Damit kann man den Wert des Feldes "tablenames" in sys_file_reference konkret setzen:

'foreign_match_fields' => [
'fieldname' => 'image',
'tablenames' => 'tx_myextension_domain_model_mytable',
'table_local' => 'sys_file',
],

D.h. obwohl ich für die Frontend-Ausgabe mit einem Datenbank-View arbeite, kann ich in der TCA dieses DB-Views meine ursprüngliche Elterntabelle angeben.

Das reicht jedoch noch nicht, um Bilder der Elterntabelle zu finden, denn die oben genannte WHERE-Klauses enthält immer noch "....sys_file_reference.tablenames = 'tx_myextension_domain_model_myview'...".
Das Debuggen der SQL-Befehle zeigte mir, dass bei Verwendung von "foreign_table_field = tablenames" UND "'foreign_match_fields'=> 'tablenames'" in der TCA ZWEI gleichlautende WHERE-Bedingungen erzeugt werden:

... WHERE ((((sys_file_reference.uid_foreign = [UID Elterntabelle] AND sys_file_reference.tablenames = 'tx_myextension_domain_model_mytable') AND sys_file_reference.fieldname = 'images') AND sys_file_reference.tablenames = 'tx_myextension_domain_model_mytable') AND sys_file_reference.table_local = 'sys_file') AND ....

Meine Lösung bestand darin, den Parameter foreign_table_field aus der TCA für meinen Datenbank-View zu löschen:

.....
unset($aTCA['columns']['images']['config']['foreign_table_field']);
return $aTCA;

Damit werden die zugehörigen Bilder nun auch bei meinem Datenbank-View gefunden und ich kann in den Fluid-Templates wie gewohnt auf sie zugreifen.

finnegan