Mustache.php rendering multi-dimensional data - php

I'm utilizing Mustache to template some XML responses for an API. I was wondering how I could use the XML template below to render data from this array?
The data is not rendering at all when using this code:
$result = $m->render($template, $r);
echo $result;
Here is JSON converted data:
[
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"41",
"condition":"A",
"stocknumber":"F0049356",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"U3020",
"comments": "comment for #0"
},
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"68",
"condition":"C",
"stocknumber":"F0048586",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"KEEP"
"comments": "comment for #1"
},
{
"UUID": "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID": "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company":"UAR",
"itemname":"DOOR ",
"daysinstock":"280",
"condition":"B",
"stocknumber":"171013",
"ic":"120-00409AL",
"price":"750.00",
"quantity":"1",
"location":"YCR4"
"comments": "comment for #2"
}
]
XML template trying to render
$template = '<SupplierResponse>
<QuotedPartList>
{{#parts}}
<QuotedPart>
<BMSObject>
<UUID>{{UUID}}</UUID>
<RefUUID>{{RefUUID}}</RefUUID>
</BMSObject>
<SupplierResponseCode>AsRequested</SupplierResponseCode>
<SupplierRefLineNum>{{SupplierRefLineNum}}</SupplierRefLineNum>
<PartNumInfo>
<PartNumType>Stock</PartNumType>
<PartNum>{{stocknumber}}</PartNum>
</PartNumInfo>
<PartNumInfo>
<PartNumType>IC</PartNumType>
<PartNum>{{ic}}</PartNum>
</PartNumInfo>
<PartType>PAL</PartType>
<PartDesc>{{itemname}}</PartDesc>
<PriceInfo>
<UnitListPrice>{{price}}</UnitListPrice>
<UnitNetPrice>{{price}}</UnitNetPrice>
</PriceInfo>
<RInfo>
<Grade>{{condition}}</Grade>
<DaysInStock>{{daysinstock}}</DaysInStock>
<PartLocation>{{location}}</PartLocation>
<PartStore>{{company}}</PartStore>
</RInfo>
<Availability>
<Quantity>{{quantity}}</Quantity>
<InventoryStatus>Available</InventoryStatus>
<AvailableShipDate>2018-05-10</AvailableShipDate>
</Availability>
<LineNoteInfo>
<LineNoteMemo>{{comments}}</LineNoteMemo>
</LineNoteInfo>
</QuotedPart>
{{/parts}}
</QuotedPartList>
</SupplierResponse>';

Edit: Based on new information that came to light after I posted this answer - your issue occurred because Mustache requires data to be stored in an associative array.
// Not correct
$data = [
[
'Foo' => 'Bar'
],
[
'Biz' => 'Buz'
],
]
// Correct
$data = [
'MyData' => [
[
'Foo' => 'Bar'
],
[
'Biz' => 'Buz'
]
]
]
You could try something like this:
<?php
$objectToPassIn = [
'parts' => [
// .. your data here
]
];
// Load template and initialize Mustache
$m = new Mustache_Engine(array(
'loader' => new Mustache_Loader_FilesystemLoader('path/to/where/template/is/stored', array('extension' => '.xml'))
));
$rendered = $m->render(
'template-name-without-file-extension',
$objectToPassIn
);

Finally got it fixed. The data was not formatted correctly:
Data:
$r = array("parts"=> array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"41",
"condition"=>"A",
"stocknumber"=>"F0049356",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"U3020",
"comments"=> "comment for #0",
"SupplierRefNum"=> 1
),
array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"68",
"condition"=>"C",
"stocknumber"=>"F0048586",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"KEEP",
"comments"=> "comment for #1",
"SupplierRefNum"=> 2
),
array(
"UUID"=> "655482ab-38ee-433f-b310-1f6f227113b9",
"RefUUID"=> "92a8ecf6-8eb6-4d1e-b88d-59b50c3b0cc9",
"company"=>"UAR",
"itemname"=>"DOOR ",
"daysinstock"=>"280",
"condition"=>"B",
"stocknumber"=>"171013",
"ic"=>"120-00409AL",
"price"=>"750.00",
"quantity"=>"1",
"location"=>"YCR4",
"comments"=> "comment for #2",
"SupplierRefNum"=> 3
}
}
);
Code:
$result = $m->render($template, $r); // Used same template as in my original post.

Related

How to Format JSON correctly Laravel 5.5

