Extbase: update funktioniert nicht

Während der Entwicklung einer Extension unter Typo 4.7.4 habe ich mich strikt an die Blog Example Extension gehalten. Ich habe brav meine ext_table.sql angelegt, die ext_tables.php angepasst und das dort referenzierte „dynamicConfigFile“ akribisch ergänzt und kontrolliert.

Im Typo3 Backend kann ich die Datensätze ohne Probleme anlegen, bearbeiten und löschen.

Für das Frontend habe ich ein Model und ein Repository angelegt. Nichts kompliziertes, da ich mit keinen Relationen zu tun habe. Anschließend ging es an den Controller. Ich habe natürlich vorher die ext_localconf.php angepasst:

Tx_Extbase_Utility_Extension::configurePlugin(
    $_EXTKEY,
    'Navigation',
    array(
        'Navigation' => 'list,new,create,edit,update,delete'
    ),
    // non-cacheable actions
    array(
        'Navigation' => 'list,new,create,edit,update,delete'
    )
);

Dann ging es im Controller weiter. Ich habe die list-Action implementiert – geht. Ich habe die new und die create-Aktion implementiert – geht. Auch die delete-Action macht keine Probleme. Nun die edit- und update-Action…. geht nicht!!!

Diese sieht so aus:

/**
 * Updates an existing navigation entity
 *
 * @param Tx_MyExtension_Domain_Model_Navigation $navigation
 * @return void
 */
 public function updateAction(Tx_MyExtension_Domain_Model_Navigation $navigation)
 {
   $this->navigationRepository->update($navigation);
   $this->addFlashMessage('update'); // see blog_example
   $this->redirect('list');
 }

Erst dachte ich: Wahrscheinlich kommen falsche Werte an. Ein Ausgabe über folgende Funktion sollte mich belehren:

Tx_Extbase_Utility_Debugger::var_dump($navigation);

Das Model hatte alle Werte korrekt aus dem Request übernommen. Also hab ich mir die update-Methode genauer angeschaut. Diese befindet sich in der Klasse Tx_Extbase_Persistence_Repository und ruft ihrerseits die replace-Methode der selben Klasse auf. In dieser Funktion wird vom Persistence Manager das Backend geholt und anschließend wird die Methode replaceObject aufgerufen:

/* @var Tx_Extbase_Persistence_Backend */
$backend = $this->persistenceManager->getBackend();
...
$backend->replaceObject($existingObject, $newObject);

Anschließend kommt eine if/elseif-Konstrukt:

if ($this->removedObjects->contains($existingObject)) {
  ..
} 
elseif ($this->addedObjects->contains($existingObject)) 
{
  ...
}

Genau dort liegt das Problem. Keine der beiden Bedingungen greift und somit passiert…… gar nix. Ich bin nach etwas längerem Suchen darauf gestoßen, dass das ursprüngliche Objekt nicht in der Identity Map enthalten ist. Leider habe ich den Grund dafür bisher nicht gefunden. Als Workaround habe ich die updateAction-Methode leicht angepasst:

/**
 * Updates an existing navigation entity
 *
 * @param Tx_MyExtension_Domain_Model_Navigation $navigation
 * @return void
 */
 public function updateAction(Tx_MyExtension_Domain_Model_Navigation $navigation)
 {
   // FIXME: updateAction do not work, I don't no why...
   /* @var $persistenceManager Tx_Extbase_Persistence_Manager */
   $persistenceManager=$this->objectManager->get('Tx_Extbase_Persistence_Manager');
   $backend=$persistenceManager->getBackend();
   $identityMap=$backend->getIdentityMap();
   $identityMap->registerObject($navigation, $navigation->getUid());
   // FIXEND
 
   $this->navigationRepository->update($navigation);
   $this->addFlashMessage('update'); // see blog_example
   $this->redirect('list');
 }

Vielleicht stoßt ja ein Typo3-Guru auf diesen Blogeintrag und hat einen Tipp für mich… ansonst hilft es vielleicht dem einen oder anderen, der dieses Problem auch hat.

 Update 26.09.2012:

Der Fix oben funktioniert leider nur, wenn jemand im Backend angemeldet ist. Warum das nicht die remove- bzw. die add-Methode betrifft, kann ich leider nicht sagen. Ich habe für mich im Repository die update-Methode überschrieben. Um die Daten in die Datenbank zu schreiben verwende ich dort die Methode

$GLOBALS['TYPO3_DB']->exec_UPDATEquery('table', 'uid='.$uid, $hash);

 

2 Gedanken zu “Extbase: update funktioniert nicht

  1. Hallo Tobias,

    bin über Deinen Eintrag gestolpert, da ich das gleiche Problem bei einer Erweiterung und Updates von FE Usern hatte.

    Bei mir hat’s funktioniert, nachdem ich die FrontenUserRepository.php angelegt und dort den Namespace definiert habe:
    namespace TYPO3\MeineExtension\Domain\Repository;

    Also so:

  2. Hallo,
    bin nicht sicher, ob das schon Deine Version betrifft, aber ich bin hier drauf gestoßen:

    „if the object is new you have to call ->add on the repository instead of ->update. Could you try that?
    With 6.1 the persisting of object has been made explicit and aligned more with Flow.“

    http://forge.typo3.org/issues/48256

    Bei mir funktionierte
    $this->practiceRepository->add($practice); in der Liveversion (4.7.14) aber nicht in der Entwicklung (6.1) – dort ging’s dann aber mit
    $this->practiceRepository->add($practice);

    Wie man i der Praxis damit umgehen soll, weiß ich im Moment auch noch nicht (außer verscheiden Versionen zu entwickeln, wenn das Livesystem nicht aktualisiert werden darf).

    Gruß, Stefan

Kommentar verfassen