2016-02-16 30 views
7

Ho entità:Symfony2, FOSRestBundle. Come usare il gruppo con 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; 


} 

mio controller:

<?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); 

    } 

} 

Un utente con ruolo ROLE_ADMIN non hai l'auto (auto hanno solo gli utenti con ruolo ROLE_DRIVER). Quando cerco di ottenere tutti gli amministratori ottengo questo:

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

ho cercato aggiungere gruppi. Che cosa ho bisogno di aggiungere il mio controller per ricevere i dati solo dal gruppo predefinito e notifica

risposta

9

Come promemoria, Groups in JMSSerializer sono utilizzati come strategia di esclusione.

Una strategia di esclusione consiste in un approccio specifico utilizzato per esporre/escludere le proprietà in base alla condizione/contesto.

Per poter utilizzare correttamente, la prima cosa che dovete fare è escludere tutte le proprietà del soggetto:

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

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

Ora, avete esporre in modo esplicito le proprietà a seconda 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; 

Quindi, è necessario definire il Group utilizzato nell'azione del controller:

/** 
* 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); 
} 

Ora, $admins contiene solo le proprietà esposte al gruppo default e notification.

È anche possibile farlo manualmente invece di utilizzare un'annotazione:

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

return $this->handleView($view); 

Per maggiori informazioni, consultare Exclusion strategies.

Spero sia chiaro per voi.

+0

Salve, quale importazione (utilizzo) è necessario utilizzare l'annotazione '* @Annotations \ View (serializerGroups = {" default "," notification "})' nel controller? Grazie! –

+2

Risposta personale: utilizzare FOS \ RestBundle \ Controller \ Annotations –

+0

La funzione 'setSerializerGroups' è stata rimossa. È necessario utilizzare [contesto di serializzazione direttamente] (https://github.com/FriendsOfSymfony/FOSRestBundle/issues/521#issuecomment-207071563). – fracz