Zum Inhalt springen

Relationen mit findAll() auslesen

Erstellt am 5. August 2015 · 3 Antworten · letzte Antwort am 6. August 2015

Tags: Fluid, Frage

alfredbez ·

Moin,
bin gerade dabei eine Extbase Extension zu erstellen und stoße dabei auf folgendes Problem:

Ich lese mit findAll() alle Models aus meinem Repository aus, weiß aber nicht, wie ich verknüpfte Models mit ausgeben kann.

Ich habe ein User Model und ein Phone Model. Ein User kann mehrere Phones haben. Die Zuordnung funktioniert soweit auch, ich sehe in der Datenbank die User UID in der Phones Tabelle.

In meinem Template würde ich gerne in etwa so etwas machen:

<f:for each="{users}" as="user">
		Name: {user.name}
		<ul>
	    <f:for each="{user.phones}" as="phone">
	        <li>{phone.model}</li>
	    </f:for>
		</ul>
</f:for>

Damit ich so eine Ausgabe habe:

Name: Herbert
<ul>
	<li>Apple iPhone 5</li>
	<li>Samsung Galaxy S6</li>
</ul>

Name: Mathilde
<ul>
	<li>Apple iPhone 4S</li>
</ul>

Hier mal mal Code:
Phone.php

<?php

namespace Acme\FooBar\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

class Phone extends AbstractEntity
{
    /**
     * @var Acme\FooBar\Domain\Model\User
     */
    protected $user;
    public function getUser()
    {
        return $this->user;
    }
    public function setUser(User $user)
    {
        $this->user = $user;
    }
}

User.php

<?php

namespace Acme\FooBar\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;

class User extends AbstractEntity
{
    /**
     * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Acme\FooBar\Domain\Model\Phone>
     */
    protected $phones;

    /**
     * @return \Acme\FooBar\Domain\Model\User
     */
    public function __construct()
    {
        $this->phones = new ObjectStorage();
    }
    /**
     * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Acme\FooBar\Domain\Model\Phone>
     */
    public function getPhones()
    {
        return $this->phones;
    }
}

ext_tables.sql

CREATE TABLE tx_foobar_domain_model_user (
    uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
    pid int(11) DEFAULT '0' NOT NULL,

    PRIMARY KEY (uid),
    KEY parent (pid),
);

CREATE TABLE tx_foobar_domain_model_phone (
    uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
    pid int(11) DEFAULT '0' NOT NULL,

    user int(11) DEFAULT '0' NOT NULL,
    model text NOT NULL,

    PRIMARY KEY (uid),
    KEY parent (pid),
);

Configuration/TCA/tx_foobar_domain_model_phone.php

<?php

return [
    'columns' => [
        'user' => [],
        'model' => [],
    ],
];

Configuration/TCA/tx_foobar_domain_model_user.php

<?php

return [
    'columns' => [
    	'phones' => [
    		'config' => [
    			'config' => [
    			    'foreign_table' => 'tx_foobar_domain_model_phone',
    			    'foreign_field' => 'user',
    			],
    		]
    	]
    ],
];

Die Daten werden einmal nachts aus einem XML eingelesen und werden in keiner Weise im Backend gepflegt, sondern nur über ein Plugin im Frontend ausgelesen.

daniz78 ·

Der Weg ist auf den ersten Blick klar, das Problem aber noch etwas neblig.
Gibt es eine Fehlermeldung?

Da Du die $phones im Model als ObjectStorage angelegt hast, kannst Du auch über sie im FLUID iterieren.
Mach doch mal ein <debug> in der for-each Schleife:

<f:for each="{users}" as="user">
  <f:debug>{user.phones}</f:debug>
</f:for>
alfredbez ·

Fehlermeldung:

Extbase Variable Dump
NULL

In meiner Action im Controller steht übrigens nur folgender Code:

$this->view->assign('users', $this->userRepository->findAll());
daniz78 ·

Ich sehe in der Datenbank die User UID in der Phones Tabelle...

Aber in der User Tabelle wirst Du nicht die Phone-ID´s sehen!

In Deiner ext_tables.sql fehlt bei den Persons die Verknüpfung zu den Phones:

CREATE TABLE tx_foobar_domain_model_user (
  uid int(11) unsigned DEFAULT '0' NOT NULL auto_increment,
  pid int(11) DEFAULT '0' NOT NULL,
  phones text,

  PRIMARY KEY (uid),
  KEY parent (pid),
);

Es ist ja eine 1:n Verknüpfung, also 1 Person kann n Phones besitzen.

In Deinem Person Model muss dann natürlich noch ein paar Methoden eingefügt werden:

public function setPhones();
public function addPhone();
public function removePhone();

...der Extension Builder sollte das eigentlich für Dich übernehmen, wenn Du ihn denn nutzt 😉

Im TCA User.php müsstest Du dann noch die phones konfigurieren: