Encoding JSON with PHP from database table data - javascript

I want to be able to encode JSON into a specific format so that it can be used with another script that I have created. I am able to encode it with PHP into JSON but need to be able to push these encoded JSON sets to a 'named' array.
At the moment I am getting this
{
"ann_date":"14\/12\/2017",
"ann_title":"Return Dates",
"ann_content":"Have a good break. The course timetable resumes on Wednesday 3rd January 2018",
"tutor":"John Smith"
}
From this code
class AnnData {
public $ann_date = "";
public $ann_title = "";
public $ann_content = "";
public $tutor = "";
}
while($row = mysqli_fetch_array($result)) {
$ann_date = $row['ann_date'];
$ann_title = $row['ann_title'];
$ann_content = $row['ann_content'];
$tutor = $row['tutor'];
$annData = new AnnData();
$annData->ann_date = $ann_date;
$annData->ann_title = $ann_title;
$annData->ann_content = $ann_content;
$annData->tutor = $tutor;
$annQ = json_encode($annData);
But need it to look like this
{
"announcements":[{
"ann_date":"14\/12\/2017",
"ann_title":"Return Dates",
"ann_content":"Have a good break. The course timetable resumes on Wednesday 3rd January 2018",
"tutor":"John Smith"}]
}

You can declare an associative array and then encode it:
$annData = new AnnData();
...
$out = array('announcements' => array($annData));
$outJson = json_encode($out);

You can simplify this a lot by getting the correct columns from your database (only the 4 your need) and fetching all rows at once:
$annQ = json_encode([
'announcements' => mysqli_fetch_all($result, MYSQLI_ASSOC),
]);
This replaces all the code you have posted.
An associative array will be stored in the string as an object so you don't need that class either if you are not going to use it anywhere else.

Related

PHP laravel parse data using jQuery or combine them to single array

I have this code
$days = [];
foreach ($list1 as &$day){
$pleads = \DB::table('leads')
->selectRaw('count(*)')
->whereColumn('owned_by_id', 'users.id')
->where('lead_source_id', 7)
->whereRaw("DATE(created_at) = '$day'");
$mleads = \DB::table('leads')
->selectRaw('count(*)')
->whereColumn('owned_by_id', 'users.id')
->where('lead_source_id', 3)
->whereRaw("DATE(created_at) = '$day'");
$aleads = \DB::table('leads')
->selectRaw('count(*)')
->whereColumn('owned_by_id', 'users.id')
->where('lead_source_id', 4)
->whereRaw("DATE(created_at) = '$day'");
$personalleads = \DB::table('users')
->where('id', $id) // User ID
->select('users.id')
->selectSub($pleads, 'pleads')
->selectSub($mleads, 'mleads')
->selectSub($aleads, 'aleads')
->get();
$days []= $performanceTable;
}
return $days;
the output is
[[{"userid":1,"pleads":2,"mleads":1,"aleads":1}],[{"userid":1,"pleads":2,"mleads":1,"aleads":1}]]
The question is how to parse this with jQuery to access the values
Or better how to output them like this with php directly so it's easier to parse them with jQuery in a single array
[{"userid":1,"pleads":2,"mleads":1,"aleads":1},{"userid":1,"pleads":0,"mleads":0,"aleads":0}]
You don't need jQuery. You can use JSON.parse() to turn json into a javascript object.
You can output $days[0] to remove the outer array.

How to convert an associative array of dates into object in jQuery for flatpickr

I've been trying to figure this out for hours, and not getting anywhere at all.
OK, so I have a database table that saves staff holidays, using a start and an end date, so it's a range. If it's a single day, it will be the same date but normally it's a range.
I am using Flatpickr on my site in order to book a job for a specific date and time, but I need to disable dates that the chosen staff member is NOT available on. When the user selects a staff member, there is an ajax call to the holiday table in the database and fetches any holiday dates, puts them in an array then returns it back to the ajax in JSON. Here's my call ($(this).val() refers to the staff dropdown, and this will run on change):
var staffId = $(this).val();
var dateObj = {};
var parsed;
$.post( '/get-availability', { staff_id: staffId }
).done( function(response) {
if(response.length > 0) {
parsed = JSON.parse(response);
$.each(parsed, function(i, element) {
console.log("i : " + i);
dateObj = { from : element['from'], to : element['to'] };
});
}
The PHP in get-availability is as follows:
$staff_id = $request->get('staff_id');
$staff_entity = $this->getDoctrine()->getManager()->getRepository('AppBundle:Staff')->findOneBy(array('id' => $staff_id));
// get all holidays for the staff member
$holiday_repo = $this->getDoctrine()->getManager()->getRepository('AppBundle:Holiday');
$holidays = $holiday_repo->findBy(array('staff' => $staff_entity));
$result = array();
if(!empty($holidays)) {
$x = 0;
foreach ($holidays as $row) {
$result[$x]['from'] = $row->getStartDate()->format('Y-m-d');
$result[$x]['to'] = $row->getEndDate()->format('Y-m-d');
$x ++;
}
}
return new Response(json_encode($result));
Coming back to the ajax, I need to layout my flatpickr config as follows (the dates are just examples):
disable: [
{
from: "2017-04-01",
to: "2017-06-01"
},
{
from: "2017-09-01",
to: "2017-12-01"
}
]
But my dateObj will get overwritten each time, so it only adds the LAST date range in:
var config = {
disable: [
dateObj
]
};
Basically, I need to know how to correctly adapt the $.each loop in order to get a result like the first example above, but nothing works. So far I've tried:
dateObj += { from : element['from'], to : element['to'] };
dateObj.i = { from : element['from'], to : element['to'] };
Then making it an array and trying:
dateObj[i] = { from : element['from'], to : element['to'] };
JSON.stringify(dateObj)
But every single one fails. I'm hoping someone can help me with this!
OK, in the end I used the DatePeriod() function and passed all the dates back as a single array, rather than in the from and to blocks. Not exactly the most optimised version of doing it but it works.
foreach ($holidays as $row) {
$start_date = new \DateTime($row->getStartDate()->format('Y-m-d'));
$end_date = new \DateTime($row->getEndDate()->format('Y-m-d'));
$date_range = new \DatePeriod($start_date, new \DateInterval('P1D'), $end_date);
foreach($date_range as $date){
$date_array[] = $date->format('Y-m-d');
}
// Add the end date as this is not included in the date period.
$date_array[] = $row->getEndDate()->format('Y-m-d');
}
$date_array then gets encoded and passed back to the Ajax where it is parsed and added to the config of flatpickr.

Perform "javascript/jQuery-like" functions using PHP

I'm trying to move some processing from client to server side.
I am doing this via AJAX.
In this case t is a URL like this: https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2.
First problem, I need to send a bunch of these URLs through this little function, to just pull out "1081244497" using my example. The following accomplishes this in javascript, but not sure how to make it loop in PHP.
var e = t.match(/id(\d+)/);
if (e) {
podcastid= e[1];
} else {
podcastid = t.match(/\d+/);
}
The next part is trickier. I can pass one of these podcastid at a time into AJAX and get back what I need, like so:
$.ajax({
url: 'https://itunes.apple.com/lookup',
data: {
id: podcastid,
entity: 'podcast'
},
type: 'GET',
dataType: 'jsonp',
timeout: 5000,
success: function(data) {
console.log(data.results);
},
});
What I don't know how to do is accomplish this same thing in PHP, but also using the list of podcastids without passing one at a time (but that might be the only way).
Thoughts on how to get started here?
MAJOR EDIT
Okay...let me clarify what I need now given some of the comments.
I have this in PHP:
$sxml = simplexml_load_file($url);
$jObj = json_decode($json);
$new = new stdClass(); // create a new object
foreach( $sxml->entry as $entry ) {
$t = new stdClass();
$t->id = $entry->id;
$new->entries[] = $t; // create an array of objects
}
$newJsonString = json_encode($new);
var_dump($new);
This gives me:
object(stdClass)#27 (1) {
["entries"]=>
array(2) {
[0]=>
object(stdClass)#31 (1) {
["id"]=>
object(SimpleXMLElement)#32 (1) {
[0]=>
string(64) "https://itunes.apple.com/us/podcast/serial/id917918570?mt=2&uo=2"
}
}
[1]=>
object(stdClass)#30 (1) {
["id"]=>
object(SimpleXMLElement)#34 (1) {
[0]=>
string(77) "https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2"
}
}
}
}
What I need now is to pull out each of the strings (the URLs) and then run them through a function like the following to just end up with this: "917918570,1081244497", which is just a piece of the URL, joined by a commas.
I have this function to get the id number for one at a time, but struggling with how the foreach would work (plus I know there has to be a better way to do this function):
$t="https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2";
$some =(parse_url($t));
$newsome = ($some['path']);
$bomb = explode("/", $newsome);
$newb = ($bomb[4]);
$mrbill = (str_replace("id","",$newb,$i));
print_r($mrbill);
//outputs 1081244497
find match preg_match() and http_build_query() to turn array into query string. And file_get_contents() for the request of the data. and json_decode() to parse the json responce into php array.
in the end it should look like this.
$json_array = json_decode(file_get_contents('https://itunes.apple.com/lookup?'.http_build_query(['id'=>25,'entity'=>'podcast'])));
if(preg_match("/id(\d+)/", $string,$matches)){
$matches[0];
}
You may have to mess with this a little. This should get you on the right track though. If you have problems you can always use print_r() or var_dump() to debug.
As far as the Apple API use , to seperate ids
https://itunes.apple.com/lookup?id=909253,284910350
you will get multiple results that come back into an array and you can use a foreach() loop to parse them out.
EDIT
Here is a full example that gets the artist name from a list of urls
$urls = [
'https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2.',
'https://itunes.apple.com/us/podcast/dan-carlins-hardcore-history/id173001861?mt=2'
];
$podcast_ids = [];
$info = [];
foreach ($urls as $string) {
if (preg_match('/id(\d+)/', $string, $match)) {
$podcast_ids[] = $match[1];
}
}
$json_array = json_decode(file_get_contents('https://itunes.apple.com/lookup?' . http_build_query(['id' => implode(',', $podcast_ids)])));
foreach ($json_array->results as $item) {
$info[] = $item->artistName;
}
print '<pre>';
print_r($info);
print '</pre>';
EDIT 2
To put your object into an array just run it through this
foreach ($sxml->entries as $entry) {
$urls[] = $entry->id[0];
}
When you access and object you use -> when you access an array you use []. Json and xml will parse out in to a combination of both objects and arrays. So you just need to follow the object's path and put the right keys in the right places to unlock that gate.

