---
title: "Schwaches Entity (weak entity) in Datensätzen"
url: "https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen"
source: "typo3.net"
tags: ["Extensions","Entwicklung","Frage","TCA"]
created: "2005-11-04"
last_reply: "2007-01-15"
replies: 29
solved: false
page: 1
pages: 1
lang: "de"
---

# Schwaches Entity (weak entity) in Datensätzen

Extensions › Entwicklung · 29 Antworten · gestartet 2005-11-04

## Eröffnungsbeitrag

**BenjaminW** · 2005-11-04 · [Beitrag #1](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/1)

Hi!

Ich möchte in Typo3 die folgende (etwas vereinfacht dargestellte) Beziehung abbilden:

Eine Firma hat mehrere Mitarbeiter.
Kein Mitarbeiter ist ohne Firma.
(Diese Art von 1 zu n Beziehung wird auch als Weak entity oder auch "identifizierende Beziehung" bezeichnet)

Wenn ich jetzt ein normales PHP Projekt hätte, wo ich selbst auf die Datenbank zugreife, hätte ich das demnach so gestaltet:

Tabelle Firma mit folgenden Spalten:

```php
fid (Firmen-ID, Primary Key)
Name (Firmenname)
```

-----------------------------------

Tabelle Mitarbeiter mit folgenden Spalten:

```php
mid (Mitarbeiter-ID, Primary Key)
fid (Firmen-ID, Primary Key!)
Name (Mitarbeiter-Name)
```

Ich krieg es einfach nicht gebacken, diese (ihr müsst zugeben) nicht gerade so unübliche Beziehung dem lieben Typo3 klarzumachen! Es kennt offenbar nur nicht-identifizierende Datenbankbeziehungen. Jedenfalls fand ich im Kickstarter sowie auch in der Doku zum TCA *keine* Angaben dazu.

Es geht im konkreten Fall um einzelne Veranstaltungen, die mehrere Termine haben. In der Anlegung einer Veranstaltung soll auch die Möglichkeit sein, direkt Termine zu der Veranstaltung hinzuzufügen. Achja: Die Termine müssen in einer separaten Tabelle stehen, also der quick&dirty Weg, einfach die Termine zeilenweise in ein Textfeld zu schreiben, is nich  #giggle#

Bitte helft mir  #paralyzed#

Gruß,
Benjamin

## Antworten

### [#2](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/2) · jenses · 2005-11-04

Dann hast du aber nicht wirklich gesucht  ;)
Was du vorhast, ist absolut problemfrei mit TYPO3 umzusetzen.
Schau mal in die TypoCoreAPI, Stichwort foreign_table.

### [#3](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/3) · just2b · 2005-11-05

genauer
<https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/Select/Index.html>

### [#4](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/4) · BenjaminW · 2005-11-05

> **jenses schrieb:**
>
> Dann hast du aber nicht wirklich gesucht  ;)
> Was du vorhast, ist absolut problemfrei mit TYPO3 umzusetzen.
> Schau mal in die TypoCoreAPI, Stichwort foreign_table.

*gg* ähm ich habe mich da wohl leider falsch ausgedrückt. Eine einfache Liste von Datensätzen einer fremden Tabelle ist das nicht wirklich. Das ist ja kein Problem.

Nennen wir nochmal das Beispiel mit der Firma und den Mitarbeitern:

Ich lege eine Firma an. Im Formular für die Firma, soll nun die Möglichkeit sein, Mitarbeiter anzulegen, die ich der Firma hinzufüge. Soweit kein Ding.

Nun lege ich eine weitere Firma an. Nach dem normalen Verfahren würde ich jetzt in der Mitarbeiter-Selectbox *alle* in der Tabelle vorhandenen Mitarbeiter sehen. Das will ich aber nicht. Sondern ich möchte *nur* die zu einer Firma gehörenen Mitarbeiter sehen. Deswegen heisst das ja auch Weak entity. Der Mitarbeiter kann nicht ohne Firma existieren, weil der FK Bestandteil des Primärschlüssels ist. Und genau so eine Beziehung ist für mein Dafürhalten so einfach nicht möglich.

Im konkreten Beispiel geht es wie gesagt um Veranstaltungen die mehrere Start- und Endzeiten haben. Es macht wenig sinn, in der Liste für die Zeiten nun *alle* Termine aller Veranstaltungen zu sehen. Es muss eine direkte Verknüpfung mit der Veranstaltung sein (sonst wäre das ne M:N Beziehung).

Was auch wichtig ist: Wenn ich nun eine Veranstaltung lösche, sollen die damit verknüpften Zeiten auch gelöscht werden!

Versteht Ihr jetzt mein Problem besser? #paralyzed#

Ich habe wirklich stundenlang gestern gegoogelt. Einige hatten ein ähnliches Problem. Die Lösung die vorgeschlagen wurde war, ein eigenes Modul zu machen, die die DB Arbeit selbst macht. Ich habe halt nur die Hoffnung, dass man das nicht doch anders lösen kann.

Gruß,
Benjamin

### [#5](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/5) · woida · 2005-11-05

Du könntest das ganze doch so lösen:
Du legst eine neue Frima an: "Frima1".
Als nächstes legest du einen Mitarbeiter, "Mitarbeiter1" an. In einer Selectbox (im selben Formular) wählst du dann die Firma aus; so ist jeder Mitarbeiter nur in einer Firma.

Nur für das Löschen wirst du dir eine eigene Funktion schreiben müssen.

### [#6](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/6) · BenjaminW · 2005-11-05

> **woida schrieb:**
>
> Du könntest das ganze doch so lösen:
> Du legst eine neue Frima an: "Frima1".
> Als nächstes legest du einen Mitarbeiter, "Mitarbeiter1" an. In einer Selectbox (im selben Formular) wählst du dann die Firma aus; so ist jeder Mitarbeiter nur in einer Firma.

Nun, im konkreten Beispiel geht es ja um Start und Endzeiten von Veranstaltungen. o.O

Das würde bedeuten, dass man ja erst ne Veranstaltung anlegen und anschließend separat Termine anlegen muss, die man dann mit einer Veranstaltung verknüpft. Naja, ich denke da ist der Workflow nicht gerade einfach...

> **woida schrieb:**
>
> Nur für das Löschen wirst du dir eine eigene Funktion schreiben müssen.

Kann man denn sich irgendwie dazwischenklemmen (z.B. ein Hook), wenn ein Datensatz gelöscht wird?

### [#7](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/7) · Stoneage · 2005-11-07

Hallo Benjamin,

Ich programmiere zur Zeit auch eine Veranstaltungsdatenbank, und fand Deine Frage sehr inspirierend. Herzlichen Dank! Ich habe mich sogar gleich drangesetzt und eine Lösung gefunden.

Meine Lösung:

1) in der tabelle veranstaltungen habe ich ein Feld Termine mit einer 1:n Beziehung (genau wie Du beschrieben hast, weak entity) zu der Tabelle tx_termine mit folgender config:

$TCA (Ausschnitt):

```php
   <?php
 	"termine" => Array (		
			"exclude" => 1,		
			"label" => "LLL:EXT:veranstaltungen/locallang_db.php:tx_veranstaltung.termine",		
			"config" => Array (
				"type" => "select",		
				"size" => 10,	
				"minitems" => 0,
				"maxitems" => 20,
				"foreign_table" => "tx_termine",	
				"foreign_table_where" => "AND tx_termine.foreign_uid=###THIS_UID###"
				"wizards" => Array(
					"_PADDING" => 2,
					"_VERTICAL" => 1,
					"add" => Array(
					...
	?>
```

wichtig ist die zeile: "foreign_table_where" => "AND tx_termine.foreign_uid=###THIS_UID###"

    damit hast du schon eine weak entity beziehung. das problem ist nun wie kriege ich die uid von der veranstaltung in die tabelle	tx_termine, wenn man aus der veranstaltung einen neuen termin anlegt? das hat etwas gedauert bis bei mir der groschen fiel. zuerst habe ich gedacht das es über das wizard add skript (wizard_add.php) gehen würde, aber das war eine Sackgasse. Nach langem suchen hatte ich dann die idee das feld foreign_uid in der tabelle tx_termine als typ 'user' anzulegen. damit hat es dann geklappt (siehe step 2)

2) in der tabelle tx_termine habe ich das feld foreign_uid als typ 'user' angelegt (fid (Firmen-ID, Primary Key!) in Deiner Tabelle). in der user funktion habe ich dann ein hidden feld mit der aktuellen eltern uid zurückgegeben, so dass beim speichern des ganzen formulars das feld in die tabelle tx_termine abgespeichert wird! es sieht zwar etwas unschön aus, wenn ein hiddenfeld zurückgegeben wird, weil da automatisch ein normales be feld mit label und tabelle drumrum gewrapt wird, aber ich kann damit leben (der kunde hoffentlich auch). als letztes musste ich noch sicherstellen, dass die foreign_uid nicht belegt ist, weil man die Termine auch direkt bearbeiten kann! in diesem fall wird die (existierende) foreign_uid als hidden feld zurückgegeben.

   Beispiel:

   $TCA:

```php
		<?php
   		'foreign_uid' => Array (
			'exclude' => 1,			
			'config' => Array (
				 'type' => 'user',
				 'userFunc' => 'tx_veranstaltungen_tcaTypeUser->hiddenUID',
			)
		),
		?>
```

die Klasse:

```php
   <?php
   class tx_veranstaltungen_tcaTypeUser {
 
	function hiddenUID($PA, $fobj) {		
		
		if (empty($PA['row']['foreign_uid'])) {
			# create new date or doc			
			$getParams = explode('&',t3lib_div::_GET('returnUrl'));
			foreach ($getParams as $key) {
				$temp = explode("=",$key);
				$getParams[$temp[0]]=$temp[1];
			}			
			return '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.$getParams['P[uid]'].'" />';
		} else {
			# edit date or doc
			return '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.$PA['row']['foreign_uid'].'" />';
		}
		
	}
  }
```

Anmerkung: die eltern uid hole ich mir von der returnUrl, das ist nicht gerade schön, aber es funktionert!

3) fürs löschen habe ich den Hook processCmdmap_preProcess in der klasse tcemain benutzt. siehe auch tt_news.

Beispiel:

   die Registrierung des Hooks in der ext_localconf.php

```php
    <?php
   # Register t3lib_tcemain processCmdmapClass (processCmdmap_preProcess) hook
$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['0'] = 'EXT:veranstaltungen/pi1/class.tx_tcemain.php:tx_tcemain';
	?>
```

die Klasse:

```php
   <?php

	class tx_tcemain {
	
		function processCmdmap_preProcess($command, $table, $id, $value, &$pObj) {		
			if ($command == 'delete' && $table == 'tx_termine') {
				# alle Termine dieser Veranstaltung löschen
				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*','tx_termine','foreign_uid='.$id);			
				$result = array();		
				while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
					$pObj->deleteRecord('tx_termine',$row['uid'], 0);
				}
			}
		} 
    }
	?>
```

Und es funktioniert! Ich kann aus jeder Veranstaltung heraus mehrere Termine anlegen, die Veranstaltung kennt nur zugehörige Termine, wenn ich eine Veranstaltung lösche, werden alle zugehörigen Termine gelöscht. Perfekt! Getestet auf T3 3.8.0.

Ich hab oft in die T3 Core Api geguckt, und kann das nur empfehlen: <https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Index.html>

Viele Grüße,

T.

### [#8](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/8) · steffenk · 2005-11-07

WOW !  8-)

Das finde ich sehr interessant und ich werde mir das genauer zu Gemüte führen, das ist ja kein Einzelfall für diese Anforderung.

Wird Deine Veranstaltungs-Extension auch public ? **interesse bekunde**

### [#9](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/9) · BenjaminW · 2005-11-07

> **Tetramatrix schrieb:**
>
> Ich programmiere zur Zeit auch eine Veranstaltungsdatenbank, und fand Deine Frage sehr inspirierend. Herzlichen Dank! Ich habe mich sogar gleich drangesetzt und eine Lösung gefunden.

