[Frage] auf Action eines anderen Controllers zugreifen - eigene Extension (Extension Builder) Typo3 7.6.4

  • eishern eishern
    T3PO
    0 x
    7 Beiträge
    0 Hilfreiche Beiträge
    01. 04. 2016, 09:21

    [b]Vorwort[/b]
    Guten Morgen liebe Community,
    da dies mein erster eigener Beitrag ist hoffe ich hier in der richtigen Kategorie gelandet zu sein. Ich versuche mein Problem so detailliert wie möglich zu schildern. Sollten dennoch Informationen oder Code-Snippets fehlen werde ich diese schnellstmöglich Nachreichen. Meine Problemstellung habe ich in verschiedenen Variationen bereits in mehreren Quellen gefunden, konnte die Lösungen jedoch nicht adaptieren.

    [b]aktuelle Situation[/b]
    Ich habe mithilfe des Extension Builders unter Typo3 7.6.4 das Grundgerüst eines Frontend-Plugins erstellt. Ich habe die Model Objects "Customer" (aggregate root) und "Hardware" (und noch einige mehr, die aber für dieses Problem nicht relevant sind). Customer hat eine 1:n Relation zu Hardware. Ein Customer kann mehrere Server, Clients usw. vor Ort haben. Momentan habe ich als default-Aktion meines FE-Plugins die Action "list" des Controllers Customer. Mit einem Click auf einen der Customer wird mir dieser via f.link-Viewhelper in der Action "show" dargestellt. Diese habe ich um ein "assignMultiple" erweitert um mir die Informationen des Hardware-Controllers darzustellen.

    (ext/customermanagement/Classes/Controller/CustomerController.php)

    1. public function showAction(\XX\Customermanagement\Domain\Model\Customer $customer)
    2. {
    3. //$this->view->assign('customer', $customer);
    4. $this->view->assignMultiple(array(
    5. 'customer' => $customer,
    6. 'hardware' => $customer->getHardware()->toArray(),
    7. ));
    8. }

    Somit habe ich unter der Darstellung des Kunden in meiner "show"-Action die verschiedenen hardwares aufgelistet.

    (ext/customermanagement/Resources/Private/Templates/Customer/Show.html)

    1. <f:layout name="Default" />
    2. <f:section name="main">
    3. <f:flashMessages />
    4. <f:render partial="Customer/Properties" arguments="{customer:customer}" />
    5. <table class="tx_customermanagement hardware" >
    6. <tr>
    7. <th class="name">Name</th>
    8. <th class="ip">IP</th>
    9. <th class="user">User</th>
    10. <th class="password">Password</th>
    11. <th class="custominfo">Custom information</th>
    12. <th class="type">Type</th>
    13. </tr>
    14. <f:for each="{hardware}" as="hw" iteration="counter">
    15. <f:cycle values="{0: 'even', 1: 'odd'}" as="evenodd">
    16. <tr class="{evenodd}">
    17. </f:cycle>
    18. <td>{hw.name}</td>
    19. <td>{hw.ip}</td>
    20. <td>{hw.user}</td>
    21. <td>{hw.password}</td>
    22. <td>{hw.custominfo}</td>
    23. <td>{hw.type}</td>
    24. </tr>
    25. </f:for>
    26. </table>
    27. <f:link.action action="list">zur Übersicht</f:link.action>
    28. </f:section>

    [b]Fragestellung[/b]
    Ich möchte innerhalb meines Customer-Controllers auf die "edit"-Action des Hardware-Controllers zugreifen. Konkret möchte ich durch den Klick auf einen der Hardware-Einträge (Zeilen 18-23) die Informationen der Hardware editieren können.

    Ich habe mir Einträge zu diesem eher trivialen Thema hier im Forum, in der Dokumentation oder auch auf anderen Seiten angeschaut. Entweder bin ich blind oder mir fehlt ein wichtiger Baustein für das Verständnis des DDD (was ich eher befürchte). Ich würde mich freuen wenn mir hier keine fertige Lösung vorgegeben wird, das würde den Lerneffekt nehmen, der mir als Anfänger wichtig wäre. Aber hat von euch jemand bitte einen Hinweis für mich in welche Richtung ich schauen sollte, evtl. ein Stichwort oder dergleichen? :-)

    Grüße
    eis
    Marcel

  • Hilfreichster Beitrag

  • ente72 ente72
    Padawan
    1 x
    45 Beiträge
    1 Hilfreiche Beiträge
    01. 04. 2016, 12:00 - Hilfreichster Beitrag

    Hallo Marcel,
    in triviale Lösung ist das man eine Bearbeitungs- Button einfügt der auf die Edit Action im Hardwarecontroller verweist und den Kunden mit durch schleift.

    1. <f:link.action controller="hardware" action="edit" argument="{customer: customer, hardware : hw}">Bearbeiten</f:link.action>

    (Den so noch in Tabelle einfügen.)

    Den editAction und die updateaction dann in etwa so anpassen, damit der Benutzer nach dem Editieren und dem Update wieder zurück in die Kundenansicht kommt.

    1. public function editAction ([namespace]\customer &custmer, [namespace]\hardware $hardware ) {
    2. $this->view->assign('Costomer' : &custmer );
    3. $this->view->assign('Hardware' : &hardware );
    4.  
    5. }
    6.  
    7.  
    8. public function updateAction ([namespace]\customer &custmer, [namespace]\hardware $hardware ) {
    9. $this->hardwareRepository->update($hardware);
    10. $this->redirect('show', 'Customer', NULL , array('customer'=>$customer) );
    11.  
    12. }

    Im Edittemplat muss das Formular den custmer auch wieder mit an die updateAction übergeben.
    Dazu kann muss man form viewhelper noch das Argumentatribut argument="customer: customer" hinzufügen.

    Hardware hinzufügen oder löschen ist etwas aufwendiger würde aber über den selben Weg auch funktionieren.
    (kein getester Code, garantiert mit Fehlern

    Grüße
    Martin


  • 1
  • ente72 ente72
    Padawan
    1 x
    45 Beiträge
    1 Hilfreiche Beiträge
    01. 04. 2016, 12:00

    Hallo Marcel,
    in triviale Lösung ist das man eine Bearbeitungs- Button einfügt der auf die Edit Action im Hardwarecontroller verweist und den Kunden mit durch schleift.

    1. <f:link.action controller="hardware" action="edit" argument="{customer: customer, hardware : hw}">Bearbeiten</f:link.action>

    (Den so noch in Tabelle einfügen.)

    Den editAction und die updateaction dann in etwa so anpassen, damit der Benutzer nach dem Editieren und dem Update wieder zurück in die Kundenansicht kommt.

    1. public function editAction ([namespace]\customer &custmer, [namespace]\hardware $hardware ) {
    2. $this->view->assign('Costomer' : &custmer );
    3. $this->view->assign('Hardware' : &hardware );
    4.  
    5. }
    6.  
    7.  
    8. public function updateAction ([namespace]\customer &custmer, [namespace]\hardware $hardware ) {
    9. $this->hardwareRepository->update($hardware);
    10. $this->redirect('show', 'Customer', NULL , array('customer'=>$customer) );
    11.  
    12. }

    Im Edittemplat muss das Formular den custmer auch wieder mit an die updateAction übergeben.
    Dazu kann muss man form viewhelper noch das Argumentatribut argument="customer: customer" hinzufügen.

    Hardware hinzufügen oder löschen ist etwas aufwendiger würde aber über den selben Weg auch funktionieren.
    (kein getester Code, garantiert mit Fehlern

    Grüße
    Martin

  • eishern eishern
    T3PO
    0 x
    7 Beiträge
    0 Hilfreiche Beiträge
    01. 04. 2016, 15:01

    Hallo Martin,

    ich danke dir für die schnelle Antwort, das hat mir auf jeden Fall weitergeholfen. Ich kämpfe nun mit dem PropertyMapper. Ich melde mich sobald ich eine Lösung dafür habe.

    [edit]: Die nun stetig folgende Fehlermeldung lautet:

    [i]#1297759968: Exception while property mapping at property path "": It is not allowed to map property "0". You need to use $propertyMappingConfiguration->allowProperties('0') to enable mapping of this property.[/i]

    Mich macht stutzig dass der property path nicht ausgegeben werden kann. In der PropertyMapper.php Zeile 128 heißt es

    1. throw new Exception('Exception while property mapping at property path "' . implode('.', $currentPropertyPath) . '": ' . $e->getMessage(), 1297759968, $e);


    Gehe ich also recht in der Annahme, dass nicht der Wert 0 in oben genannter Fehlermeldung das Problem ist, sondern dass die Variable "$currentPropertyPath" leer ist?

    [edit2]: Ich sollte spezifischer angeben wo das Problem auftritt. Ich habe, wie von Martin vorgeschlagen, meine Listeneinträge in der Show-Action des Controllers um einen "f:link.action"-Viewhelper weitert.

    1. <td><f:link.action controller="hardware" action="show" arguments="{customer : customer, hardware : hardware}">{hw.ip}</f:link.action></td>

  • ente72 ente72
    Padawan
    0 x
    45 Beiträge
    1 Hilfreiche Beiträge
    01. 04. 2016, 17:44

    Anscheinend wird eines der beiden Objekte nicht richtig übergeben. Wie sieht denn der generierte Link aus?

    Die Action müsste auch edit sein wenn Du die Hardware bearbeiten willst.

    Grüße
    Martin

  • harald1972 harald197...
    Sternenflotten-Admiral
    1 x
    198 Beiträge
    13 Hilfreiche Beiträge
    02. 04. 2016, 09:08

    Hallo,

    Martin bezieht sich auf den Link um {hw.ip}
    Da hast du arguments="{customer : customer, hardware : hardware}
    Innerhalb der for-Schleife heißt diese Variable nicht hardware, sondern hw

    Daraus ergiebt sich:

    1. <td><f:link.action controller="hardware" action="edit" arguments="{customer : customer, hardware : hw}">{hw.ip}</f:link.action></td>

    Grüße
    Harald

    P.S.: Martin hatte oben im PHP-Code noch ein, zwei typos bei $customer (&custmer).
    Aber du machst ja (hoffentlich) nicht nur Copy&Paste.

  • eishern eishern
    T3PO
    0 x
    7 Beiträge
    0 Hilfreiche Beiträge
    04. 04. 2016, 08:39

    Hallo Harald,

    es lag tatsächlich daran dass ich innerhalb der Schleife den Alias hätte verwenden müssen. Und daran habe ich nun eine Stunde "verschwendet". Vielen lieben Dank!

  • 1