2016-08-10 9 views
1

私はライフサイクルイベントを持っています。オーダーが作成されると、prePersistライフサイクルイベントは、データベースに保存される前に、オーダーにいくつかの詳細を追加します。ライフサイクルイベント内でサービスを呼び出す

これは私のprePersistイベントクラスです。

<?php 

namespace Qi\Bss\BaseBundle\Lib\PurchaseModule; 

use Qi\Bss\BaseBundle\Entity\Business\PmodOrder; 
use Doctrine\ORM\Event\LifecycleEventArgs; 

/** 
* Listener class 
* Handles events related to list prices 
*/ 
class OrderUserListener 
{ 

    /** 
    * Service container 
    * @var type 
    */ 
    private $serviceContainer; 

    /** 
    * Performs tasks before destruction 
    * @ORM\PrePersist 
    */ 
    public function prePersist(LifecycleEventArgs $args) 
    { 
     $order = $args->getEntity(); 

     if ($order instanceof PmodOrder) { 
      $user = $this->serviceContainer->get('security.token_storage')->getToken()->getUser(); 

      if ($user) { 
       $order->setCreatedBy($user); 
       $order->setCreatedAt(new \DateTime(date('Y-m-d H:i:s'))); 
       $order->setDepartment($user->getDepartment()); 
       $order->setStatus(PmodOrder::STATUS_AWAITING_APPROVAL); 

       $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created'); 
      } 
     } 
    } 

    /** 
    * Sets the sales order exporter object 
    * @param type $serviceContainer 
    */ 
    public function setServiceContainer($serviceContainer) 
    { 
     $this->serviceContainer = $serviceContainer; 
    } 
} 

それは完璧に動作しますが、この部分$this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');は仕事をしたくはありません。私はその中のサービスに電話しようとします。サービスがコントローラ内で完璧に動作することは分かっていますが、ここではエラーが発生します。 NuweテストVIR ロガー:

新しいエンティティは、エンティティのための操作を持続カスケードに設定されていない た関係 「チー\はBss \ BaseBundle \エンティティ\ビジネス\ PmodLog番号順」を介していました。この不明なエンティティの EntityManager#persist()を明示的に呼び出すか、カスケードをコンフィグレーションする は、この関連付けをマッピング内に保持します(例: @ManyToOne(..、cascade = {"persist"})。

これは私のOrderLoggerサービスクラスの外観です。

<?php 

namespace Qi\Bss\BaseBundle\Lib\PurchaseModule; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; 
use Doctrine\ORM\EntityManager; 
use Qi\Bss\BaseBundle\Entity\Business\PmodLog; 

/** 
* Class AppLogger. Purchase Module logger. 
* @package FcConnectBundle\Lib 
*/ 
class OrderLogger { 

    private $em; 
    private $tokenStorage; 

    /** 
    * Constructor. 
    * 
    * @param EntityManager $em 
    * @param TokenStorage $securityTokenStorage 
    */ 
    public function __construct(EntityManager $em, TokenStorage $securityTokenStorage) 
    { 
     $this->em = $em; 
     $this->tokenStorage = $securityTokenStorage; 
    } 

    /** 
    * Log an order action. 
    * 
    * @param string $text 
    */ 
    public function log($order, $action) 
    { 
     $logRecord = new PmodLog(); 
     if (is_object($this->tokenStorage->getToken())) { 
      $user = $this->tokenStorage->getToken()->getUser(); 
      if (is_object($user)) { 
       $logRecord->setUser($user); 
      } 
     } 
     $logRecord->setOrder($order); 
     $logRecord->setAction($action); 
     $logRecord->setTime(new \DateTime()); 

     $this->em->persist($logRecord); 
     $this->em->flush(); 
    } 

} 

私はすでにマージするために自分のログ内の永続性を変更しようとしましたが、それも機能しません。誰か助けて、私が間違っていることを説明できますか?

+0

サービスは、prePersistイベントで '' $ em-> flush() ''を呼び出すべきではありません。 – Alsatian

+0

分かりませんが、EntityManagerのコンストラクタインジェクションではなく、 '' $ args-> getEntityManager() ''をログメソッドに渡そうとしています。 – Alsatian

+0

@Alsatian私は100%理解していない、私のサービスからフラッシュを削除する必要がありますか?しかし、それは私が同じサービスを呼び出す私のコントローラではうまくいかないでしょう。コントローラーと私のprePersistイベントでそれが必要です。 –

答えて

0

を追加postPersistを追加して、私のprePersistの代わりにそこにロガーを呼び出して問題を解決してください。

/** 
* Performs tasks before destruction 
* @ORM\PostPersist 
*/ 
public function postPersist(LifecycleEventArgs $args) 
{ 
    $order = $args->getEntity(); 

    if ($order instanceof PmodOrder) {     
     $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created'); 
    } 
} 

何私だと思うが起こっていることは、ロガーが実行されるようにしようとしますが、それはまだ保持されませんようロガーで注文がまだ存在しないということですので。この方法は私にはもっと意味をなさないが、これは最も簡単な解決策だと思う。私は間違っているかもしれませんが、私の答えに関するコメントや他の意見は大歓迎です。

0

これが最善のアーキテクチャではありませんが、それは動作します:

prePersistで、私は固定($ logMessagesのような)プライベート変数のいくつかの種類にすべてのメッセージを追加し、別のイベント

/** 
* @param PostFlushEventArgs $args 
*/ 
public function postFlush(PostFlushEventArgs $args) 
{ 
    $logMessages = $this->logMessages; 

    $this->logMessages = array(); //clean to avoid double logging 

    if (!empty($logMessages)) { 
     foreach ($logMessages as $message) { 
      $this->serviceContainer->get('bss.pmod.order_logger')->log($message); 
     } 

    } 
} 
関連する問題