Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony2][Symfony]update powiązanej encji - jak rozwiązać
Forum PHP.pl > Forum > PHP > Frameworki
longinustorwaldzki
Witajcie,


nie wiem czy uda mi się przedstawić sprawę bez wklejania kodu... spróbuję:
Powiedzmy, że mam 3 encje:

Stockinvoice - fakturaz zakupowa
Stockinvoiceelement - poszczególne produkty na fakturze zakupowej
Stock - magazyn przechowujący ilości poszczególnych produktów na magazynie



cel jest taki aby każde wprowadzenie/edycja/usunięcie Stockinvoiceelement skutkowało aktualizacją ilości elementów Stock.

na pierwszy rzut oka wydało mi się, że mógłbym to zrobić w Encji Stockinvoiceelement za pomocą serwisu w lifecycle callbacks (preInsert, preUpdate, preDelete)

ale wszędzie piszą, że Encje nie powinny mieć dostępu do serwisów. Więc jak mam to zrobić po bożemu (wolał bym uniknąć triggerów mysql...)


z góry dzięki


Edit: Dokopałem się do czegoś co nazywa się Entity listener. Zostało zaimplementowane w doctrine 2.4 i chyba nie ma jeszcze przyzwoitej dokumentacji w SF2.

Ktoś może próbował użyć takiego listenera?

edit2: więc chyba się dokopałem, jeśli ktoś jest tak zielony w SF2 jak ja to może się mu przyda:
MyBundle/Resources/config/services.yml
Kod
services:
    stockelementlistener:
        class:MyBundle\Listener\StockelementListener
        tags:
            - { name: doctrine.orm.entity_listener }    
        calls:
            - [ setContainer, [ @service_container ]]



MyBundle/Entity/Stockinvoiceelement.php
Kod
namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\EntityListeners;
/**
* Stockinvoiceelement
*
* @ORM\Table(name="m_stockinvoiceelements")
* @ORM\Entity(repositoryClass="MyBundle\Entity\StockinvoiceelementRepository")
* @ORM\Entity @EntityListeners({"MyBundle\Listener\StockelementListener"})
*/
class Stockinvoiceelement
{
...


MyBundle/Listener/Stockelementlistener.php
Kod
namespace  MyBundle\Listener;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use MyBundle\Entity\Stockinvoiceelement;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use MyBundle\Entity\Stock;
class StockelementListener extends Controller {
  
    
    public function prePersist(Stockinvoiceelement $stockinvoiceelement, LifecycleEventArgs $event){
    ...
   }



ps. to działa i wydaje się, że to może być właściwa droga ale jeśli ktoś zna lepsze rozwiązanie to proszę o info coby nie brnąć w ślepą uliczkę.
blahy
troche juz minelo, ale najlepsza decyzja wydaje sie uzycie kilku listenerow: doctrine.event_listener albo jednego subscribera doctrine.event_subscriber:
http://symfony.com/doc/current/cookbook/do...ubscribers.html
Nie trzeba wtedy wstrzykiwac kontenerow, extendowac konrollerow itp.

Tworzymy jeden EventSubscrier, w metodzie getSubscribedEvents dodajemy eventy, ktorych chcemy sluchac (np. postPersist, postUpdate i postRemove) a w ich implementacji wykonujemy operacje na encji Stock tylko jesli w evencie mamy docznienia z encja Stockinvoiceelement.
Do subscribera (jako ze jest to serwis) wstrzykujemy tylko potrzebne rzeczy (encje Stock dostaniemy w triggerowanym evencie).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.