i'm trying to load events into a calendar.
Therefore i need to make a JSONstring with the event data but i can't figure out how to do this.
how i create the data:
$tickets = Ticket::where('mechanic_id', $request->mechanic_id)->get();
$tickets_json[] = [];
foreach($tickets as $ticket) {
$tickets_json['title'] = $ticket->number;
$tickets_json['start'] = $ticket->planned_timestamp_start->format('d-m-Y H:i');
$tickets_json['end'] = $ticket->planned_timestamp_end->format('d-m-Y H:i');
$tickets_json['url'] = '/tickets/' . $ticket->id;
}
This returns:
array:5 [▼
0 => []
"title" => "452"
"start" => "27-10-2017 09:00"
"end" => "27-10-2017 12:00"
"url" => "/tickets/2"
]
This is not what i want and need.
I need it like this :
{
title: '63782136',
start: '27-10-2017 09:00',
end: '"27-10-2017 12:00"',
url: '/tickets/2'
},
{
title: '23123',
start: '27-10-2017 09:00',
end: '"27-10-2017 12:00"',
url: '/tickets/3'
},
{
title: '432512',
start: '27-10-2017 09:00',
end: '"27-10-2017 12:00"',
url: '/tickets/4'
},
I have tried:
return response()->json($tickets_json);
But doesn't return the correct format:
#data: "{"0":[],"title":"452","start":"27-10-2017 09:00","end":"27-10-2017 12:00","url":"\/tickets\/2"}"
It adds {"0":[],}
.
Thanks in advance.
You're making the mistake of assigning your data to the first dimension of the array when you want it in the second dimension. The following should do the trick:
$tickets_json = [];
$tickets->each(function ($ticket) use (&$tickets_json) {
$tickets_json[] = [
'title' => $ticket->numer,
'start' => $ticket->planned_timestamp_start->format('d-m-Y H:i'),
'end' => $ticket->planned_timestamp_end->format('d-m-Y H:i'),
'url' => '/tickets/' . $ticket->id
];
});
return $tickets_json;
This code will give you a proper formatted array which you can use to get the following JSON output:
[
{
"title": "63782136",
"start": "27-10-2017 09:00",
"end": "27-10-2017 12:00",
"url": "/tickets/2"
},
{
"title": "23123",
"start": "27-10-2017 09:00",
"end": "27-10-2017 12:00",
"url": "/tickets/3"
}
]

How to get data from JSON file by parsing array name from the url

I am trying to print data in json format from my 'data.json' file. With my php file (alldata.php), I could get all data (arrays) pretty printed. But where I want you to help me is how to get a specific array name and it objects/content.
My alldata.php looks like this:
{
"players": [
{
"name": "Marcos Alonso",
"position": "Left-Back",
"nationality": "Spain",
"marketValue": "9,000,000 €",
"created": "2017-04-15 10:04:58"
}],
"articles": [
{
"author": "Stephen Walter",
"title": "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url": "http://www.telegraph.co.uk/news/2017/04/15/disruptive-stag-party-revellers-thrown-plane-manchester-airport/",
"publishedAt": "2017-04-15T09:25:10Z"
}],
land": [
{
"state": "Somewhr",
"found": "1889",
"area": "6,812",
"empl": "1,325",
"ppl": "16,842"
}]
}
In php, how can I get an array e.g "players" with the content by using url such as 'alldata.php?search=players'
Here is a code sample....
//get content of the JSON API using file_get_contents()
$url = ('myJson.json');
$jsondata = file_get_contents($url);
//convert json object to php associative array
$data = json_decode($jsondata, true);
what do I do here to query the data.json file for a specific array?????
header('Content-Type: application/json; charset=UTF-8');
$json_string = json_encode($????????????, JSON_PRETTY_PRINT);
print $json_string;
Thanks
If I properly understood what you mean, and if your array has always the same tree, this wilp help you access the data :
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
$array = array(
0 => array(
"players" => array(
"name" => "Marcos Alonso",
"position" => "Left-Back",
"nationality" => "Spain",
"marketValue" => "9,000,000 €",
"created" => "2017-04-15 10:04:58"
),
"articles" => array(
"author" => "Stephen Walter",
"title" => "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url" => "http://www.telegraph.co.uk/news/2017/04/15/",
"publishedAt" => "2017-04-15T09:25:10Z"
),
"land" => array(
"state" => "Somewhr",
"found" => "1889",
"area" => "6,812",
"empl" => "1,325",
"ppl" => "16,842"
)
),
1 => array(
"players" => array(
"name" => "Sebastian Vettel",
"position" => "Driver",
"nationality" => "Germany",
"marketValue" => "9,000,000 €",
"created" => "2013-03-15 11:04:52"
),
"articles" => array(
"author" => "Stephen Walter",
"title" => "Disruptive stag party revellers thrown off plane at Manchester Airport",
"url" => "http://www.telegraph.co.uk/news/2017/04/15/",
"publishedAt" => "2017-04-15T09:25:10Z"
),
"land" => array(
"state" => "Somewhr",
"found" => "1889",
"area" => "6,812",
"empl" => "1,325",
"ppl" => "16,842"
)
)
);
/* end of array */
$data1 = json_encode($array); /* just checking - not needed after that */
$data = json_decode($data1, true); /* just checking - not needed after that */
$needle = "articles"; /* should be $needle = $_GET['search']; and checked before use */
//print_r($data); /* just checking */
foreach($data as $value){ /* we access 1st level */
echo '** Needle is: '.$needle.' **<br/>';
foreach($value[$needle] as $sub_key => $sub_data){ /* we access 2nd level */
echo $sub_key.'-->'.$sub_data.'<br/>'; }
}
?>
Once you access the data, you can easily do what you want with it...

