JMSSerializerBundle and Symfony 2 - Output Doctrine/ODM to JSON file - php

I am trying to retrieve all records and display them in a JSON file.
My current function retrieves all Events that belong to a specific user.
/**
* create json files from doctrine/mongo
* #Route("/createjson", name="createjson")
*/
public function createJson()
{
// check user authentication
$this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');
$dm = $this->get('doctrine_mongodb')->getManager();
$repository = $dm->getRepository('AppBundle:Event');
$events = $repository->findBy(array('user' => $this->getUser()));
$serializer = SerializerBuilder::create()->build();
$result = $serializer->deserialize($events, 'AppBundle\Document\Event', 'json');
var_dump($result);
exit;
}
This is not working because some of the elements passed into the serializer are of an array format. Error I am getting.
Warning: json_decode() expects parameter 1 to be string, array given
500 Internal Server Error - ContextErrorException
However if I use the inbuilt Symfony Serializer it works fine:
$serializer = $this->container->get('serializer');
$reports = $serializer->serialize($events, 'json');
return new Response($reports);
However the JSON to be produced will be different to my Document/Entity hence why I want/need to use the JMSSerializerBundle.
For example, a record looks like this:
[{
"id": "572041b3288b560e5e00451c",
"name": "Test",
"date": "2016-04-27T05:25:00+1000",
"enddate": "2016-04-30T11:55:00+1000",
"location": {
"name": "Sydney, NSW"
},
"key": {
"id": "1g43g34g34g23f32g32G32gGSDF"
},
"user": {
"id": "57203174288b560e5e0044da"
}, ...
}]
But I only want to display (output) to JSON
[{
"id": "572041b3288b560e5e00451c",
"name": "Test",
"date": "2016-04-27T05:25:00+1000",
"location": "Sydney, NSW"
}]
How would I go about doing this? There is not much documentation on JMSSerializerBundle online.
Edit: I should mention that the database collection I am querying has a relation to the User collection which is managed by FOSUserBundle. I'm not sure if this has any relation to my problem however

You should look at the documentation of the bundle, may be you will find more information
http://jmsyst.com/bundles/JMSSerializerBundle
http://jmsyst.com/libs/serializer/master/usage
You seems to use the wrong function of the serializer. In your case, you seems to need to get a json from your user object, so you need to use
$serializer = SerializerBuilder::create()->build();
$result = $serializer->serialize($events, 'AppBundle\Document\Event', 'json');
serialize($object):string : get a string from an object
deserialize($string):object : get an object from a representation of an object (json, xml...).

Related

search through JSON Object for specific key

I'm getting a JSON response from an API provider which I can't change, and there are lots of nested objects in the response and then there is an object which I need, below is just the example of response actual response has a lot of nested objects and then the match object,
I can easily access the match object but in some case, the API provider add some more object above it as shown in the 2nd response where he added the group and then there is match object which I need,
still by using some if, else we can get through it.
but are there any methods or ways available that can directly give me access to the match object or can find the match object?
I'm using laravel 5.8
and tried some of the collection methods none of them work on objects.
in actual response, I have to go 7 steps nested.
//1nd API response
[{
"version": "2.258.2",
"sport": "badminton",
"lang": "en",
"generated_utc": "2021-07-28T13:58:16+00:00",
"method": {
"method_id": "258",
"name": "get_matches"
"match" : {
score_a:0,
score_b:1
}
}
}]
//2nd API response
[{
"version": "2.258.2",
"sport": "badminton",
"lang": "en",
"generated_utc": "2021-07-28T13:58:16+00:00",
"method": {
"method_id": "258",
"name": "get_matches"
"group":{
"match" : {
score_a:0,
score_b:1
}
}
}
}]
Thank You!

Get whole object data instead id in Laravel

I have an object with this structure, that I need to get name of source_id in my blade file,
When I try to access that by the way
$data['source_id']['name']
$data->source_id->name
$data->{'source_id'}->{'name'}
I got this error
Trying to get property 'name' of non-object
I just try this $data->source_id, but it return its ID, instead the object,
any suggestion?
{
"id": 4,
"type": "s1",
"source_id": {
"id": 1,
"code": "۱",
"name": "تیل پطرول",
"manager": "نجیب",
"phone": "۰۷۷۲۴۳۴۳۲۱",
"address": "دهمزنگ",
"capacity": "0.00",
"oum_id": 1,
"created_at": "2021-03-02T15:55:20.000000Z",
"updated_at": "2021-03-02T15:55:20.000000Z"
},
"source_type": "STRG",
}
Here is the function to get data
public function loadSale($id){
$base = Sale::findOrFail($id);
if ($base->type == "s1") {
$sale = Sale::with(['saleS1.project.pro_data', 'source_id'])->where('id', $id)->first();
$sale['sales'] = $sale->saleS1;
}
return $sale
}
I could understand your problem. But it is an object not an array. You have to use a loop to access the object. Create a for loop and and inside which you can access the particular field of the object. Hope this helpful
As #MAY mentioned in the comment
I guess the name of your relation and foreign key field is same, that's why you get id when you do this $data->source_id
So I modify the relation and define the source, now I can't access the data simply as before $data->source->name