VIELEN DANK!!! Das freut mich aber sehr.
Ich werds mir gleich anschauen.  :D

Gruß,
Benjamin

### [#10](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/10) · BenjaminW · 2005-11-07

Es funktioniert tatsächlich. So ganz will mir aber das nicht gefallen. Erstens habe ich jetzt eine doppelte Referenzierung, das heisst, ich habe in der Tabelle Veranstaltungen einen BLOB mit komma-getrennten IDs (kommt gut bei SELECT Abfragen mit JOINs...) und zusätzlich in der Termine Tabelle noch die direkte Referenzierung zu den Veranstaltungen...
Aber wir kommen dem ganzen schon ein gutes Stück näher.

Kann man sich irgendwie die BLOB-Spalte sparen? Dann hätte ich halt noch das Problem, dass ich nicht in der List-Ansicht die Start und Endzeiten als Übersicht habe.

Der Hook-Code hatte einen kleinen Fehler:

```php
<?php
# Register t3lib_tcemain processCmdmapClass (processCmdmap_preProcess) hook
$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'][] = 'EXT:veranstaltungen/pi1/class.tx_tcemain.php:tx_tcemain';
?>
```

Aus dem ['processCmdmapClass']['0'] muss ein ['processCmdmapClass'][] gemacht werden, sonst überschreibt man Hooks von anderen Extensions (tt_news).

Noch als Ergänzung für die interessierte Allgemeinheit  :-)
Hier noch die Hookfunktion fürs Kopieren von Veranstaltungen(Termine werden automatisch mitkopiert), die ich mal dazugescriptet habe. Die muss dazukopiert werden.

```php
<?php
function processCmdmap_postProcess($command, $table, $id, $value, &$pObj)
{
  if ($command == 'copy' && $table == 'tx_weakentitytest_events' 
    and $pObj->copyMappingArray['tx_weakentitytest_events'])
  {
    // Ziel-ID herausfinden. Die steht im copyMappingArray
    $source = $id;
    $dest = $pObj->copyMappingArray['tx_weakentitytest_events'][$source];

    $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 
      'tx_weakentitytest_event_dates',
      'foreign_uid='.$source);

    while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))
    {
      // Datensätze kopieren. foreign_uid remappen
      // auf die neue Veranstaltungs-ID.
      $pObj->copyRecord('tx_weakentitytest_event_dates',$row['uid'],
        $row['pid'],0,array('foreign_uid' => $dest));
    }
  }
}
?>
```

Gruß,
Benjamin

### [#11](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/11) · Stoneage · 2005-11-07

Hallo Benjamin,

das BLOB-Feld kann man eventuell mit einer MM-Tabelle rausschmeissen. In die List-Ansicht kann man sich nur reinhacken (HOOK?), aber wie stellst Du Dir die Ansicht mit mehreren Terminen vor? Das wird ja voll die Fummelarbeit.

Gruß,

T.

### [#12](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/12) · BenjaminW · 2005-11-07

Hi Tetramatrix,

> **Tetramatrix schrieb:**
>
> das BLOB-Feld kann man eventuell mit einer MM-Tabelle rausschmeissen.

Na dann hab ich ja immernoch die doppelte Referenzierung, und das auch noch in einer weiteren Table  :-)

> **Tetramatrix schrieb:**
>
> In die List-Ansicht kann man sich nur reinhacken (HOOK?), aber wie stellst Du Dir die Ansicht mit mehreren Terminen vor? Das wird ja voll die Fummelarbeit.

Ok, dann werd ich das wohl über ein eigenes Web->Modul lösen müssen.

Es ist halt z.Z. irgendwie nur ein riesiger Workaround. Typo3 kennt vom Core her keine identifizierende 1:n Beziehung (außer halt die "pid" Spalte bei z.B. tt_content).

Nachdenkliche Grüße,
Benjamin

### [#13](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/13) · Stoneage · 2005-11-07

> Na dann hab ich ja immernoch die doppelte Referenzierung, und das auch noch in einer weiteren Table

Du könntest doch die foreign_uid in die mm_tabelle packen?

### [#14](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/14) · BenjaminW · 2005-11-07

Hi!

> **Tetramatrix schrieb:**
>
> Du könntest doch die foreign_uid in die mm_tabelle packen?

Hm, geht das denn? Ich habe immer gedacht, dass die mm_table nicht bearbeitet werden kann, zumindest gibts ja dafür keine Konfiguration in der TCA, oder?

Gruß,
Benjamin

### [#15](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/15) · Stoneage · 2005-11-07

Hallo Benjamin,

das aber ne gute idee, oder?

Gruß,

T.

### [#16](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/16) · BenjaminW · 2005-11-07

Hi Tetram.,

> **Tetramatrix schrieb:**
>
> das aber ne gute idee, oder?

Es geht halt nicht um den BLOB, sondern um diese zusätzliche Referenzierung der Veranstaltung zu Termine.
Letztlich gesehen ist das alles irgendwie murks  :-)  von vernünftigem DB-Design ist das weit entfernt.
Das DB Design sollte schon irgendwo entsprechenden Standards genügen (ist Vorgabe des Kunden). Jeder DB Fachmann kriegt Warzen wenn er das sieht *gg*

Ich bin halt noch ein wenig unschlüssig, ob das wirklich das Problem am Schopfe packt. Was wir bisher gemacht haben, ist, dass wir das foreign_table Feature ein wenig eingeschränkt haben. Was aber bleibt ist die **Art und Weise**, wie Typo3 die Referenzierungen macht. Eigentlich sollte die Zuweisung schon dadurch passiert sein, dass ein entsprechender Termin-Datensatz existiert und nicht noch durch eine weitere Zuweisung (ob per BLOB oder mm_table ist letztlich egal). Es ist ja keine M:N Beziehung, Typo3 macht aber eine.
Mein Formular sieht halt jetzt so aus, dass ich zwei Listen habe (links die zugewiesenen und rechts die vorhandenen). Das aber brauche ich eigentlich nicht, sondern nur eine Liste aller Termine, die ich im Veranstaltungs-Formular hinzufügen, bearbeiten und auch löschen (daran zerbreche ich mir grad den Kopf -> wizard) kann.

