DEPRECATION WARNING

This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.

EXT: uk_db_tutorial

Author:Kasper Skårhøj
Created:2002-11-01T00:32:00
Changed by:Syrcam
Changed:2008-05-27T14:30:26
Author:Eike Starkmann
Email:starkmann@undkonsorten.com
Info 3:
Info 4:

EXT: uk_db_tutorial

Extension Key: my_extension_key

Copyright 2000-2002, Eike Starkmann, starkmann@undkonsorten.com>

This document is published under the Open Content License

available from http://www.opencontent.org/opl.shtml

The content of this document is related to TYPO3

- a GNU/GPL CMS/Framework available from www.typo3.com

Table of Contents

EXT: uk_db_tutorial 1

Introduction 1

What does it do? 1

Screenshots 1

Tutorial 3

Worum geht es hier genau? 3

N:M Relation 3

N:M Relation mit Attributen 5

Weiterführende Links 9

Introduction

What does it do?

Der Kickstarter für TYPO3-Extensions gibt einem Entwickler viele Möglichkeiten Datenbanken anzulegen, sogar MM Tabellen. Aber leider lassen sich viele Funktionen die modernes Datenbankdesign bietet mit dem Kickstarter nicht umsetzen. Dieser Artikel gibt einen Einblick, wie in TYPO3 die wichtigsten Relation zwischen Tabellen

  • M zu M
  • N zu M
  • N zu M mit Attributen

angelegt werden können.

Auf 1:N Relationen wird hier nicht eingegangen, da diese vom Kickstarter voll unterstützt und einfach zusammen geklickt werden können.

Screenshots

in Beispiel der gewünschten Datenbankrelation:

Datenbankrelation Beispiel

Ein Beispiel: N zu M Relation mit Attributen

TYPO3 Datenbankrelation - N zu M

Bearbeitung der Firma:

TYPO3 Datenbankrelation - Backend N zu M - Firma

Bearbeitung des Mitarbeiters:

TYPO3 Datenbankrelation - Backend N zu M - Mitarbeiter

Tutorial

Worum geht es hier genau?

Fangen wir mit einem einfachen Beispiel an. Für eine Freelancer- Datenbank die mit TYPO3 umgesetzt werden soll brauchen wir zwei Datensatztypen:

  • Mitarbeiteroder Freelancer sowie
  • Firmenbei für die diese Mitarbeiter gerade arbeiten.

Logischerweise sollen diese Daten miteinander verknüpft werden können. Mitarbeiterarbeiten für verschiedenen Firmenund für Firmen arbeiten verschiedenen Mitarbeiter. Nun soll die Eingabe der Verbindungen Mitarbeiter-Firmaso flexibel sein, dass wir sie von beiden Seiten aus bearbeiten können.

Wird also zum Beispiel einem Mitarbeiter-Datensatz A eine Firma B zugeordnet, so sieht man auch im Firmen-Datensatz B, dass der Mitarbeiter bei der Firma arbeitet. Man kann so die Verbindung zwischen dem Mitarbeiter und der Firma sowohl beim Bearbeiten des Firmen-, als auch des Mitarbeiter-Datensatzes wieder lösen. Ferner kann natürlich der Firma B ein Mitarbeiter C zugeordnet werden und im Mitarbeiter-Datensatz C erscheint dann automatisch die Firma B.

In einem weiteren Schritt werden wir auch noch erklären, wie man der Verbindung noch weitere Eigenschaften wie Werksvertrag, studentische Hilfskraftoder freier Mitarbeiterhinzufügt.

Doch bereits das erste Szenario ist mit dem TYPO3-Kickstarter nicht mehr möglich: Wird mit dem eine Tabelle Firma angelegt mit dem Feld Mitarbeiter (Relation zu Mitarbeiter) und ein Mitarbeiter mit dem Feld Firma, so macht der Kickstarter daraus zwei M:M Tabellen. Es ist aber klar, dass sowohl Mitarbeiter als auch Firma über ein und dieselbe Relationstabelle verknüpft werden müssen, um die gewünschte, oben beschriebene Funktionalität zu erhalten. Dies wird ermöglicht mit ‘foreign_table’ =>”und ‘foreign_field’ => ”welche in der tca.phpder Extension definiert werden können.

N:M Relation

Ein Beispiel der gewünschten Datenbankrelation:

Datenbankrelation Beispiel

Ein Projekt-Mitarbeiter kann für mehrere verschiedene Firmen arbeiten und eine Firma hat mehrere verschieden Mitarbeiter. Zunächst werden beide Tabellen im Kickstarter angelegt:

