В последние дни я искал как сумасшедшие, пытаясь понять (без успеха), как переопределить действие SonataAdmin, чтобы захватить имя пользователя сеанса и сохранить его в поле внешнего ключа.
Класс 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
Наконец я добрался до решения. Я уверен, что есть некоторые другие (например, с помощью прослушивателей событий, например, это кажется более простым), но сейчас это лучшее, что я могу найти (это работает, и это важно).
Я пытался переопределить 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" ]
Я принял решение со следующих сайтов:
(И документация Проекта Сонаты)