Grüße,
Benjamin

### [#17](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/17) · Stoneage · 2005-11-07

Hallo Benjamin,

stimmt, das zuweisen mit linker und rechter Spalte ist eigentlich unnötig. das könnte man auch rauschmeissen. meinst du findest eine lösung? Ich habe ja schon den Start gemacht...

Gruß,

T.

### [#18](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/18) · BenjaminW · 2005-11-09

> **Tetramatrix schrieb:**
>
> das könnte man auch rauschmeissen. meinst du findest eine lösung? Ich habe ja schon den Start gemacht...

;)

Ich habe heute nochmal den ganzen Tag getüftelt. Mit Erfolg!
Zuerst habe ich aus dem "termine" Feld in Veranstaltungen ein User-defined Field gemacht. Die Liste baue ich nun selber auf. Außerdem habe ich die Wizards für Hinzufügen, Editieren und Löschen über TCEforms::renderWizards (ein Krampf war das!) um meinen Output gestülpt. Das klappt soweit und sieht auch gut aus. Leider funktioniert es noch nicht so wie ich es will. Delete musste ich über einen eigenen Wizard implementieren und Edit läuft auch noch nicht, weil wizard_edit.php anscheinend die ausgelesene ID nicht kriegt (er geht ja von zwei Listen aus, liest folglich die falsche aus), aber das schaffe ich glaube ich morgen schon (denke ich *gg*). Zur Not bastle ich auch noch den Edit-Wizard selbst...

Ich habe in der core api doku das Flag "noTableWrapping" gesehen (<https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/User/Index.html>).
Wenn ich das richtig verstehe, kann ich hiermit verhindern, dass diese Spalte in die Datenbank geschrieben wird , oder? *hoff*
Zur Not lass ich sonst einfach den BLOB leer, fürs Auslesen vom Frontend-Plugin aus brauch ich ihn ja nicht.

Sobald ich was zeigbares habe, werd ich das hier mal posten; es scheint ja immerhin eine Premiere zu sein  ;-)

Nochmals vielen Dank für die Denkanstöße!

Gruß,
Benjamin

### [#19](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/19) · Stoneage · 2005-11-21

> Ich habe in der core api doku das Flag "noTableWrapping" gesehen (<https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/User/Index.html>).
> Wenn ich das richtig verstehe, kann ich hiermit verhindern, dass diese Spalte in die Datenbank geschrieben wird , oder? *hoff*

das feld wird einfach nicht in der tceform gerendert. bist du weiter gekommen?

### [#20](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/20) · BenjaminW · 2005-11-21

Hallo Tetramatrix,

> **Tetramatrix schrieb:**
>
> das feld wird einfach nicht in der tceform gerendert.

Richtig. Habe ich inzwischen auch mit Bedauern festgestellt. Ich habe einfach die Spalte als VARCHAR definiert. Das ist wenigstens performanter.

> **Tetramatrix schrieb:**
>
> bist du weiter gekommen?

Ja! Es läuft soweit. Hat noch ein paar Kinderkrankheiten, für die ich noch die richtige Medizin suche. Beispielsweise möchte ich Start und Endzeiten bei der Eingabe überprüfen (per Javascript am besten), ob Startzeit kleiner als Endzeit ist.

Sobald ich die Extension für mein derzeitiges Projekt fertig habe, werde ich mich mal an nem WE ransetzen und die wesentlichen Dinge rausisolieren und hier posten bzw. vielleicht mal als Beispiel-Extension auf Typo3.net.

Gruß,
Benjamin

### [#21](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/21) · Stoneage · 2006-06-26

Hallo Benjamin,

> Zuerst habe ich aus dem "termine" Feld in Veranstaltungen ein User-defined Field gemacht. Die Liste baue ich nun selber auf. Außerdem habe ich die Wizards für Hinzufügen, Editieren und Löschen über TCEforms::renderWizards (ein Krampf war das!) um meinen Output gestülpt. Das klappt soweit und sieht auch gut aus. Leider funktioniert es noch nicht so wie ich es will. Delete musste ich über einen eigenen Wizard implementieren und Edit läuft auch noch nicht, weil wizard_edit.php anscheinend die ausgelesene ID nicht kriegt (er geht ja von zwei Listen aus, liest folglich die falsche aus), aber das schaffe ich glaube ich morgen schon (denke ich *gg*). Zur Not bastle ich auch noch den Edit-Wizard selbst...

Ich habe jetzt sowas ähnliches gemacht. Vielen Dank für Deine Hilfe!

T.

### [#22](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/22) · Stoneage · 2006-08-07

Hier mal meine Lösung:

In der ext_tables.php die neue Klasse tx_chvacationindex_tcaSingleBox inludieren:

```php
// class for rendering a singlebox by a user function or class method.
include_once(t3lib_extMgm::extPath($_EXTKEY).'TCA/class.tx_chvacationindex_tcaSingleBox.php');
```

In der tca.php die user function tx_chvacationindex_tcaSingleBox->singleBox aufrufen:

```typoscript
'config' => Array (
 				'type' => 'select',
                                'form_type' => 'user',
				'userFunc' => 'tx_chvacationindex_tcaSingleBox->singleBox',
				'size' => 10,
				'minitems' => 0,
				'maxitems' => 100,
				'foreign_table' => 'tx_chvacationindex_accommodation',	
				'foreign_table_where' => 'AND tx_chvacationindex_accommodation.parent_uid=###THIS_UID###',
				'MM' => 'tx_chvacationindex_accommodation_mm',
                    )
```

Die Klasse "tx_chvacationindex_tcaSingleBox" zum abspeichern:

```php
<?php

/***************************************************************
*  Copyright notice
*
*  (c) 2006 Chi Hoang (chibox@gmail.com)
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project 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.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script 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.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

require_once(PATH_t3lib.'class.t3lib_tceforms.php');
 
class tx_chvacationindex_tcaSingleBox extends t3lib_TCEforms {

	function singleBox($PA, $fobj) {		
	    global $TCA;
        
			// Field configuration from TCA:
		$config = $PA['fieldConf']['config'];

			// "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/.
		$specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']);

			// Getting the selector box items from the system
		$selItems = $this->addSelectOptionsToItemArray($this->initItemArray($PA['fieldConf']),$PA['fieldConf'],$this->setTSconfig($PA['fieldConf']['config']['foreign_table'],$PA['row']),$field);
        $selItems = $this->addItems($selItems,$PA['fieldTSConfig']['addItems.']);

        if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$PA['fieldTSConfig']['itemsProcFunc.'],$config,$table,$row,$field);

			// Possibly remove some items:
		$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
        
		foreach($selItems as $tk => $p)	{
				// Checking languages and authMode:
			$languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]);
			$authModeDeny = $config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$p[1],$config['authMode']);
			if (in_array($p[1],$removeItems) || $languageDeny || $authModeDeny)	{
				unset($selItems[$tk]);
			} elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) {
				$selItems[$tk][0]=$this->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]);
			}

				// Removing doktypes with no access:
			if ($table.'.'.$field == 'pages.doktype')	{
				if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'],$p[1])))	{
					unset($selItems[$tk]);
				}
			}
		}

			// Creating the label for the "No Matching Value" entry.
		$nMV_label = isset($PA['fieldTSConfig']['noMatchingValue_label']) ? $this->sL($PA['fieldTSConfig']['noMatchingValue_label']) : '[ '.$this->getLL('l_noMatchingValue').' ]';

			// Prepare some values:
		$maxitems = intval($config['maxitems']);        

        return $this->getSingleBox($PA['table'],$PA['field'],$PA['row'],$PA,$config,$selItems,$nMV_Label);  
	}

	/**
	 * Creates a multiple-selector box (two boxes, side-by-side)
	 * (Render function for getSingleField_typeSelect())
	 *
	 * @param	string		See getSingleField_typeSelect()
	 * @param	string		See getSingleField_typeSelect()
	 * @param	array		See getSingleField_typeSelect()
	 * @param	array		See getSingleField_typeSelect()
	 * @param	array		(Redundant) content of $PA['fieldConf']['config'] (for convenience)
	 * @param	array		Items available for selection
	 * @param	string		Label for no-matching-value
	 * @return	string		The HTML code for the item
	 * @see getSingleField_typeSelect()
	 */
	function getSingleBox($table,$field,$row,&$PA,$config='',$selItems='',$nMV_label='')	{

			// Setting this hidden field (as a flag that JavaScript can read out)
		$item.= '<input type="hidden" name="'.$PA['itemFormElName'].'_mul" value="'.($config['multiple']?1:0).'" />';

			// Set max and min items:
		$maxitems = t3lib_div::intInRange($config['maxitems'],0);
		if (!$maxitems)	$maxitems=100000;
		$minitems = t3lib_div::intInRange($config['minitems'],0);

			// Register the required number of elements:
		$this->requiredElements[$PA['itemFormElName']] = array($minitems,$maxitems,'imgName'=>$table.'_'.$row['uid'].'_'.$field);

			// Get "removeItems":
		$removeItems = t3lib_div::trimExplode(',',$PA['fieldTSConfig']['removeItems'],1);
             
			// Perform modification of the selected items array:
		$itemArray = t3lib_div::trimExplode(',',$PA['itemFormElValue'],1);
        
        foreach ($itemArray as $k => $v) {
            $tvP = explode('|',$v,2);
            $iA[$tvP[0]]=rawurldecode($tvP[1]); 
        }
        
        foreach ($selItems as $k) {
            if (!$iA[$k[1]]) {
                $iA[$k[1]] = $k[0];
            }            
        }        
        
        $itemArray=array();
        
        foreach ($iA as $k => $v) {
            $itemArray[] = $k.'|'.rawurlencode($v);
        }
        
		foreach($itemArray as $tk => $tv) {
			$tvP = explode('|',$tv,2);            
			$evalValue = rawurldecode($tvP[0]);
			$isRemoved = in_array($evalValue,$removeItems)  || ($config['form_type']=='select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table,$field,$evalValue,$config['authMode']));
			if ($isRemoved && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement'])	{
				$tvP[1] = rawurlencode(@sprintf($nMV_label, $evalValue));
			} elseif (isset($PA['fieldTSConfig']['altLabels.'][$evalValue])) {
				$tvP[1] = rawurlencode($this->sL($PA['fieldTSConfig']['altLabels.'][$evalValue]));
			} else {
				$tvP[1] = rawurlencode($this->sL(rawurldecode($tvP[1])));
			}
			$itemArray[$tk] = implode('|',$tvP);
		}

		$size = intval($config['size']);
		$size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray)+1,t3lib_div::intInRange($size,1),$config['autoSizeMax']) : $size;
        
			// Pass to "dbFileIcons" function:
		$params = array(
			'size' => $size,
			'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'],0),
			'style' => isset($config['selectedListStyle']) ? ' style="'.htmlspecialchars($config['selectedListStyle']).'"' : ' style="'.$this->defaultMultipleSelectorStyle.'"',
			'dontShowMoveIcons' => ($maxitems<=1),
			'maxitems' => $maxitems,
			'info' => '',
			'headers' => array(
				'selector' => $this->getLL('l_selected').':<br />',
				'items' => $this->getLL('l_items').':<br />'
			),
			'noBrowser' => 1,
			'thumbnails' => $itemsToSelect
		);        
        
		$item .= $this->dbFileIconsSingleBox($PA['itemFormElName'],'','',$itemArray,'',$params,$PA['onFocus']);
        $item = $this->renderWizards(array($item,$altItem),$config['wizards'],$table,$row,$field,$PA,$PA['itemFormElName'],$specConf,$RTEwouldHaveBeenLoaded);
        
		return $item;
	}
    
    	/**
	 * Prints the selector box form-field for the db/file/select elements (multiple)
	 *
	 * @param	string		Form element name
	 * @param	string		Mode "db", "file" (internal_type for the "group" type) OR blank (then for the "select" type)
	 * @param	string		Commalist of "allowed"
	 * @param	array		The array of items. For "select" and "group"/"file" this is just a set of value. For "db" its an array of arrays with table/uid pairs.
	 * @param	string		Alternative selector box.
	 * @param	array		An array of additional parameters, eg: "size", "info", "headers" (array with "selector" and "items"), "noBrowser", "thumbnails"
	 * @param	string		On focus attribute string
	 * @return	string		The form fields for the selection.
	 */
	function dbFileIconsSingleBox($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='')	{

			// Sets a flag which means some JavaScript is included on the page to support this element.
		$this->printNeededJS['dbFileIcons']=1;

			// INIT
		$uidList=array();
		$opt=array();
		$itemArrayC=0;

			// Creating <option> elements:
		if (is_array($itemArray))	{
			$itemArrayC=count($itemArray);
			reset($itemArray);
			switch($mode)	{
				case 'db':
					while(list(,$pp)=each($itemArray))	{
						$pRec = t3lib_BEfunc::getRecord($pp['table'],$pp['id']);
						if (is_array($pRec))	{
							$pTitle = t3lib_div::fixed_lgd_cs($this->noTitle($pRec[$GLOBALS['TCA'][$pp['table']]['ctrl']['label']]),$this->titleLen);
							$pUid = $pp['table'].'_'.$pp['id'];
							$uidList[]=$pUid;
							$opt[]='<option value="'.htmlspecialchars($pUid).'">'.htmlspecialchars($pTitle).'</option>';
						}
					}
				break;
				case 'file':
					while(list(,$pp)=each($itemArray))	{
						$pParts = explode('|',$pp);
						$uidList[]=$pUid=$pTitle = $pParts[0];
						$opt[]='<option value="'.htmlspecialchars(rawurldecode($pParts[0])).'">'.htmlspecialchars(rawurldecode($pParts[0])).'</option>';
					}
				break;
				default:
					while(list(,$pp)=each($itemArray))	{
						$pParts = explode('|',$pp);
						$uidList[]=$pUid=$pParts[0];
						$pTitle = $pParts[1];
						$opt[]='<option value="'.htmlspecialchars(rawurldecode($pUid)).'">'.htmlspecialchars(rawurldecode($pTitle)).'</option>';
					}
				break;
			}
		}

			// Create selector box of the options
		$sSize = $params['autoSizeMax'] ? t3lib_div::intInRange($itemArrayC+1,t3lib_div::intInRange($params['size'],1),$params['autoSizeMax']) : $params['size'];
		if (!$selector)	{
			$selector = '<select size="'.$sSize.'" this-="">insertDefStyle('group').' multiple="multiple" name="'.$fName.'_list" '.$onFocus.$params['style'].'>'.implode('',$opt).'</select>';
		}

		$icons = array(
			'L' => array(),
		);
        
		if (!$params['dontShowMoveIcons'])	{
			if ($sSize>=5)	{
				$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Top\'); return false;">'.
						'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_totop.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_to_top')).' />'.
						'</a>';
			}
			$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Up\'); return false;">'.
					'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/up.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_up')).' />'.
					'</a>';
			$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Down\'); return false;">'.
					'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/down.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_down')).' />'.
					'</a>';
			if ($sSize>=5)	{
				$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Bottom\'); return false;">'.
						'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_tobottom.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_move_to_bottom')).' />'.
						'</a>';
			}
		}
        
		$icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$fName.'\',\'Remove\'); return false;">'.
				'<img'.t3lib_iconworks::skinimg($this->backPath,'gfx/group_clear.gif','width="14" height="14"').' border="0" '.t3lib_BEfunc::titleAltAttrib($this->getLL('l_remove_selected')).' />'.
				'</a>';

		$str='<table border="0" cellpadding="0" cellspacing="0" width="1">
			'.($params['headers']?'
				<tr>
					<td>'.$this->wrapLabels($params['headers']['selector']).'</td>
					<td></td>
					<td></td>
					<td></td>
				</tr>':'').
			'
			<tr>
				<td valign="top">'.
					$selector.'<br />'.
					$this->wrapLabels($params['info']).
				'</td>
				<td valign="top">'.
					implode('<br />',$icons['L']).'</td>
				<td valign="top"></td>
				<td><img src="clear.gif" width="5" height="1" alt="" /></td>
			</tr>
		</table>';

			// Creating the hidden field which contains the actual value as a comma list.
		$str.='<input type="hidden" name="'.$fName.'" value="'.htmlspecialchars(implode(',',$uidList)).'" />';

		return $str;
	}
}
?>
```

