Zum Inhalt springen

symmetric Relation

Erstellt am 16. März 2015 · 7 Antworten · letzte Antwort am 28. März 2015

Tags: Frage

p-steve ·

Hallo,

ich versuche eine symmetrische Beziehung innerhalb einer Tabelle (https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/Inline/Index.html) zu realisieren.

Im Backend funktioniert auch alles super. Allerdings bekomme ich im Frondend die Fehlermeldung:

Unknown column 'tx_osw_domain_model_standard.person_symmetric' in 'where clause'

Was auch sicher richtig ist, da dieses Feld ja nur in der Zwischentabelle existiert.
Wird hier die Relation nicht richtig aufgelöst oder muss ich noch irgendetwas konfigurieren?

Vielen Dank für Eure Hilfe!

Unbekannter Benutzer ·

Da du keine Angaben machst, was du konfiguriert hast, kann auch niemand sagen, ob du "noch etwas" konfigurieren musst.

Interessant wären dein Model und dein TCA.
Warum sollte das Feld person_symmetric in deiner Zwischentabelle stehen? In deiner Relation-Table sollte eigentlich nur die uid, und die foreign id stehen.

p-steve ·

Hier kommt mein Model:

class Standard extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

	/**
	 * name
	 *
	 * @var string
	 * @validate NotEmpty
	 */
	protected $name = '';

	/**
	 * person
	 *
	 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Standard>
	 */
	protected $person = NULL;

	/**
	 * __construct
	 */
	public function __construct() {
		//Do not remove the next line: It would break the functionality
		$this->initStorageObjects();
	}

	/**
	 * Initializes all ObjectStorage properties
	 * Do not modify this method!
	 * It will be rewritten on each save in the extension builder
	 * You may modify the constructor of this class instead
	 *
	 * @return void
	 */
	protected function initStorageObjects() {
		$this->person = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
	}

	/**
	 * Returns the name
	 *
	 * @return string $name
	 */
	public function getName() {
		return $this->name;
	}

	/**
	 * Sets the name
	 *
	 * @param string $name
	 * @return void
	 */
	public function setName($name) {
		$this->name = $name;
	}

	/**
	 * Adds a Standard
	 *
	 * @param \Osw\Osw\Domain\Model\Standard $person
	 * @return void
	 */
	public function addPerson(\Osw\Osw\Domain\Model\Standard $person) {
		$this->person->attach($person);
	}

	/**
	 * Removes a Standard
	 *
	 * @param \Osw\Osw\Domain\Model\Standard $personToRemove The Standard to be removed
	 * @return void
	 */
	public function removePerson(\Osw\Osw\Domain\Model\Standard $personToRemove) {
		$this->person->detach($personToRemove);
	}

	/**
	 * Returns the person
	 *
	 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Standard> $person
	 */
	public function getPerson() {
		return $this->person;
	}

	/**
	 * Sets the person
	 *
	 * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Standard> $person
	 * @return void
	 */
	public function setPerson(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $person) {
		$this->person = $person;
	}

}

das TCA von Standard:

$GLOBALS['TCA']['tx_osw_domain_model_standard'] = array(
	'ctrl' => $GLOBALS['TCA']['tx_osw_domain_model_standard']['ctrl'],
	'interface' => array(...),
	'types' => array(...'),
	'palettes' => array(...),
	'columns' => array(
		'name' => array(
			'exclude' => 1,
			'label' => 'LLL:EXT:osw/Resources/Private/Language/locallang_db.xlf:tx_osw_domain_model_standard.name',
			'config' => array(
				'type' => 'input',
				'size' => 30,
				'eval' => 'trim,required'
			),
		),
		'person' => array(
			'exclude' => 1,
			'label' => 'LLL:EXT:osw/Resources/Private/Language/locallang_db.xlf:tx_osw_domain_model_standard.relation',
			'config' => array(
                'type' => 'inline',
                'foreign_table' => 'tx_osw_person_symmetric_mm',
                'foreign_field' => 'person_symmetric',
                'foreign_sortby' => 'sorting_person',
                'foreign_label' => 'spouse',
                'symmetric_field' => 'spouse',
                'symmetric_sortby' => 'sorting_spouse',
                'symmetric_label' => 'person',
			),
		),
		
	),
);

und das TCA der Zwischentabelle:

$GLOBALS['TCA']['tx_osw_person_symmetric_mm'] = array(
    'ctrl' => $GLOBALS['TCA']['tx_osw_person_symmetric_mm']['ctrl'],
    'interface' => array(...),
    'types' => array(...),
    'palettes' => array(...),
    ),
    'columns' => array(
        'person_symmetric' => array(
            'exclude' => 0,
            'label' => 'person',
            'config' => array(
                'type' => 'input',
                'foreign_table' => 'tx_osw_domain_model_standard',
                'minitems' => 0,
                'maxitems' => 1,
            ),
        ),
        'sorting_person' => array(
            'exclude' => 0,
            'config' => array(
                'type' => 'passthrough',
            ),
        ),

        'spouse' => array(
            'exclude' => 0,
            'label' => 'spouse',
            'config' => array(
                'type' => 'input',
                'foreign_table' => 'tx_osw_domain_model_standard',
                'minitems' => 0,
                'maxitems' => 1,
            ),
        ),
        'sorting_spouse' => array(
            'exclude' => 0,
            'config' => array(
                'type' => 'passthrough',
            ),
        ),


    ),
);