TYPO3 Datenbankrelation - Kickstarter

In der Tabelle Mitarbeiterwird nun eine Relation zur Tabelle Firmadefiniert:

TYPO3 Datenbankrelation - Kickstarter #2

In der Tabelle Firmawird eine Relation zur Tabelle Mitarbeiterdefiniert:

TYPO3 Datenbankrelation - Kickstarter #2

Beide Relationen müssen als True M-M relationsmarkiert werden, da sonst keine extra Relationstabelle angelegt wird. Das beidseitige Anlegen von Mitarbeiter und Firma ermöglicht später das beidseitige Editieren (siehe oben).

Schaut man sich nun die ext_tables.sql der Exension an, erkennt man, dass zwei MM Relationstabellen angelegt werden. Eine für die Richtung Mitarbeiter->Firmaund eine für Firma->Mitarbeiter:ext_tables.sql

CREATE TABLE tx_ukdbtutorial_mitarbeiter_firma_mm (uid_local int(11) DEFAULT ‘0′ NOT NULL,uid_foreign int(11) DEFAULT ‘0′ NOT NULL,tablenames varchar(30) DEFAULT ” NOT NULL,sorting int(11) DEFAULT ‘0′ NOT NULL,KEY uid_local (uid_local),KEY uid_foreign (uid_foreign));

CREATE TABLE tx_ukdbtutorial_firma_mitarbeiter_mm (uid_local int(11) DEFAULT ‘0′ NOT NULL,uid_foreign int(11) DEFAULT ‘0′ NOT NULL,tablenames varchar(30) DEFAULT ” NOT NULL,sorting int(11) DEFAULT ‘0′ NOT NULL,KEY uid_local (uid_local),KEY uid_foreign (uid_foreign));

Es werden aber nicht beide benötigt, daher kann getrost eine Tabelle aus der Datei gelöscht werden, z.B. tx_ukdbtutorial_firma_mitarbeiter_mm. Außerdem muss bei der Relationstabelle ein Feld hinzugefügt werden: sorting_foreign int(11) DEFAULT ‘0′ NOT NULL.

Dies ermöglicht das unterschiedliche Sortieren der Datensätze auf beiden Seiten und muss erstellt werden, da TYPO3 danach verlangt.Das Resultat sieht dann also so aus:

CREATE TABLE tx_ukdbtutorial_mitarbeiter_firma_mm (uid_local int(11) DEFAULT ‘0′ NOT NULL,uid_foreign int(11) DEFAULT ‘0′ NOT NULL,tablenames varchar(30) DEFAULT ” NOT NULL,sorting int(11) DEFAULT ‘0′ NOT NULL,sorting_foreign int(11) DEFAULT ‘0′ NOT NULL,KEY uid_local (uid_local),KEY uid_foreign (uid_foreign));

Jetzt muss noch dafür gesorgt werden, dass sowohl Firmaals auch Mitarbeiterauf dieselbe Relationstabelle zugreifen:

$TCA[”tx_ukdbtutorial_firma”] = array (“mitarbeiter” => Array (“exclude” => 1,“label” => “LLL:EXT:uk_db_tutorial/locallang_db.xml :tx_ukdbtutorial_firma.mitarbeiter”,“config” => Array (“type” => “group”,“internal_type” => “db”,“allowed” => “tx_ukdbtutorial_mitarbeiter”,“size” => 10,“minitems” => 0,“maxitems” => 10,“MM” => “tx_ukdbtutorial_firma_mitarbeiter_mm”,)

wird geändert in:

$TCA[”tx_ukdbtutorial_firma”] = array (“mitarbeiter” => Array (“exclude” => 1,“label” => “LLL:EXT:uk_db_tutorial/locallang_db.xml :tx_ukdbtutorial_firma.mitarbeiter”,“config” => Array (“type” => “group”,“internal_type” => “db”,“allowed” => “tx_ukdbtutorial_mitarbeiter”,“size” => 10,“minitems” => 0,“maxitems” => 10,“MM” => “tx_ukdbtutorial_mitarbeiter_firma_mm”,“MM_opposite_field” => “mitarbeiter”,)

“MM” => “tx_ukdbtutorial_mitarbeiter_firma_mm” ist die zu benutzende Relationstabelle, sie muss sowohl bei Mitarbeiter als auch bei Firma dieselbe sein.“MM_opposite_field” => “mitarbeiter”sorgt dafür das die uids in der Relationstabelle nicht vertauscht werden .Diese Relation ist jetzt eigentlich eine N:M Relation da, z.B. mehrere Mitarbeiter einer Firma zugeordnet werden können, die Anzahl der Zuordnungen auf beiden Seiten aber nicht gleich sein muss. Möchte man dies haben sollten die Max number of relationsim Kickstarter passend gesetzt werden.

N:M Relation mit Attributen

Ein Mitarbeiter kann in mehreren Firmen arbeiten, in diesen kann er bestimmte Positionen, z.B. Werksvertrag, studentische Hilfskraft, fester freier Mitarbeiterbesitzen. Dies sind die Attribute.

Ein Beispiel: N zu M Relation mit Attributen

TYPO3 Datenbankrelation - N zu M

Es ist kann aber vorkommen, das ein Mitarbeiter in der Firma A einen Werksvertrag hat und in der Firma B studentische Hilfskraft ist. Es ist also nicht möglich die Position des Mitarbeiters in einem Feld in der Tabelle Mitarbeiter zu speichern, da die Position von der jeweiligen Firma abhängt. Das Attribut Positionmuss also in der Relationstabelle gespeichert werden. Dies lässt sich am besten mit Inline Rational Relation Editing (IRRE)realisieren:

Zunächst legt man zwei neue Tabellen an: Mitarbeiter2und Firma2. Dies kann exakt, wie oben beschrieben, mit Hilfe des Kickstarters erfolgen.

Jetzt müssen wieder die tca.phpund die ext_tables.sqleditiert werden:ext_tables.sql:

CREATE TABLE tx_ukdbtutorial_mitarbeiter2_firma_mm (uid int(11) NOT NULL auto_increment,pid int(11) DEFAULT ‘0′ NOT NULL,tstamp int(11) DEFAULT ‘0′ NOT NULL,tablenames varchar(30) DEFAULT ” NOT NULL,sorting int(11) DEFAULT ‘0′ NOT NULL,position tinytext NOT NULL,mitarbeiterid int(11) DEFAULT ‘0′ NOT NULL,firmaid int(11) DEFAULT ‘0′ NOT NULL,crdate int(11) DEFAULT ‘0′ NOT NULL,cruser_id int(11) DEFAULT ‘0′ NOT NULL,deleted tinyint(4) DEFAULT ‘0′ NOT NULL,PRIMARY KEY (uid),KEY parent (pid)););

Die zweite Relationstabelle tx_ukdbtutorial_firma2_mitarbeiter_mmkann wieder gelöscht werden. Wir benötigen jetzt das neue Feld positionund 2 Felder zu Steuerung mitarbeiteridund firmaid. uid_localund uid_foreignwerden als Felder nicht mehr benötigt, dafür aber eine uid und eine pid. Die uid ist wie immer der Primary Key und wird daher auf auto_increment gesetzt.cruser, tstamp, deletedund crdatewerden von TYPO3 benötigt.Man sieht jetzt schon das die Relationstabelle nicht mehr klassisch aufgebaut ist , sondern wie eine ganz normale “Datensatz”-Tabelle., dazu später mehr.

In der tca.phpmuss nun etwas mehr geändert werden:

$TCA[”tx_ukdbtutorial_mitarbeiter2″] = array (“interface” => array (“showRecordFieldList” => “hidden,name,firma”),“firma” => Array (“exclude” => 1,“label” => “LLL:EXT:uk_db_tutorial/locallang_db.xml :tx_ukdbtutorial_mitarbeiter2.firma”,“config” => Array (‘type’ => ‘inline’,‘foreign_table’ => ‘tx_ukdbtutorial_mitarbeiter2_firma_mm’,‘foreign_field’ => ‘mitarbeiterid’,‘foreign_label’ => ‘firmaid’,),),$TCA[”tx_ukdbtutorial_firma2″] = array (“interface” => array (“showRecordFieldList” => “hidden,name,mitarbeiter”),“mitarbeiter” => Array (“exclude” => 1,“label” => “LLL:EXT:uk_db_tutorial/locallang_db.xml:tx_ukdbtutor ial_firma2.mitarbeiter”,“config” => Array (‘type’ => ‘inline’,‘foreign_table’ => ‘tx_ukdbtutorial_mitarbeiter2_firma_mm’,‘foreign_field’ => ‘firmaid’,‘foreign_label’ => ‘mitarbeiterid’,),),

type’ => ‘inline’: Jetzt wird nicht länger die Groupbox von TYPO3 benutzt, sondern IRRE. Das heißt, dass Kinderelemente oder Relationen direkt in dem Mitarbeiter bzw. der Firma angelegt werden können.foreign_table’ =>: Definiert welche Relationstabelle benutzt wird, muss auch hier wieder gleich sein.Achtung es darf kein “MM” =>benutzt werden, da dann keine Attribute mehr unterstützt werden.

Außerdem muss die Relationstabelle in der tca.phpdefiniert werden:

$TCA[’tx_ukdbtutorial_mitarbeiter2_firma_mm’] = Array(“ctrl” => $TCA[”tx_ukdbtutorial_mitarbeiter2_firma_mm”][”ctrl”],“interface” => Array (“showRecordFieldList” => “mitarbeiterid,firmatid,position”),“feInterface” => $TCA[”tx_ukdbtuto rial_mitarbeiter2_firma_mm”][”feInterface”],‘columns’ => Array(‘mitarbeiterid’ => Array(‘label’ => ‘LLL:EXT:uk_db_tutorial/lo callang_db.xml:tx_ukdbtutorial_mitarbeiter2′,‘config’ => Array(‘type’ => ’select’,‘foreign_table’ => ‘tx_ukdbtutorial_mitarbeiter2′,’size’ => 1,‘minitems’ => 0,‘maxitems’ => 1,),),‘firmaid’ => Array(‘label’ => ‘LLL:EXT:uk_db_t utorial/locallang_db.xml:tx_ukdbtutorial_firma2′,‘config’ => Array(“type” => “group”,“internal_type” => “db”,“allowed” => “tx_ukdbtutorial_firma2″,“size” => 1,“minitems” => 1,“maxitems” => 1,)),‘position’ => Array(‘label’ => ‘LLL:EXT:uk_db_tutorial/locallan g_db.xml:tx_ukdbtutorial_mitarbeiter2_firma_mm.position’,‘config’ => Array(“type” => “input”,“size” => “30″,),),),“types” => Array (“0″ => Array(”showitem” => “hidden;;1,firmaid,mitarbeiterid,position”)),“palettes” => Array (“1″ => Array(”showitem” => “”)));

Die Konfiguration für das Backend wurde hier so gestaltet, dass bestehende Mitarbeiter über eine Selectorbox und bestehende Firmen über eine eine Groupbox ausgewählt werden können.Die Eingabe der Position kann über ein normales Input Feld erfolgen.

In der ext_tables.phpwird nun ebenfalls die Relationstabelle definiert:

$TCA[”tx_ukdbtutorial_mitarbeiter2_firma_mm”] = Array (“ctrl” => Array (‘title’ => ‘LLL:EXT:uk_db_tutorial/locallang_db.xml:tx_ukdb tutorial_mitarbeiter2_firma_mm’,‘label’ => ‘uid’,‘tstamp’ => ‘tstamp’,‘crdate’ => ‘crdate’,“dynamicConfigFile” => t3lib_extMgm::extPath($_EXTKEY).”tca.php”,“iconfile” => t3lib_extMg m::extRelPath($_EXTKEY).”icon_tx_ukdbtutorial_firma2.gif”,),“feInt erface” => Array (“fe_admin_fieldList” => “mitarbeiterid, firmaid, position”,));

Jetzt müssen nur noch die Labels für die Relationstabelle in der locallang_db.xmlgesetzt werden:

<label index=”tx_ukdbtutorial_mitarbeiter2_firma_mm”>Mitarbeiter- Firma</label><label index=”tx_ukdbtutorial_mitarbeiter2_firma_mm.p osition”>Position</label>

Nun kann man das Resultat im Backend bewundern, das Ganze sieht dann wie folgt aus:

TYPO3 Datenbankrelation - Backend N zu M

Wie man sieht , können, jetzt auch die Relation an sich bearbeitet werden. Sie erscheinen in dem Sysordner als regulärer Datensatz.

Bearbeitung der Firma:

TYPO3 Datenbankrelation - Backend N zu M - Firma

Bearbeitung des Mitarbeiters:

TYPO3 Datenbankrelation - Backend N zu M - Mitarbeiter

Zum Verständnis:Neu anlegenmeint in diesem Fall das Neuanlegen einer Relation, es können keine neuen Firmen innerhalb eines Mitarbeiters angelegt werden, sondern nur bestehende ausgewählt werden.

TYPO3 Datenbankrelation - Backend N zu M - Relation Man kann IRRE aber auch so konfigurieren, das neue Kindelemente direkt angelegt werden können.