### [#23](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/23) · L1NU5 · 2006-08-08

Vielen Dank für das Posten deiner Lösung!

Dein Script enthält einen kleinen Fehler in Zeile 223:

```php
$selector = '<select size="'.$sSize.'" this-="">insertDefStyle('group').' multiple="multiple" name="'.$fName.'_list"
```

müsste eigentlich folgendermassen heissen:

```php
$selector = '<select size="'.$sSize.'" this-="">insertDefStyle('group') . ' multiple="multiple" name="'.$fName.'_list"
```

Leider funktionieren auch die Wizards nicht  :'(
Habe es auf einem ähnlichem Weg versucht, aber den part mit den Wizards leider auch nicht hinbekommen...

Vielleicht kennt ja Jemand 'ne Lösung, oder Benjamin präsentiert mal seine  #paralyzed#

Gruß Linus

### [#24](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/24) · Stoneage · 2006-08-09

Die PHP Anzeige vom Forum funktioniert wohl nicht ganz richtig. #angry#  Die hat kleinere Probleme mit dem Parsen. Mein Skript ist schon korrekt. Es muß natürlich so heissen:

```php
... $this->insertDefStyle('group') ...
```

Die Wizards (Add, List, Edit) funktionieren bei mir aber ganz gut. Die haben mit meinem Skript rein gar nichts zu tun. Die tust Du nach wie vor in der $TCA inkludieren:

```php
'config' => Array (
    'MM' => 'tx_chvacationindex_accommodation_mm',
    'wizards' => Array(
        '_PADDING' => 2,
        '_VERTICAL' => 1,
        'add' => Array(
            'type' => 'script',
            'title' => 'Create new record',
            'icon' => 'add.gif',
            'params' => Array(
                'table'=>'tx_chvacationindex_accommodation',
                'pid' => '###CURRENT_PID###',
                'setValue' => 'append'
            ),
            'script' => 'wizard_add.php',
        ),
        'list' => Array(
            'type' => 'script',
            'title' => 'List',
            'icon' => 'list.gif',
            'params' => Array(
                'table'=>'tx_chvacationindex_accommodation',
                'pid' => '###CURRENT_PID###',
            ),
            'script' => 'wizard_list.php',
        ),
        'edit' => Array(
            'type' => 'popup',
            'title' => 'Edit',
            'script' => 'wizard_edit.php',
            'icon' => 'edit2.gif',
            'popup_onlyOpenIfSelected' => 1,						
            'JSopenParams' => 'height=800,width=630,status=0,menubar=0,scrollbars=1',
        ),
    )
```

### [#25](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/25) · L1NU5 · 2006-08-09

> Die PHP Anzeige vom Forum funktioniert wohl nicht ganz richtig. #angry# Die hat kleinere Probleme mit dem Parsen.

#giggle# War mir gestern garnicht aufgefallen!

> Die Wizards (Add, List, Edit) tust Du nach wie vor in der $TCA inkludieren:

Ja, schon klar, aber irgendwie funktioniert bei mir das Selektieren eines Eintrags in der Selectbox nicht richtig,
so dass Edit immer nur ausspuckt, dass kein Eintrag markiert ist...

Ausserdem kann ich auch keinen Eintrag aus der Selectbox löschen...

Naja, keine Ahnung wo bei mir da das Problem ist, aber ich werde mich Morgen nochmal ransetzen.

Vielen Dank für deine Hilfe!

### [#26](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/26) · hnesk · 2006-09-06

Hmmm, bin hier gerade nur so reingeschlittert, aber kann es ein dass du versuchst, die Einträge in der rechten Box zu bearbeiten? Die Wizards beziehen sich auf die linke Seite, habe ich mir auch schon mal ein wenig den Kopf drüber zerbrochen.

### [#27](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/27) · alexhaupt · 2007-01-12

Hallo Tetramatrix,
hallo BenjaminW,

vielen Dank für Eure Codesnippel. Exat vor dem gleichen Problem stande ich auch, bevor ich Euren Thread gelesen habe.

Wollte mal nach der langen Zeit mal nachfragen, ob Ihr oder irgendjemand anderes eine Lösung für das löschen eines Termines gefunden hat bzw. einen eigenen Wizard für das löschen geschrieben hat?

Und nochmal danke an die beiden Code-Poster, Ihr habt mir sehr viel Kopfschmerzen erspart :).

Schönen Gruß
Alex

### [#28](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/28) · BenjaminW · 2007-01-12

Hallo zusammen!

Kaum zu glauben, aber es tut sich was im T3 Core diesbezüglich #giggle#
<http://typo3.org/news-single-view/?tx_newsimporter_pi1%5BshowItem%5D=5&cHash=489a4a5ad7#single>

Schönes Wochenende!

Gruß,
Benjamin

### [#29](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/29) · alexhaupt · 2007-01-15

Servus Benjamin,

hast Du aus eigentlich eine Ext veröffentlicht? Dann kann ich mir mal anschauen, wie Du die Löschfunktionen implementiert hast.

Schönen Gruß
Alex

### [#30](https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen/30) · BenjaminW · 2007-01-15

Hier schonmal der Code für die tceMain Hooks (löscht Termine von Veranstaltungen, wenn diese gelöscht werden, gleiches Spiel beim Kopieren):

```php
<?php
	class tx_ccseminare_tcemain {

		function get1nHiddenUID(&$PA, &$fObj)
		{
			global $TCA;

			$ret = '';

			$foreign_uid = 0;
			$foreign_table = $TCA[$PA['table']]['ctrl']['1n_parent'];

			if (empty($PA['row'][$TCA[$PA['table']]['ctrl']['1n_foreign_field']]))
			{
				$url = parse_url(t3lib_div::_GP('returnUrl'));
				$query = $url['query'];
				$url_vars = array();
				parse_str($query, $url_vars);

				$foreign_uid = $url_vars['P']['uid'];
			}
			else
			{
				// edit date or doc
				$foreign_uid = $PA['row'][$TCA[$PA['table']]['ctrl']['1n_foreign_field']];
			}

			if ($foreign_uid)
			{
				$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,'.$TCA[$foreign_table]['ctrl']['label'], $foreign_table, 'uid = "'.$foreign_uid.'"');
				$result = array();

				$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);

				$ret .= '<p>'.$row[$TCA[$foreign_table]['ctrl']['label']].' ['.$row['uid'].'] </p>';
				$ret .= '<input type="hidden" name="'.$PA['itemFormElName'].'" value="'.$foreign_uid.'" />';
			}
			else
			{
				// TODO!!!
				$msg = 'Sie können keinen Termin ohne Fortbildung/Seminar erstellen!!!';
				$ret .= '<table class="warningbox" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td><img src="gfx/icon_fatalerror.gif" class="absmiddle" alt="" height="16" width="18">'.$msg.'</td></tr></tbody></table>';
			}

			return $ret;
		}

		function find1nChilds($table)
		{
			global $TCA;

			$childs = array();

			foreach($TCA as $child_table => $table_config)
			{
				if ($table_config['ctrl']['1n_parent'] and $table_config['ctrl']['1n_parent']==$table)
				{
					$childs[] = $child_table;
				}
			}

			return $childs;
		}

		/**
		 * Hook Funktion for pre-processing the delete command on events table
		 * It will trigger deletion of 1:n records
		 */
		function processCmdmap_preProcess($command, $table, $id, $value, &$pObj)
		{
			global $TCA;

			if ($command == 'delete')
			{
				$childs = $this->find1nChilds($table);

				// This table has child records in a different table. So delete them, too!
				if (is_array($childs) and count($childs) > 0)
				{
					foreach($childs as $child)
					{
						$table_ctrl = $TCA[$child]['ctrl'];

						$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid',$child,
								$table_ctrl['1n_foreign_field'].'='.$id
									.($table_ctrl['delete'] ? ' AND '.$table_ctrl['delete'].'=0' : '')
								);

						$result = array();

						while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
							$pObj->deleteRecord($child,$row['uid'], 0);
						}
					}
				}
			}
		}

		/**
		 * Hook Funktion for post-processing the copy command on `events` table
		 * It will trigger the copying of related `dates`
		 */
		function processCmdmap_postProcess($command, $table, $id, $value, &$pObj)
		{
			global $TCA;

			if ($command == 'copy')
			{
				$childs = $this->find1nChilds($table);

				if (is_array($childs) and count($childs) > 0 and $pObj->copyMappingArray[$table])
				{
					// Ziel-ID herausfinden. Die steht im copyMappingArray
					$dest = $pObj->copyMappingArray[$table][$id];

					foreach($childs as $child)
					{
						$table_ctrl = $TCA[$child]['ctrl'];
						$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid, pid', $child,
								$table_ctrl['1n_foreign_field'].'='.$id
									.($table_ctrl['delete'] ? ' AND '.$table_ctrl['delete'].'=0' : '')
								);

						while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
							// Datensätze kopieren. foreign_uid remappen auf die neue Veranstaltungs-ID.
							$pObj->copyRecord($child,$row['uid'],$row['pid'],0,array($table_ctrl['1n_foreign_field'] => $dest));
						}
					}
				}
			}
		}

		/**
		 * Simple Hook which just erases content in `dates` field of tx_ccseminare_further_educations
		 **/
		function processDatamap_postProcessFieldArray($command, $table, $id, &$value, &$pObj)
		{
/*			if ($table == 'tx_ccseminare_further_educations' and in_array($command, array('new', 'update'))) {
				$value['dates'] = '';
			}
			else if ($table == 'tx_ccseminare_further_educations')
			{
//				debug($command);
//				debug($id);
//				debug($value);
			}
*/
		}

	}

	if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cc_seminare/class.tx_ccseminare_tcemain.php'])    {
	    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cc_seminare/class.tx_ccseminare_tcemain.php']);
	}

?>
```