How to create json string given below

I am android developer and new in PHP. I don't know PHP very well. I create
<?php
header('Content-Type: application/json; charset=utf-8');
$mysqli = new mysqli ('localhost', 'mabhi', '9993', 'general');
//PROBLEM LANGUAGE ?????
if (function_exists('mysql_set_charset')) {
mysqli_set_charset($mysqli, 'utf8');
} else {
mysqli_query($mysqli, "SET NAMES 'utf8'");
}
// Check if album id is posted as GET parameter
$myq = $mysqli->query('SELECT * FROM Ages');
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
}
echo json_encode($array, JSON_UNESCAPED_UNICODE);
?>
output:
{
"Questions": [
{
"Question": "sfsa sfd s sdf",
"Answer": "vvv",
"CorrectAnswer": null
},
{
"Question": "dsfgdsfgv dsf dfs",
"Answer": "vvvv vv",
"CorrectAnswer": null
}
]
}
But I would like json output in below format: Answer are displayed multiple times for each question. Please suggest me what changes in my code.
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
{
"Answer": "vvvvvvv"
},
{
"Answer": "vvv"
},
{
"Answer": "vv"
},
{
"Answer": "v"
}
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
{
"Answer": "Lee"
},
{
"Answer": "Wrangler"
},
{
"Answer": "Levi's"
},
{
"Answer": "Diesel"
}
]
}
]
}
As pointed by jereon, you are overwriting the value of Answer key. You need to create a separate array for the all the Answers together.
Change
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answer' => $myr['option1'],
'Answer' => $myr['option2'],
'Answer' => $myr['option3'],
'Answer' => $myr['option4'],
'CorrectAnswer' => $myr['CorrectAnswer'],
));
to
$array["Questions"][] = (array(
'Question' => $myr['Question'],
'Answers' => array((object)array('Answer' => $myr['option1']),
(object)array('Answer' => $myr['option2']),
(object)array('Answer' => $myr['option3']),
(object)array('Answer' => $myr['option4'])),
'CorrectAnswer' => $myr['CorrectAnswer'],
));
You should not assign multiple array elements with the same identifier ("Answer") as they would just overwrite each other. I would suggest you to use a non-associative array for the Answers so that your target JSON would look like this:
{
"Questions": [
{
"Question": "dfsfdsfgv dfsfsd dfs sf",
"CorrectAnswer": 3,
"Answers": [
"vvvvvvv",
"vvv",
"vv",
"v"
]
},
{
"Question": "dgdsgdsgdsgszdfvgfvds",
"CorrectAnswer": 0,
"Answers": [
"Lee",
"Wrangler",
"Levi's",
"Diesel"
]
}
]
}
Therefore you would use the following PHP code for the loop:
$array = array();
while ($myr = $myq->fetch_assoc()) {
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'Answers' => array(
$myr['option1'],
$myr['option2'],
$myr['option3'],
$myr['option4'],
),
);
}
First thing you are doing wrong is you are overwriting the value of answer options so what will happen is when your 1st option will be overwritten by 2nd option, 2nd option with 3rd and 3rd option with 4th option. So you will have to create an array for answers and push every answer in that array and in the end assign this answer option array to answer. So your code should look like below
while ( $myr = $myq->fetch_assoc () ) {
$answers_array=new array();
$answer_option=new stdClass(); // Create a object to format in required format and use this object to store every option of answer
$answer_option->answer=$myr['option1'];
array_push($answers_array,$answer_option);
$answer_option->answer=$myr['option2'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option3'];
array_push($answers_array, $answer_option);
$answer_option->answer=$myr['option4'];
array_push($answers_array,$answer_option);
$array["Questions"][] = array(
'Question' => $myr['Question'],
'CorrectAnswer' => $myr['CorrectAnswer'],
'answers' => $answers_array;
);
}

getting relational results from three tables into one nested array

i have googled for solution to my problem but nun helped me.
here i have three tables items, feeds and images. each item has one feed and one or more images.
i have 3 functions. one is to return records from items table the second one receives feeds_id (foreign key in items table) then return records from feeds table. the third function is to return all images related to items_id.
those functions are :
* To get all items in database:
function get_items(){
return $query = Database::getInstance('db')
->table('items')
->columns(
'id',
'items.rowid',
'items.feed_id as feed_id',
'title' )
->findAll();
}
* To get feed data from feeds table :
function get_feeds($id){
return $query = Database::getInstance('db')
->table('feeds')
->eq('id',$id)
->findAll();
}
* To get image data from images table :
function get_images($id){
return $query = Database::getInstance('db')
->table('images')
->columns('items_id','src as image_url',
'title as image_title',
'alt')
->eq('items_id',$id)
->findAll();
}
Then i have the following code to call those function and display the result in jsonformat:
$response['items'] = array();
$response['feeds'] = array();
$response['images'] = array();
foreach ($items = get_items() as $item) {
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
);
foreach ($feeds = get_feeds((int)$item['feed_id']) as $feed) {
$response['feeds'][] = array(
'title' => $feed['title'],
'logo_url' => $feed['logo_url'],
'site_url' => $feed['site_url'],
);
}
foreach ($images = get_images($item['id']) as $image) {
$response['images'][] = array(
'id' => $image['items_id'],
'url' => $image['image_url'],
'thumb' => $_SERVER['SERVER_NAME'] . /myServer/images/thumbs/'. 'thumb_'.basename($image['image_url']),
'title' => $image['image_title'],
'alt' => $image['alt']
);
}
}
echo json_encode($response, JSON_PRETTY_PRINT);
so, my expectation is to get json output like:
"items": [
{
"id": ,
"feed_id":
"title":
"feeds": [
{
"title": ,
"logo_url": ,
"site_url": "
}
]
"images": [
{
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{
....
}
]
}]
i mean each item array should include nested arrays of its related data coming from get_feeds and get_images functions.
instead of that, i get response like :
//here i select two items from my db
"items": [
{ //first_item
"id": ,
"feed_id":
"title":
},
{ //second_item
"id": ,
"feed_id":
"title":
}
],
"feeds": [
{ // feed data for first item
"title": ,
"logo_url": ,
"site_url": "
},
{ // feed data for second item
"title": ,
"logo_url": ,
"site_url": "
}
],
"images": [
{ // image data for first item
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{ // other images data
....
}
]
}]
as you see i am getting output without keeping relation between items, feeds and images, all of them are shown independently.
my queries are fine but i am suspecting error in my foreach statements.
i could fix this issue by joining those tree tables in one query, but i don't want to do that because i need to do validation and other operations to output comes from each table.
i appreciate your help
i found the solution. it is very easy :)
it is just like:
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
'feeds' => array(
)
'images' => array(
)
);

