Zum Inhalt springen

Object aus einer 1:n Relation lösen ( Schwierigkeiten mit Extbase und/oder php OOP programmierung

Erstellt am 19. März 2015 · 6 Antworten · letzte Antwort am 23. März 2015

Tags: Frage

ente72 ·

Hallo,
ich programmiere gerade eine Erweiterung mit der man sich Dokumente in einen Warenkorb packen kann und dann zusenden lassen kann.

Ich habe ein Warenkorbobjekt und ein Dokument im Kickstarter angelegt. Mit einer 1:n Verknüpfung Warenkorb zum Wissensdokument unter dokumente.

Der Kickstarter hat folgendes erstellt

TCA:

		'dokumente' => array(
			'exclude' => 1,
			'label' => 'LLL:EXT:warenkorb/Resources/Private/Language/locallang_db.xlf:tx_warenkorb_domain_model_warenkorb.dokumente',
			'config' => array(
				'type' => 'inline',
				'foreign_table' => 'tx_warenkorb_domain_model_wissensdokument',
				'foreign_field' => 'warenkorb',
				'maxitems'      => 9999,
				'appearance' => array(
					'collapseAll' => 0,
					'levelLinksPosition' => 'top',
					'showSynchronizationLink' => 1,
					'showPossibleLocalizationRecords' => 1,
					'showAllLocalizationLink' => 1
				),
			),

		),

und in der Warenkorb Klasse

  /**
	 * dokumente
	 *
	 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Sutor\Warenkorb\Domain\Mode \WissensDokument>
	 * @cascade remove
	 * @lazy
	 */
	protected $dokumente = NULL;

In der Warenkorb Klasse habe ich jetzt zum entfernen eines Dokumentes erst diese Methode angelegt.

	/**
	 * WissensDokument aus dem Warenkorb entfernen
	 *
	 * @param \Sutor\Warenkorb\Domain\Model\WissensDokument $dokumenteToRemove
	 * @return void
	 */

	public function removeDokument(\Sutor\Warenkorb\Domain\Model\WissensDokument $dokumentToRemove) {
		
	  $this->dokumente->detach($dokument);

	}

Funktioniert aber nicht, da das Objekt $dokumentToRemove neu erstellt wird und nicht das Gleiche ist wie im Objectstorage $this->$dokumente.

Annschließend habe ich es so versucht

	public function removeDokument(\Sutor\Warenkorb\Domain\Model\WissensDokument $dokumentToRemove) {
	        \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($this->getDokumente());	
			foreach ($this->getDokumente() as $dokument){
				if ($dokument->getUid() === $dokumentToRemove->getUid()) {	
                    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(spl_object_hash($dokument));				
					$this->dokumente->detach($dokument);
				}
			}
		die();
	}

Die Debugging ausgabe wenn ich das Dukoment1 löschen will ist für

$this->getDokumente()

TYPO3\CMS\Extbase\Persistence\ObjectStorageprototypemodified object (2 items)
0000000004b8b7d100000000231c17a6 => Sutor\..prototypepersistent entity (uid=1, pid=296)
000000004f770b92000000003c96eeb4 => Sutor\..tprototypepersistent entity (uid=2, pid=296)

und für den Obeject Hash für $dokument

'0000000020853b890000000050bb6d6d' (32 chars)

Also auch hier wieder verschiedene Objekte. Das verstehe ich nicht so ganz. Es könnte daran liegen das der Warenkorb in einer Session gespeichert wird.

Als drittes habe ich dann folgender versucht

	public function removeDokument(\Sutor\Warenkorb\Domain\Model\WissensDokument $dokumentToRemove) {
	    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($this->getDokumente());	
			foreach ($this->getDokumente() as $objectHash => $dokument){
				if ($dokument->getUid() === $dokumentToRemove->getUid()) {		       
					\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($objectHash);				  
					\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($this->dokumente[$objectHash]);
					unset($this->dokumente[$objectHash]);
				}
			}			 
	}

Die Debuggingausgabe wenn ich das Dukoment1 löschen will ist für

$this->getDokumente()

TYPO3\CMS\Extbase\Persistence\ObjectStorageprototypemodified object (2 items)
0000000004b8b7d100000000231c17a6 => Sutor\..prototypepersistent entity (uid=1, pid=296)
000000004f770b92000000003c96eeb4 => Sutor\..tprototypepersistent entity (uid=2, pid=296)

und für den Obeject Hash für $dokument

'0000000004b8b7d100000000231c17a6' (32 chars)

Aber für $this->dokumente[$objectHash] kommt null

An dieser Stelle verstehe ich jetzt gar nix mehr. Kann ich noch nicht gut genug PHP ?

Frage ist
Was mache ich falsch ?
oder
Bin ich überhaupt auf dem richtigen Weg?

Gibt es evt. einen Link für Beispiel? Es ja nichts außergewöhnliches. ( Ich habe gegooglt aber nichts gefunden )

Vielen Dank
Martin

loeschendatach.jpg
loeschenunset.jpg

Unbekannter Benutzer ·

Moin,

wenn ich das richtig sehe, kann das auch gar nicht funktionieren. Du übergibst $dokumentToRemove als Parameter. Innerhalb deiner Funktion rufst du dann aber detach($dokument) auf.

ente72 ·

Hallo,
Um den Code noch mal in Worte zu fassen.

Das Objekt $dokumentToRemove lässt sich nicht direkt aus der Dokumentenliste mit detach aus der Dokumentenliste ($this-dokumente) löschen. Da es ein Kopie des zu löschenden Element ist. Es hat einen andern objecthash. Daher habe ich eine foreach-Schleife über die Dokumentenliste gemacht, und möchte jetzt das Dokument löschen das die selbe UID hat wie das Dokument unter $dokumentToRemove.

Unbekannter Benutzer ·

Moin,

das war soweit schon klar. Dennoch der Hinweis, einmal die richtige Funktion mit richtigen Parametern und richtigen Variablen zu benutzen.

Hast du das mal ausprobiert ?
Das müsste nämlich EXAKT so funktionieren, und wenn es das nicht tut, dann wird der Fehler ziemlich sicher woanders liegen.

ente72 ·

Hallo,
ich verstehe ich es, du meintest die erste Methode. Das habe ich hier falsch eingegestellt. Ich habe das schon mit dem richtigen Variablen Namen ausprobiert.

	public function removeDokument(\Sutor\Warenkorb\Domain\Model\WissensDokument   $dokumentToRemove) {
 
             $this->dokumente->detach($dokumentToRemove);
 
}

Das hatte ich dann in der objectstorage Klasse gedebuggt und festgestellt das es so nicht geht, da das $dokumentToRemove ein neues WissensDokument ist und entsprechen einen neuen objecthash hat. 

Ich habe hier noch mal die action aus dem Warenkorb Controller.  Habe ich dort evt etwas einen Fehler drin

[code language=php]
	/**
	 * removeFromWarenkorb list
	 * @param \Sutor\Warenkorb\Domain\Model\WissensDokument $wissensDokument
	 * @return void
	 */		

	public function removeFromWarenkorbByAjaxAction(\Sutor\Warenkorb\Domain\Model\WissensDokument $wissensDokument)  {
	      
      if ($this->warenkorb->isDokumentInWarenkorb($wissensDokument->getUid())) {					        
				$this->warenkorb->removeDokument($wissensDokument);
				$GLOBALS['TSFE']->fe_user->setKey('ses', 'warenkorb', serialize($this->warenkorb));					
				foreach ($this->warenkorb->getDokumente() as $dokument) {	
				$json[$dokument->getUid()] = $dokument->getTitel();			
				}
			return json_encode($json);
			} else {
				$json = (false);
				return json_encode($json);
			}
		}
	}