Den Löschen-Wizard musste ich selber machen:

```php
<?php
define('TYPO3_MOD_PATH', '../typo3conf/ext/cc_seminare/');
$BACK_PATH='../../../typo3/';
require ($BACK_PATH.'init.php');
require ($BACK_PATH.'template.php');
$LANG->includeLLFile('EXT:lang/locallang_wizards.xml');
require_once (PATH_t3lib.'class.t3lib_page.php');
require_once (PATH_t3lib.'class.t3lib_pagetree.php');
require_once (PATH_t3lib.'class.t3lib_tcemain.php');
require_once (PATH_t3lib.'class.t3lib_tceforms.php');

/**
 * Script Class for redirecting the user to the Web > List module if a wizard-link has been clicked in TCEforms
 *
 * @author	Benjamin Wilger
 */
class tx_ccseminare_wizard_delete {

	// Internal, static: GPvars
	var $P;						// Wizard parameters, coming from TCEforms linking to the wizard.
	var $confirmed = false;		// Contains true, if the user confirmed the deletion of the record
								// will be set in init()!

	var $content;				// Content of the page. Output it with outputContent()

	var $table;					// Holds Tablename needed for deletion of the record
	var $uid;					// uid of Record to delete.


	/**
	 * Initialization of the class, setting GPvars.
	 *
	 * @return	void
	 */
	function init()	{
		$this->P = t3lib_div::_GP('P');
		$this->confirmed = t3lib_div::_GP('confirmed');

		$this->table = $this->P['table'];
		$this->uid = $this->P['currentValue'];
	}

	function main()	{
		if (t3lib_div::testInt($this->uid) and $this->confirmed)
		{
			// Make instance of TCEmain class needed for deletion of records
			$deleteTCE = t3lib_div::makeInstance('t3lib_TCEmain');
			$deleteTCE->stripslashes_values = 0;
			// Init
			$deleteTCE->start(0, '');
			// Fire up the deleteRecord() method
			$deleteTCE->deleteRecord($this->table,$this->uid, 0);

			$this->closeWindowRefresh();
		}
		else if (t3lib_div::testInt($this->uid))
		{
			// debug($GLOBALS['TBE_TEMPLATE']);
			$tmpl = t3lib_div::makeInstance('smallDoc');
			$tmpl->form = '<form action="'.htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')).'" name="_confirmform" method="post">';

			$this->content .= $tmpl->startPage('Datensatz löschen?');
			$this->content .= $tmpl->header('Wirklich löschen?');

			$this->content .= '<input type="submit" value="JA" name="confirmed" />';
			$this->content .= '&nbsp;&nbsp;';
			$this->content .= '<input type="button" onclick="window.close()" value="NEIN" name="_cancelbutton" />';
			$this->content .= $tmpl->endPage();
		}

		//debug(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'));


	}

	function outputContent()
	{
		echo $this->content;
	}

	/**
	 * Printing a little JavaScript to close the open window and submitting the form.
	 *
	 * @return	void
	 */
	function closeWindowRefresh()	{
		echo '<script language="javascript" type="text/javascript">';
		echo 'if (opener && !opener.closed) opener.TBE_EDITOR_submitForm();';
		echo 'window.close();';
		echo '</script>';
		exit;
	}
}

if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cc_seminare/wizard_delete.php'])    {
    include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cc_seminare/wizard_delete.php']);
}

// Make instance:
$SOBE = t3lib_div::makeInstance('tx_ccseminare_wizard_delete');
$SOBE->init();
$SOBE->main();
$SOBE->outputContent();

?>
```

Der Lösch-Wizard ist Quick&Dirty aus verschiedenen anderen Wizards zusammengepasted und sieht auch nicht gut aus :-)

Hoffe das hilft weiter

---

Quelle: „Schwaches Entity (weak entity) in Datensätzen“, typo3.net, https://www.typo3.net/d/32753-schwaches-entity-weak-entity-in-datensaetzen
Beiträge von Mitgliedern des Forums. Bitte mit Link auf die Diskussion zitieren.
