Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Dlaczego to samo co w kontrolerze nie wychodzi w listenerze? :)
porzeczki
post 18.10.2016, 01:01:00
Post #1





Grupa: Zarejestrowani
Postów: 144
Pomógł: 0
Dołączył: 15.09.2016
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Próbowałem zadać uniwersalne pytanie, ale było bardziej nieczytelne. Może komuś mimo to zechce się rzucić okiem, uprościłem ile się dało.

Dlaczego listener nie wysyła poprawnie produktów w linii $event->getZamowienie()->getZamowienieProdukty()
a chwilę później kontroler robi to poprawnie w linii $produkty = $zamowienie->getZamowienieProdukty()
W debugerze w obu przypadkach $produkty są typu doctrine/orm/persistentcollection i wyglądają identycznie (ale w obu przypadkach nie widać jakie dane przechowują)

  1. //Manager, tu zapisuje dane do db i wypstrykuję dispatchera
  2. class ZamowienieManager
  3. {
  4. public function tworzZamowienie($klient)
  5. {
  6. $zamowienie = new Zamowienie();
  7. $zamowienie->setIdklient($klient);
  8. $zamowienie->setDatazlozeniacurrent();
  9.  
  10. $this->tworzProduktyZamowienia($zamowienie);
  11.  
  12. $this->em->persist($klient);
  13. $this->em->persist($zamowienie);
  14. $this->em->flush();
  15.  
  16. $this->dispatcher->dispatch(OrderPlacedEvent::NAME, new OrderPlacedEvent($zamowienie));
  17.  
  18. $this->addFlashBag($zamowienie);
  19.  
  20. }
  21.  
  22. private function tworzProduktyZamowienia($zamowienie)
  23. {
  24. foreach ($this->cart as $isbn => $quantity)
  25. {
  26. $ksiazka = $this->em
  27. ->getRepository('AppBundle:Ksiazka')
  28. ->find($isbn);
  29. $zm = new ZamowienieProdukt();
  30. $zm->setIdzamowienie($zamowienie);
  31. $zm->setIsbn($ksiazka);
  32. $zm->setTytul($ksiazka->getTytul());
  33. $zm->setAutor($ksiazka->getAutor());
  34. $zm->setIlosc($quantity);
  35. $this->em->persist($zm);
  36. }
  37. }
  38.  
  39. public function addFlashBag($zamowienie){
  40. $this->session->getFlashBag()->add(
  41. 'idzamowienie',$zamowienie->getIdzamowienie(););
  42. }
  43. }



  1. //Listener. wysyła maila potwierdzającego zamówienie. POPRAWNIE WYŚWIETLA DANE ZAMÓWIENIA, NIE WYŚWIETLA PRODUKTÓW.
  2. class Listener
  3. {
  4. public function onOrderPlaced(OrderPlacedEvent $event)
  5. {
  6. ...
  7. $body = $this->renderTemplate($event);
  8. ...
  9. }
  10. private function renderTemplate($event)
  11. {
  12. return $this->twig->render(
  13. 'AppBundle:Cart:potwierdzenieMail.html.twig',
  14. 'zamowienie'=>$event->getZamowienie(),
  15. 'produkty'=>$event->getZamowienie()->getZamowienieProdukty()
  16. )
  17. );
  18. }


  1. //kontroler, POPRAWNIE WYŚWIETLA DANE ZAMÓWIENIA, I PRODUKTY.
  2. public function potwierdzenieAction(Request $request)
  3. {
  4. $idzamowienie=$request->getSession()->getFlashBag()->get('idzamowienie');
  5.  
  6. $zamowienie = $this->getDoctrine()
  7. ->getRepository('AppBundle:Zamowienie')
  8. ->find($idzamowienie[0]);
  9. $produkty = $zamowienie->getZamowienieProdukty();
  10.  
  11. return $this->render('AppBundle:Cart:potwierdzenie.html.twig',[
  12. 'zamowienie'=>$zamowienie, 'produkty'=>$produkty]);
  13. }


Czy to chodzi o to, że bez przeładowania strony nie mogę wywołać powiązanej z Entity/Zamowienie (ManyToOne) kolekcji (Doctrine\Common\Collections\Collection) którą zwraca ->getZamowienieProdukty(), gdy ten obiekt (new Zamowienie) dopiero co utworzyłem i dopiero co zapisałem go flush() do bazy danych? (wiem, że to zdanie wygląda jakby było pisane przed dałna, staram się jak mogę, zasób słów jest jaki jest)