Wie oben schon gesagt: Im Backend wird die Relation ordentlich dargestellt. Nur im Frontend kommt es zu einem Fehler.

harald1972 ·

Moin,

ich versteh zwar nicht im geringsten, was das ganze soll. Aber den Teil, den ich gelesen hab, hab ich wie folgt verstanden:

Du hst also eine Klasse namens "Standard"... welche scheinbar (vielleicht?) eine Person darstellen soll.
Dieser Klasse verpasst du einen ObjectStorage von Standards und nennst ihn "person".
Ein Standard hat also eine person, welche aus beliebig vielen Standards besteht.
Sorry, aber Sinn und Semantik sehe ich dahinter nicht.

Die Methode "addPerson" wird kommentiert mit "adds a Standard", usw...

Achja... ist zwar nur ein "label", aber das von person suchst du unter "relation"

'person' => array(
'exclude' => 1,
'label' => 'LLL:EXT<i class="mmforum-iconset-20-surprised"></i>sw/Resources/Private/Language/locallang_db.xlf:tx_osw_domain_model_standard.relation',

Ich will ja nicht klugscheißen, aber eine stringente Namensgebung macht Code gleich viel lesbarer.
...und wo ich die Stelle grad seh... fehlt da nicht ein 'o' vor 'sw/Resources/Private...'?

p-steve ·

So jetzt noch mal von vorn, in der Hoffnung, dass es jetzt verständlicher ist.
Ich möchte über die symmetrische Relation folgendes erreichen. Wenn ich einer Person A eine Beziehung zu einer Person B zuweise, soll automatisch auch eine Beziehung von Person B nach Person A angelegt werden.
Funktioniert auch prima im Backend. Im Frontend wird folgender Fehler angezeigt:
Unknown column 'tx_osw_domain_model_person.beziehung_von' in 'where clause'

Mein Model:

class Person extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

	/**
	 * name
	 *
	 * @var string
	 * @validate NotEmpty
	 */
	protected $name = '';

	/**
	 * beziehung
	 *
	 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Person>
	 */
	protected $beziehung = NULL;

	/**
	 * __construct
	 */
	public function __construct() {
		//Do not remove the next line: It would break the functionality
		$this->initStorageObjects();
	}

	/**
	 * Initializes all ObjectStorage properties
	 * Do not modify this method!
	 * It will be rewritten on each save in the extension builder
	 * You may modify the constructor of this class instead
	 *
	 * @return void
	 */
	protected function initStorageObjects() {
		$this->beziehung = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
	}

	/**
	 * Returns the name
	 *
	 * @return string $name
	 */
	public function getName() {
		return $this->name;
	}

	/**
	 * Sets the name
	 *
	 * @param string $name
	 * @return void
	 */
	public function setName($name) {
		$this->name = $name;
	}

	/**
	 * Adds a beziehung
	 *
	 * @param \Osw\Osw\Domain\Model\Person $beziehung
	 * @return void
	 */
	public function addBeziehung(\Osw\Osw\Domain\Model\Person $beziehung) {
		$this->beziehung->attach($beziehung);
	}

	/**
	 * Removes a beziehung
	 *
	 * @param \Osw\Osw\Domain\Model\Person $beziehungToRemove The Person to be removed
	 * @return void
	 */
	public function removeBeziehung(\Osw\Osw\Domain\Model\Person $beziehungToRemove) {
		$this->beziehung->detach($beziehungToRemove);
	}

	/**
	 * Returns the beziehung
	 *
	 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Person> $beziehung
	 */
	public function getBeziehung() {
		return $this->beziehung;
	}

	/**
	 * Sets the beziehung
	 *
	 * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Osw\Osw\Domain\Model\Person> $beziehung
	 * @return void
	 */
	public function setBeziehung(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $beziehung) {
		$this->beziehung = $beziehung;
	}

}

