2016-02-16 2 views
7

У меня есть объект:Symfony2, FOSRestBundle. Как использовать группу с JMSSerializerBundle?

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use JMS\Serializer\Annotation\Groups; 
//... 


/** 
    * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository") 
    **/ 
class User extends BaseUser 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @Groups({"default"}) 
    */ 
protected $id; 

/** 
* @ORM\ManyToMany(targetEntity="StorageBundle\Entity\File") 
* @ORM\JoinTable(name="users_photos", 
*  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="photo_id", referencedColumnName="id", onDelete="CASCADE")} 
*  ) 
* @Groups({"default"}) 
*/ 
protected $photoFiles; 

/** 
* @ORM\Column(type="string", length=255, nullable=true, unique=false) 
* @Groups({"notification"}) 
*/ 
protected $deviceId; 

/** 
* @ORM\Column(type="string", length=255, nullable=true, unique=false) 
    *  @Groups({"default"}) 
*/ 
protected $name; 

/** 
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Car", mappedBy="driver") 
* @Groups({"driver"}) 
*/ 
private $car; 

/** 
* @var \DateTime $created 
* 
* @Gedmo\Timestampable(on="create") 
* @ORM\Column(type="datetime") 
* @Groups({"default"}) 
*/ 
protected $created; 

/** 
* @var \DateTime $updated 
* 
* @Gedmo\Timestampable(on="update") 
* @ORM\Column(type="datetime") 
* @Groups({"default"}) 
*/ 
protected $updated; 


} 

Мой контроллер:

<?php 
namespace AppBundle\Controller; 

use AppBundle\Entity\User; 
//... 

class UsersController extends AppController{ 

    /** 
    * Get list of Admins 
    * @Annotations\Get("/api/v1/admins", name="list_of_admins") 
    * @return \FOS\RestBundle\View\View 
    */ 
    public function getAdminsAction(){ 

     if(!$this->isGranted('ROLE_ADMIN')){ 
      throw new AccessDeniedException('Only for Admin'); 
     } 

     $admins = $this->getDoctrine()->getRepository('AppBundle:User')->findByRole('ROLE_ADMIN'); 

     return $this->view(['data' => $admins], Codes::HTTP_OK); 

    } 

} 

Пользователь с ролью ROLE_ADMIN не имеет автомобиля (автомобиль имеют только пользователи с ролью ROLE_DRIVER). Когда я пытаюсь получить всех администраторов, я получаю следующее:

{ 
    "id": 4, 
    "username": "[email protected]", 
    "email": "[email protected]", 
    "roles": [ 
    "ROLE_ADMIN" 
    ], 
    "photoFiles": [], 
    "name": "Andrii", 
    "car": null 
} 

Я пробовал добавлять группы. Что мне нужно, чтобы добавить свой контроллер для приема данных только от группы по умолчанию и уведомления

ответ

9

Как напоминание, Groups в JMSSerializer используется в качестве стратегии исключения.

Стратегия исключения состоит из конкретного подхода, используемого для раскрытия/исключения свойств в зависимости от состояния/контекста.

Для того, чтобы правильно использовать их, то первая вещь, которую вы должны сделать, это исключить все свойства вашего объекта:

// ... 
use JMS\Serializer\Annotation as JMS; 

/** 
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository") 
* @JMS\ExclusionPolicy("all") 
*/ 
class User extends BaseUser 

Теперь, вы явно выставить свойства в зависимости от Groups:

/** 
* @ORM\Column(type="string", length=255, nullable=true, unique=false) 
* @JMS\Groups({"default"}) // Idem for all properties you want render in group "default" 
*/ 
protected $name; 

/** 
* @ORM\Column(type="string", length=255, nullable=true, unique=false) 
* @JMS\Groups({"notification"}) 
*/ 
protected $deviceId; 

Затем вы должны определить используемый Group в действии вашего контроллера:

/** 
* Get list of Admins 
* @Annotations\Get("/api/v1/admins", name="list_of_admins") 
* @Annotations\View(serializerGroups={"default", "notification"}) // Here set the Group used 
* @return \FOS\RestBundle\View\View 
*/ 
public function getAdminsAction() 
{ 
    if(!$this->isGranted('ROLE_ADMIN')){ 
     throw new AccessDeniedException('Only for Admin'); 
    } 

    $admins = $this->getDoctrine()->getRepository('AppBundle:User')->findByRole('ROLE_ADMIN'); 

    return $this->view(['data' => $admins], Codes::HTTP_OK); 
} 

Теперь $admins содержит только свойства, подверженные действию группы default и notification.

Вы также можете сделать это вручную, вместо использования аннотаций:

$view = $this->view($admins, 200); 
$view->setSerializerGroups(array('default', 'notification')); 

return $this->handleView($view); 

Для получения дополнительной информации см Exclusion strategies.

Надеюсь, это ясно для вас.

+0

Привет, Какой импорт (использование) нам нужно использовать аннотацию '* @Annotations \ View (serializerGroups = {" default "," notification "})' в контроллере? Благодаря! –

+2

Автоответ: использование FOS \ RestBundle \ Controller \ Annotations –

+0

Функция 'setSerializerGroups' была удалена. Вы должны использовать [контекст сериализации напрямую] (https://github.com/FriendsOfSymfony/FOSRestBundle/issues/521#issuecomment-207071563). – fracz

Смежные вопросы