How do I remove nested object from an object in CakePHP?

CakePHP API returns result like this:
{
"status": "OK",
"themes": [
{
"Theme": {
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
}
]
}
I would like to ask, how can in remove nested Theme object to get result like this?:
{
"status": "OK",
"themes": [
{
"id": "20",
"user_id": "50",
"name": "dwdwdw",
"language_code_from": "cz",
"language_code_to": "en",
"type": "CUSTOM",
"created": "2014-10-19 15:36:05",
"count_of_cards": 0
}
]
}
Here is my CakePHP code:
$this->Theme->recursive = -1;
// GET USER ID
$themeData['user_id'] = $isSessionValid;
// GET ALL THEMES RELATED TO USER
$foundThemes = $this->Theme->find('all', array(
'conditions' => array(
'Theme.user_id' => $themeData['user_id'])
)
);
$themes = array();
// FOREACH THEMES AND GET COUNT FOR CARDS FOR EACH THEME
foreach($foundThemes as $foundTheme) {
// GET COUNT OF QUESTIONS FOR ACTUAL THEME
$countOfCards = $this->Theme->Card->find('count', array(
'conditions' => array(
'Card.theme_id' => $foundTheme['Theme']['id'])
)
);
// APPEND TO ACTUAL ARRAY
$foundTheme['Theme']['count_of_cards'] = $countOfCards;
array_push($themes,$foundTheme);
}
// SET SUCCESS RESPOSNSE
$this->set(array(
'status' => 'OK',
'themes' => $themes,
'_serialize' => array(
'status',
'themes',
)
));
Many thanks for any advice.
You can manipulate CakePHP's array formats using its built in Hash utility: http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash
What I would do would be to flatten the results:
$results = Hash::flatten($results);
Your data array will end up as a single dimensional array looking like this:
$results = array(
'status' => 'OK'
'themes.0.Theme.id' => 20,
...
'themes.1.Theme.id' => 21,
...
);
You can then use string replace to remove "Theme" from your keys:
$keys = array_keys($results);
$keys = str_replace('Theme.', '', $keys);
Then you can use Hash::expand to get your original array, now formatted how you want:
$results = Hash::expand(array_combine($keys, array_values($results)));
I dont think CakePHP supports this. if you want to do this with an easy way check the Set Utility.
http://book.cakephp.org/2.0/en/core-utility-libraries/set.html

Categories