TCA der Person:

$GLOBALS['TCA']['tx_osw_domain_model_person'] = array(
	'ctrl' => $GLOBALS['TCA']['tx_osw_domain_model_person']['ctrl'],
	'interface' => array(...),
	'types' => array(...),
	'palettes' => array(...),
	),
	'columns' => array(
		'name' => array(
			'exclude' => 1,
			'label' => 'LLL:EXT:osw/Resources/Private/Language/locallang_db.xlf:tx_osw_domain_model_person.name',
			'config' => array(
				'type' => 'input',
				'size' => 30,
				'eval' => 'trim,required'
			),
		),
		'beziehung' => array(
			'exclude' => 1,
			'label' => 'LLL:EXT:osw/Resources/Private/Language/locallang_db.xlf:tx_osw_domain_model_person.beziehung',
			'config' => array(
				'type' => 'inline',
                'foreign_table' => 'tx_osw_person_symmetric_mm',
                'foreign_field' => 'beziehung_von',
                'foreign_sortby' => 'sorting_beziehung_von',
                'symmetric_field' => 'beziehung_zu',
                'symmetric_sortby' => 'sorting_beziehung_zu',
			),
		),
		
	),
);

TCA der Zwischentabelle:

$GLOBALS['TCA']['tx_osw_person_symmetric_mm'] = array(
    'ctrl' => $GLOBALS['TCA']['tx_osw_person_symmetric_mm']['ctrl'],
    'interface' => array(...),
    'types' => array(...),
    'palettes' => array(...),
    ),
    'columns' => array(
        'beziehung_von' => array(
            'exclude' => 0,
            'label' => 'beziehung_von',
            'config' => array(
                'type' => 'input',
                'foreign_table' => 'tx_osw_domain_model_person',
                'minitems' => 0,
                'maxitems' => 1,
            ),
        ),
        'sorting_person' => array(
            'exclude' => 0,
            'config' => array(
                'type' => 'passthrough',
            ),
        ),
        'beziehung_zu' => array(
            'exclude' => 0,
            'label' => 'beziehung_zu',
            'config' => array(
                'type' => 'input',
                'foreign_table' => 'tx_osw_domain_model_person',
                'minitems' => 0,
                'maxitems' => 1,
            ),
        ),
        'sorting_beziehung_zu' => array(
            'exclude' => 0,
            'config' => array(
                'type' => 'passthrough',
            ),
        ),
    ),
);
harald1972 ·

Wie zooloohed schon sagte, sollte eine MM-Tabelle ganz genau so aussehen:

ext_tables.sql

CREATE TABLE tx_osw_person_person_mm (
	uid_local int(11) unsigned DEFAULT '0' NOT NULL,
	uid_foreign int(11) unsigned DEFAULT '0' NOT NULL,
	sorting int(11) unsigned DEFAULT '0' NOT NULL,
	sorting_foreign int(11) unsigned DEFAULT '0' NOT NULL,

	KEY uid_local (uid_local),
	KEY uid_foreign (uid_foreign)
);

...eventuell kann der Tabellenname abweichen, aber so sollte eine MM-Beziehung Person zu Person aufgebaut werden. Auf sorting kann auch verzichtet werden.
Ich habe hier ein Projekt mit MM-Tabellen, allerdings hab ich dafür keine extra TCA-Dateien.

Im TCA der Klasse, welche eine solche MM-Beziehung hat (hier: Person) sollte das dann...
... an dieser Stelle frag ich mich, warum bei dir überall $GLOBALS['TCA']['undsoweiter'] steht.
ich hab da nur $TCA['undsoweiter']
...naja, ungefähr so aussehen:

$TCA['tx_osw_domain_model_person'] = array(
...
   'columns' => array(
   ...
      'beziehung' => array(
           'foreign_table' => 'tx_osw_domain_model_person',
	   'MM' => 'tx_osw_person_person_mm',

...ohne Gewähr

harald1972 ·

Gut.
Der erste Teil ist dir bekannt.

Dann schau dir den zweiten Teil an!
Deine Fehlermeldung lautet:
Unknown column 'tx_osw_domain_model_person.beziehung_von' in 'where clause'
Und wie ich das sehe, hast du ja auch keine Spalte namens "beziehung_von", sondern "beziehung".

Eine Tabelle 'tx_osw_person_symmetric_mm' würde imho die beiden Tabellen tx_osw_domain_model_person und tx_osw_domain_model_symmetric verknüpfen. Hast du ein Model namens Symmetric?