user3531149
user3531149

Reputation: 1539

How to to prevent doctrine2 from returning certain fields

What I have coded is a oneToMany relationship with doctrine

one user ---> has many notifications

This is how I get the data

/**
 * @Route("/test")
 */
public function testRoute()
{
    //get the user notifications 
    $notifications = $this->getUser()->getNotifications();

    //return json response
    $serializer = $this->get('serializer');
    $json = $serializer->serialize($notifications, 'json');
    $response =  new Response($json);
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

This is what the controller returns

    [
{
    "id": 1,
    "receiver": 1,
    "notification_type": "new_comment",
    "triggered_by": {
      "id": 1,
      "username": "gabriel",
      "username_canonical": "gabriel",
      "password":    "3e6bS2I==",
      "email": "[email protected]",
      "first_name": "Gabriel",
      "last_name": "ThaKid",
      "likes_counter": 0,
      "dislikes_counter": 2,
      "favourites_counter": 0,
      "profile_pic": "profilepic_60181.png", 
      "salt": "Lqch0N84UH1QmFI5O",
      "form_token": "sO6NgWd",
      "is_active": true, 
      "registration_confirmation": "success",
      "secret_confirmation_id": "qTwNGm4CSKHzJOe8ry9DcXavt",
      "socket_token": "KuMlxYHa"
},
"created_at": "2014-12-16T13:36:20+0100",
"link_to": "#test"
},
{
"id": 2,
"receiver": 1,
"notification_type": "new_comment",
 "triggered_by": {
   "id": 1,
   "username": "gabriel",
   "username_canonical": "gabriel",
   "password": "3e6bS2IYX1DONLA/70a8hzMUQ==",
   "email": "[email protected]",
   "first_name": "Gabriel",
   "last_name": "ThaKid",
   "likes_counter": 0,
   "dislikes_counter": 2,
   "favourites_counter": 0,
   "profile_pic": "profilepic_60181.png",
   "profile_rank": "Beginner", (...)
},
   "created_at": "2014-12-16T13:36:24+0100",
   "link_to": "#test"
}
]

I think you get the point, it returns the notifications of a certain user which is allright, I also need certain fields from the user, like the lastname and the firstname, so the returned data is usable in the application. But doctrine also returns the hashed password and the salt along with tokens and information the user doesn't need to know.

how do I tell doctrine not to return those fields or not to fetch them to begin with?

Upvotes: 2

Views: 1519

Answers (2)

Holger
Holger

Reputation: 151

You should create a custom repository class.

In this class create a method like this:

// src/AppBundle/Entity/NotificationRepository.php
namespace AppBundle\Entity;

use Doctrine\ORM\EntityRepository;

class NotificationRepository extends EntityRepository
{
    public function findAllByUser()
    {
        return $this->getEntityManager()
            ->createQuery(
                'SELECT [only the fields you need] FROM [....]'
            )
            ->getResult();
    }
}

For the DQL query you could use the partial object syntax.

Upvotes: 3

kix
kix

Reputation: 3319

This is not about Doctrine, this is the default Serializer that tries to fetch and return all of the values available.

Take a look at the Serializer component documentation to understand how to ignore properties. Basically, you'll have to pass a normalizer into your serializer's constructor:

<?php
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$normalizer = new GetSetMethodNormalizer();
$normalizer->setIgnoredAttributes(array('age'));
$encoder = new JsonEncoder();

$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($person, 'json');

Also, I'd strongly suggest to switch to JMSSerializer and/or use FOSRestBundle, as it gives a lot more flexibility for the serialization. The property list is configured against contexts, and has base exclusion strategies. This way, you'd only need to list properties to expose, not to exclude:

AppBundle\Entity\Car:
  exclusion_policy: all
  properties:
    id:
      expose: true
    vendor:
      expose: true
    title:
      expose: true

In the given example, all properties that were not listed would be excluded.

Upvotes: 3

Related Questions