generating multidimensional object with array

I am generating an object like this:
As you can see education is an array inside an object,
but what I want is for degree_1 and major_1 and their values to be in the same object.
This is how I want it but with education as an array:
One other thing:
When I var_dump it in my php it is just fine with the arrays and everything. But my javascript gets the second image above- object of object when it was just an array..
public function show($id)
{
$tmp = array();
$post = array();
$postInfo = Post::find($id);
$params = DB::select( DB::raw("SELECT param.*, sys_param_values.*,param_value.*,type_post.*,
param.name AS paramName,
doc_param.name AS docParamName
FROM param
LEFT JOIN doc_param ON param.doc_param_id = doc_param.id
LEFT JOIN sys_param_values ON param.id = sys_param_values.param_id
LEFT JOIN param_value ON sys_param_values.value_ref = param_value.id
LEFT JOIN type_post ON sys_param_values.ref_id = type_post.id WHERE type_post.id = ".$id));
$isMultiple = false;
$post['postInfo'] = $postInfo['original'];
foreach($params as $k=>$v) {
$iteration = $v->iteration;
$docParamName = $v->docParamName;
$paramName = $v->paramName;
if($v->value_ref == null) {
$value = $v->value_short;
} else {
$value = $v->value;
}
if($iteration) {
$post[$docParamName][$iteration][$paramName] = $value;
// need to return education as array not as object
// $post[$docParamName][] = array($paramName=>$value) ;
}elseif(!$iteration) {
$post[$docParamName][$paramName] = $value;
}
}
return Response::json($post);
}
Make first element from education to 0, now it is 1, so that's why json_encode is parsing it as an object.
I don't know what you data source looks like, but it looks to me that you're fetching vertical data and them want to display it horizontally. If that is the case your data need to be stored in a way that simply looping is enough, if not some PHP logic will be required.
We can't really help you on that until you show us an example of your table contents.
Cheers

HighCharts, Json Format

So i'm attempting to use highcharts with the pie chart drilldown option.
Working with static data this is working perfectly. However, as I would like to use the Pie chart as a form of reporting, Ideally It needs to run with dynamic data.
The top level data is made up of requests. Each request is made up of subsequent tasks.
This is the php I have which retrieves the tasks and requests.
foreach($getRequests as $key=> $val){
$timeArr = explode(':', $val['duration']);
$decTime = ($timeArr[0]) + ($timeArr[1]/60); // this is purely to convert hh:mm to decimal time
$pieData['name'] = $val['name'];
$pieData['y'] = $decTime;
$pieData['drilldown'] = $key;
$pie[]=$pieData;
// This creates the first level of data which the $pie[] array gives the correct format, so when json_encode is applied, the data is usable
$getTasks = $task->getReportTasks($user, $status, $key, $dateRange, $date);
foreach($getTasks as $taskKey => $taskVal){
$pieTasks['id']=$key;
$pieTasks['name'] = "Tasks";
$timeArrTask = explode(':', $taskVal['duration']);
$decTimeTask = ($timeArrTask[0]) + ($timeArrTask[1]/60);
$pieTasks['data'] = array($taskVal['name'], $decTimeTask);
$pie2[] = $pieTasks;
}
}
However by applying the same logic to tasks and using json_encode, I end up with the following.
[
{"id":25684
,"name":"Tasks"
,"data":["test task1",3]
}
,{"id":25684
,"name":"Tasks"
,"data":["testtask2",14.383333333333]
}
,{"id":25689
,"name":"Tasks"
,"data":["testtask3",1]}
]
But the format I need is for tasks with the same request ID, the "id" field to be contained within the same data field.
Like so
[
{"id":25684
,"name":"Tasks"
,"data":[
["test task1",3]
,["testtask2",14.383333333333]
]
}
,{"id":25689
,"name":"Tasks"
,"data":[
["testtask3",1]
]
}
]
where because testtask2 has the same id, it is contained within the same data field.
I hope this makes sense and any help anyone can provide so I can structure this correctly would be greatly appreciated.
Not tested, but try to replace the last foreach with this code:
$pieTasks['id'] = $key;
$pieTasks['name'] = "Tasks";
$pieTasks['data'] = array();
foreach($getTasks as $taskKey => $taskVal){
$timeArrTask = explode(':', $taskVal['duration']);
$decTimeTask = ($timeArrTask[0]) + ($timeArrTask[1]/60);
$pieTasks['data'][] = array($taskVal['name'], $decTimeTask);
}
$pie2[] = $pieTasks;
Standart JSON parser can't parse double (14.383333333333) .
Try write in double quotes ( "14.383333333333" )

Categories

Resources