Symfony2,FOSRestBundle。如何使用JMSSerializerBundle组?

时间:2016-02-16 15:51:36

标签: symfony 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": "admin@site.com",
  "email": "admin@site.com",
  "roles": [
    "ROLE_ADMIN"
  ],
  "photoFiles": [],
  "name": "Andrii",
  "car": null
}

我尝试添加群组。 我需要添加我的控制器才能接收来自默认通知

组的数据

1 个答案:

答案 0 :(得分:11)

作为提醒,JMSSerializer中的Groups用作排除策略。

排除策略包括用于根据条件/上下文公开/排除属性的特定方法。

为了正确使用它们,您首先要做的是排除实体的所有属性:

// ...
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仅包含公开给群组defaultnotification的属性。

您也可以手动执行此操作,而不是使用注释:

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

return $this->handleView($view);

有关更多信息,请参阅Exclusion strategies

我希望你能清楚。