[/code]


Viele Grüße und besten Dank schon mal bis hierher
Martin
ente72 · · Beste Antwort

Den Ajaxrequest erzeuge ich mit diesem Viewhelper
<f:uri.action action="removeFromWarenkorbByAjax" controller="WissensDokument" arguments="{wissensDokument:wissensDokument}" pageType="99" pluginName="pi2" /

Das sieht um das Dukument mir der uid = 1 zu löschen so aus
[Pfad]?tx_warenkorb_pi2[wissensDokument]=1&tx_warenkorb_pi2[action]=removeFromWarenkorbByAjax&tx_warenkorb_pi2[controller]=WissensDokument&cHash=32fbbbb25a63bb2509acb42cc0fdfff8

Ich habe es aber immer noch nicht hin bekommen. Ich habe es jetzt erst mal ganz dirty gelöst.
Indem ich mir erst mal ein Array mit den Dokumenten erstelle und das zu löschenden Dokument dort raus lösche. Anschließend baue ich mir mit den übrigen Dokumenten ein neues ObjectStorage auf.
Nicht schön aber funktioniert.

Ich muss mir wohl das ObjectStorage nochmal genauer unter die Lupe nehmen.
die Methoden detachByUid() oder detachbyPosition() wären dort vielleicht hilfreich.

	public function removeDokument(\Sutor\Warenkorb\Domain\Model\WissensDokument $dokumentToRemove) {
		   
            $dokumentenArray = $this->getDokumente()->toArray();    	
            		
			foreach ($dokumentenArray as $key => $dokument){
							 
					if ($dokument->getUid() === $dokumentToRemove->getUid()) {	            					                   					 
					 unset($dokumentenArray[$key]); 
					}				
			}
			
			$this->dokumente = NULL;
			$this->dokumente = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
			foreach ($dokumentenArray as $dokument){
			$this->dokumente->attach($dokument);	
			}				
		
	}

Vielen Dank erst mal
Martin