Ten post edytował porzeczki 18.10.2016, 01:24:55
Go to the top of the page
+Quote Post
kpt_lucek
post 18.10.2016, 02:12:22
Post #2





Grupa: Zarejestrowani
Postów: 428
Pomógł: 77
Dołączył: 10.07.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Tak się dzieje, jak do produktu przypisujesz zamówienie, ale zamówienie nie wie o tym, że coś zostało do niego "przypisane".

W tym wypadku robiąc coś takiego:
  1. $zm->setIdzamowienie($zamowienie);
  2. [php]
  3. i zakładając coś takiego:
  4. [php]
  5. class ZamowienieProdukt
  6. {
  7. public function setIdZamowienie(Zamowienie $zamowienie)
  8. {
  9. $this->idZamowienie = $zamowienie;
  10.  
  11. return $this;
  12. }
  13. }


w rzeczywistości powinieneś zrobić coś takiego:
  1. class ZamowienieProdukt
  2. {
  3. public function setIdZamowienie(Zamowienie $zamowienie)
  4. {
  5. $this->idZamowienie = $zamowienie;
  6. $zamowienie->addZamowienieProdukt($this);
  7.  
  8. return $this;
  9. }
  10. }


  1. class Zamowienie
  2. {
  3. public function addZamowienieProdukt(ZamowienieProdukt $zamowienieProdukt)
  4. {
  5. if(false === in_array($zamowienieProdukt, $this->zamowienieProdukty, true)) {
  6. $this->zamowienieProdukty[] = $zamowienieProdukt;
  7. }
  8.  
  9. return $this;
  10. }
  11. }



Pytanie: Dlaczego?

Odpowiedź: Bo doctrine nie wie o zmianach które "stały się" w Twoim zamówieniu, co innego gdybyś pobrał to jako nowy wpis z bazy - czyli to, co robisz w kontrolerze.


--------------------


Cytat
There is a Bundle for that
Lukas Kahwe Smith - October 31th, 2014
Go to the top of the page
+Quote Post
porzeczki
post 18.10.2016, 11:31:47
Post #3





Grupa: Zarejestrowani
Postów: 144
Pomógł: 0
Dołączył: 15.09.2016
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


dziękuję, działa. (z twojego kodu pominąłem warunek in_array bo $this->zamowienieProdukty jest obiektem)

Cytat(kpt_lucek @ 18.10.2016, 03:12:22 ) *
co innego gdybyś pobrał to jako nowy wpis z bazy - czyli to, co robisz w kontrolerze.

no właśnie, próbowałem robić:
  1. //function tworzZamowienie
  2. ...
  3. $this->em->persist($zamowienie);
  4. $this->em->flush();
  5. $zamowienie = $this->em->getRepository('AppBundle:Zamowienie')->find($zamowienie->getIdzamowienie());
  6. $this->dispatcher->dispatch(OrderPlacedEvent::NAME, new OrderPlacedEvent($zamowienie));

i też zamówienie nie wiedziało o produktach.

Ten post edytował porzeczki 18.10.2016, 12:19:40
Go to the top of the page
+Quote Post
Turson
post 18.10.2016, 12:15:04
Post #4





Grupa: Zarejestrowani
Postów: 4 291
Pomógł: 829
Dołączył: 14.02.2009
Skąd: łódź

Ostrzeżenie: (0%)
-----


ZamowienieManager
tworzZamowienie
tworzProduktyZamowienia
addFlashBag
setIdklient
setDatazlozeniacurrent
itp.

karygodne nazewnictwo

Ten post edytował Turson 18.10.2016, 12:15:20
Go to the top of the page
+Quote Post
porzeczki
post 18.10.2016, 12:48:37
Post #5





Grupa: Zarejestrowani
Postów: 144
Pomógł: 0
Dołączył: 15.09.2016
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


no wiem. Zacząłem tak nazywać, więc później już poleciała lawina tych potworków. Najpierw chciałem by było zrozumiałe dla mnie (bo nikt inny miał tego nie oglądać), ale szybko okazało się że to jest niezrozumiałe też dla mnie.

Ten post edytował porzeczki 18.10.2016, 13:02:05
Go to the top of the page
+Quote Post
kpt_lucek
post 18.10.2016, 13:18:44
Post #6





Grupa: Zarejestrowani
Postów: 428
Pomógł: 77
Dołączył: 10.07.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


$em->refresh($zamowienie);


--------------------


Cytat
There is a Bundle for that
Lukas Kahwe Smith - October 31th, 2014
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 10:19