Laravel Model created_at inconsistent display

I am new to laravel and php,
I have the code below, REST API
public function sendMessage(Request $request)
{
$message = Message::create($request->all());
return response()->json(['result'=>'success','created_at'=>$message->created_at],200);
}
This is displayed like this in the postman
{
"result": "success",
"created_at": "2020-06-29T23:31:32.000000Z"
}
If I change the return message-object by changing return statement to
return response()->json(['result'=>'success','created_at'=>$message],200);
Then time format is displayed differently as below
{
"result": "success",
"created_at": {
"sender": "47",
"receiver": "23",
"message": "hello world reply",
"updated_at": "2020-06-29 23:38:53",
"created_at": "2020-06-29 23:38:53",
"id": 515
}
}
I do not want this form "2020-06-29T23:31:32.000000Z" when I access it as a property,not sure what is this 00000Z at then end. want it like this "2020-06-29 23:38:53" Any help
When you access the data member ->created_at you get a Carbon instance, instead if you serialize the object, you get its attribute.
This is why you are getting two different serialization, because you are serializing two different things (one is a Carbon instance, the onthe one is a Model)
If you convert the Carbon instance to a string it will be in the same format as you see in the serialized model. When you pass it without doing this it is going to json_encode the value which will return it how you are currently seeing it.
return response()->json([
'result' => 'success',
'created_at' => (string) $message->created_at
],200);

Laravel Collection Returns Inconsistant Results

I have a collection that will switch between responding as an array or as an object seemingly at random. What would cause that to happen?
$events = Event::all();
$events = $events->map(function ($event) use ($request) {
$reducedEventName = Helper::alphaNum($event->name);
$reducedRequestName = Helper::alphaNum($request->name);
$distance = levenshtein($reducedEventName, $reducedRequestName);
return [
'name' => $event->name,
'url' => route('event.view', ['slug' => $event->slug]),
'distance' => $distance,
];
})
->filter(function ($event) {
return $event['distance'] <= Helper::threshold($event['name']);
})
->take(3)
->sortBy('distance');
return $events->toArray();
This method is called via XHR, so I want the raw JSON response. Sometimes it looks like this (👍):
[{
"name": "Taylor Swift - Reputation - Release",
"url": "http:\/\/localhost\/e\/lgKejoPSg",
"distance": 22
}, {
"name": "Wiz Khalifa \"Laugh now, fly later\"",
"url": "http:\/\/localhost\/e\/DdLnFD3Qf",
"distance": 24
}]
And sometimes it looks like this (👎):
{
"1": {
"name": "Wiz Khalifa \"Laugh now, fly later\"",
"url": "http:\/\/localhost\/e\/DdLnFD3Qf",
"distance": 18
},
"0": {
"name": "Taylor Swift - Reputation - Release",
"url": "http:\/\/localhost\/e\/lgKejoPSg",
"distance": 23
}
}
Laravel 5.4
As to your question, I am not sure what could cause that to happen as the sortBy() method states it returns a collection. Do you return that exact $events as is to your blade? If so that could be inconsistency on the browser deciding how to handle the collection that is sent back to it. You could always use ->toArray() at the end of your query to ensure that it always returns an array, or ->toJson() if you don't want to do anything else with it.
Resorting the results tries to preserve the original keys, so I needed to discard the original keys:
return array_values($events->toArray());

Sort data from mongodb by decending order

I am trying to output users chat history and then put it into a JSON object I want the messages to come out in descending order but when I try $cursor->sort() is throwing Call to a member function sort() on a non-object
$cursor = $collection->findOne(array('chatbetween' => $channel_name));
$cursor->sort(array('messages' => -1));
$messages = array();
for($i=0; $i<count($cursor['messages']); $i++){
$object = array('message'=>$cursor['messages'][$i]['message'],
'time'=>date('Y-m-d\TH:i:s\Z', $cursor['messages'][$i]['time']->sec),
'user'=>$cursor['messages'][$i]['user']);
$messages[] = $object;
}
echo json_encode($messages);
Here is what a collection looks like.
"_id": ObjectId("4f3c19e37edae1723d000000"),
"chatbetween": "private-4f3bb96d7edae1850b0000004f3c0d2d7edae1e935010000",
"messages"▼: {
"0": {
"user": "4f3c0d2d7edae1e935010000",
"time": ISODate("2012-02-15T20: 47: 30.175Z"),
"message": "message1"
},
"1": {
"user": "4f3bb96d7edae1850b000000",
"time": ISODate("2012-02-15T20: 47: 37.79Z"),
"message": "message2"
},
"2": {
"user": "4f3c0d2d7edae1e935010000",
"time": ISODate("2012-02-15T20: 47: 43.295Z"),
"message": "message3"
}
}
Your problem is you're trying to sort sub-documents, whereas the .sort() function is for sorting documents.
So, each object in the collection is a document--in this case, each chat is a document. You can sort your chats with .sort(), but you have subdocuments called messages within your documents (sub-documents), and Mongo doesn't sort those for you.
See some answers to a similar question here:
Sort Sub Documents in MongoDB

Categories