2012-08-13 40 views
4

我試圖弄清楚(沒有成功)最後幾天如何覆蓋SonataAdmin操作來捕獲會話用戶名並將其保存在外鍵字段中。Symfony2:在SonataAdmin中重寫createAction()

AttachmentAdminController類:

<?php 

namespace Application\Sonata\UserBundle\Controller; 

use Sonata\AdminBundle\Controller\CRUDController as Controller; 
#use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use FOS\UserBundle\Entity\User; 
use Symfony\Component\Security\Core\SecurityContextInterface; 
use Symfony\Bridge\Monolog\Logger; 
use Mercury\CargoRecognitionBundle\Entity\Attachment; 

class AttachmentAdminController extends Controller 
{ 
    /** 
    * (non-PHPdoc) 
    * @see Sonata\AdminBundle\Controller.CRUDController::createAction() 
    */ 
    public function createAction() 
    { 
     $result = parent::createAction(); 

     if ($this->get('request')->getMethod() == 'POST') 
     { 
      $flash = $this->get('session')->getFlash('sonata_flash_success'); 

      if (!empty($flash) && $flash == 'flash_create_success') 
      { 
       #$userManager = $this->container->get('fos_user.user_manager'); 
       #$user = $this->container->get('context.user'); 
       #$userManager = $session->get('username'); 
       $user = $this->container->get('security.context')->getToken()->getUser()->getUsername(); 

       $attachment = new Attachment(); 
       $attachment->setPath('/tmp/image.jpg'); 
       $attachment->setNotes('nothing interesting to say'); 
       $attachment->getSystemUser($user); 

       $em = $this->getDoctrine()->getEntityManager(); 
       $em->persist($product); 
       $em->flush(); 
      } 
     } 

     return $result; 
    } 
} 

服務附件:

mercury.cargo_recognition.admin.attachment: 
    class: Mercury\CargoRecognitionBundle\Admin\AttachmentAdmin 
    tags: 
     - { name: sonata.admin, manager_type: orm, group: General, label: Attachments } 
    arguments: [ null, Mercury\CargoRecognitionBundle\Entity\Attachment, "SonataAdminBundle:CRUD" ] 

在我看來,作爲ActionController的()是被SonataAdminBundle(也許全班文件)被忽略,因爲沒有錯誤消息,但我不知道爲什麼。實際上,我不確定是否從會話中提取用戶名。

我真的需要一個關於這個的好教程,但看起來像我得到的任何信息在某些方面已經過時。順便說一下,我正在使用Symfony 2.0.16

+0

的映射連接實體將是在這種情況下有幫助。使用用戶名作爲D2的fk可能是不可能的。您可能希望將user.id作爲fk。 – WizardZ 2012-08-15 05:44:33

+0

我不確定你的意思是「地圖實體」。 你是正確的在外鍵使用user.id,這是我從一開始就主要關心的,實際上,我添加了一個教條查詢從會話用戶名查找用戶ID,它的工作原理,但.. 。 我與覆蓋createAction()最後一個問題是,我生成表的兩個對象,併爲此兩條記錄(從表單中記錄,沒有FK,另一個硬編碼,用FK)。我正在使用prePersist()方法閱讀有關Event Listener的內容,因爲我只需要一條記錄,並且用戶標識已記錄在外鍵中。 – abiyi 2012-08-15 13:35:21

回答

7

最後我得到了解決方案。我相信還有一些其他的(比如使用事件監聽器,比如說,看起來更簡單),但現在它是我能找到的最好的(它有效,這是最重要的)。

我試圖覆蓋createAction()基於我在另一個論壇主題中找到的例子,但我在表中獲取兩個記錄而不是一個。最重要的是重寫WHOLE操作方法並將自定義代碼放入其中。

控制器

<?php 

namespace Mercury\CargoRecognitionBundle\Controller; 

use Symfony\Component\Security\Core\SecurityContextInterface; 
use Symfony\Bridge\Monolog\Logger; 
use Sonata\AdminBundle\Controller\CRUDController as Controller; 
use Application\Sonata\UserBundle\Entity\User; 
use Mercury\CargoRecognitionBundle\Entity\Attachment; 
use Mercury\CargoRecognitionBundle\Entity\SystemUser; 
use Mercury\CargoRecognitionBundle\Repository\SystemUserRepository; 

class AttachmentAdminController extends Controller 
{ 
    /** 
    * Set the system user ID 
    */ 
    private function updateFields($object) 
    { 
     $userName = $this->container->get('security.context') 
         ->getToken() 
         ->getUser() 
         ->getUsername(); 

     $user = $this->getDoctrine() 
        ->getRepository('ApplicationSonataUserBundle:User') 
        ->findOneByUsername($userName); 

     $object->setSystemUser($user); 

     return $object; 
    } 

    /** 
    * (non-PHPdoc) 
    * @see Sonata\AdminBundle\Controller.CRUDController::createAction() 
    */ 
    public function createAction() 
    { 
     // the key used to lookup the template 
     $templateKey = 'edit'; 

     if (false === $this->admin->isGranted('CREATE')) { 
      throw new AccessDeniedException(); 
     } 

     $object = $this->admin->getNewInstance(); 

     $object = $this->updateFields($object); 

     // custom method 
     $this->admin->setSubject($object); 

     $form = $this->admin->getForm(); 
     $form->setData($object); 

     if ($this->get('request')->getMethod() == 'POST') { 
      $form->bindRequest($this->get('request')); 

      $isFormValid = $form->isValid(); 

      // persist if the form was valid and if in preview mode the preview was approved 
      if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) { 
       $this->admin->create($object); 

       if ($this->isXmlHttpRequest()) { 
        return $this->renderJson(array(
         'result' => 'ok', 
         'objectId' => $this->admin->getNormalizedIdentifier($object) 
        )); 
       } 

       $this->get('session')->setFlash('sonata_flash_success','flash_create_success'); 
       // redirect to edit mode 
       return $this->redirectTo($object); 
      } 

      // show an error message if the form failed validation 
      if (!$isFormValid) { 
       $this->get('session')->setFlash('sonata_flash_error', 'flash_create_error'); 
      } elseif ($this->isPreviewRequested()) { 
       // pick the preview template if the form was valid and preview was requested 
       $templateKey = 'preview'; 
      } 
     } 

     $view = $form->createView(); 

     // set the theme for the current Admin Form 
     $this->get('twig')->getExtension('form')->setTheme($view, $this->admin->getFormTheme()); 

     return $this->render($this->admin->getTemplate($templateKey), array(
      'action' => 'create', 
      'form' => $view, 
      'object' => $object, 
     )); 
    } 
} 

服務爲控制器

mercury.cargo_recognition.admin.attachment: 
    class: Mercury\CargoRecognitionBundle\Admin\AttachmentAdmin 
    tags: 
     - { name: sonata.admin, manager_type: orm, group: General, label: Attachments } 
    arguments: [ null, Mercury\CargoRecognitionBundle\Entity\Attachment, "MercuryCargoRecognitionBundle:AttachmentAdmin" ] 

我從以下站點解決方案:

(而索納塔項目文檔)