JSON Response Multidimensional Array - php

Hello i got a JSON response that looks like the one below. I want to count the posts that are younger then 24 hours and also check for unique user urls:
{
"meta":{
"network":"all",
"query_type":"realtime"
},
"posts":[
{
"network":"facebook",
"posted":"2014-08-16 08:31:31 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Terance Podolski",
"url":"someURL",
"image":"someURL"
}
},
{
"network":"facebook",
"posted":"2014-08-16 08:30:44 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Łukasz Podolski",
"url":"someURL",
"image":"someURL"
}
},
{
"network":"facebook",
"posted":"2014-08-16 08:25:39 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Marcin Podolski",
"url":"someURL",
"image":"someURL"
}
}
]
}
Thanks in advance.
With the help of #Elias Van Ootegem i got my problem solved. The code looks like that:
// Json Reponse decodieren
$jsonArray = json_decode($jsonData);
function getMentionsFromLast24H($myArray){
// set variable exactly one day ago
$since = new DateTime('-1 day');
// array where to store timestamps in
$recent = array();
foreach ( $myArray -> posts as $post ) {
try {
$post -> posted = new DateTime (substr ( $post->posted,0,19 ) );//create DateTime instance
if ( $post -> posted >= $since )
$recent[] = $post;//add to array
} catch ( Exception $e ) {
echo $e -> getMessage();
exit(1);
}
}
return $recent;
}
$mentions24h = count(getMentionsFromLast24H($jsonArray));
print_r($mentions24h);

It's pretty simple, really: decode the json data, compare the posted values with time - 24 hours, if the value is great than time-24 hours, add it to an array. That's it, you'll end up with an array containing all posts that were added in the last 24 hours:
$data = json_decode($jsonData);//creates object
$since = new DateTime('yesterday');
$recent = array();//this is the array we'll be constructing
foreach ($data->posts as $post)
{
$post->posted = new DateTime($post->posted);//create DateTime instance
if ($post->posted > $since)
$recent[] = $post;//add to array
}
var_dump($recent);//this is the array you're after
That really is all there is to it.

Related

DateTime Failed to Parse Time String

I am passing 2 date and time strings per item in the array which is brought over from JSON.
These dates are successfully stored in the array but the DateTime function doesn't like them for some reason.
I have tried using different formats, just the date, just the time but nothing worked.
I have provided the JSON file and my PHP Tests file I am using.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$revokes = jsonDecode(file_get_contents("../revokes.json"), true);
$certificates = $revokes['certificates'];
// Prints the revokes array
// print_r($revokes);
$dates = array();
foreach ($certificates as $certificate_key => $certificate) {
$signed = $certificate['signed'];
$revoked = $certificate['revoked'];
$dates[] = array(
"signed" => $signed,
"revoked" => $revoked
);
}
// Prints the dates
// print_r($dates);
$intervals = array();
foreach ($dates as $key) {
$newTimeAdd = new DateTime($key["signed"]);
$newTimeRead = new DateTime($key["revoked"]);
$interval = $newTimeAdd->diff($newTimeRead);
// returns 0 on all elements of the interval array.
// var_dump($interval);
$intervals[] = $interval->days;//get days
}
if(!empty($intervals)) {
$average = average($intervals);
}
// Prints nothing
// print_r($intervals);
function average($arr) {
return array_sum($arr)/count($arr);
}
function jsonDecode($json, $assoc = false)
{
$ret = json_decode($json, $assoc);
if ($error = json_last_error())
{
$errorReference = [
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded.',
JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON.',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded.',
JSON_ERROR_SYNTAX => 'Syntax error.',
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded.',
JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded.',
JSON_ERROR_INF_OR_NAN => 'One or more NAN or INF values in the value to be encoded.',
JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded was given.',
];
$errStr = isset($errorReference[$error]) ? $errorReference[$error] : "Unknown error ($error)";
throw new \Exception("JSON decode error ($error): $errStr");
}
return $ret;
}
?>
{
"lifeExp": "2 Days",
"certificates": [
{
"name": "CCS Group Pte Ltd",
"signed": "22/05/2020 10:31:00",
"revoked": "23/05/2020 5:40:00",
"files": {
"p12": "certificates/:id/certificate.p12",
"pem": "certificates/:id/certificate.pem",
"key": "certificates/:id/certificate.key",
"password": "certificates/:id/certificate.password"
}
},
{
"name": "Hoola Inc",
"signed": "16/05/2020 12:40:00",
"revoked": "19/05/2020 04:00:00",
"files": {
"p12": "certificates/:id/certificate.p12",
"pem": "certificates/:id/certificate.pem",
"key": "certificates/:id/certificate.key",
"password": "certificates/:id/certificate.password"
}
}
]
}
Your date formats are in European format (DD/MM/YYYY) which means you'll need to use DateTime::createFromFormat() to specify the correct format to have DateTime handle it correctly. This is due to PHP assuming US date format when it sees the NN/NN/NNNN date format.
<?php
$json = json_decode('{
"lifeExp": "2 Days",
"certificates": [
{
"name": "CCS Group Pte Ltd",
"signed": "22/05/2020 10:31:00",
"revoked": "23/05/2020 5:40:00",
"files": {
"p12": "certificates/:id/certificate.p12",
"pem": "certificates/:id/certificate.pem",
"key": "certificates/:id/certificate.key",
"password": "certificates/:id/certificate.password"
}
},
{
"name": "Hoola Inc",
"signed": "16/05/2020 12:40:00",
"revoked": "19/05/2020 04:00:00",
"files": {
"p12": "certificates/:id/certificate.p12",
"pem": "certificates/:id/certificate.pem",
"key": "certificates/:id/certificate.key",
"password": "certificates/:id/certificate.password"
}
}
]
}', true);
$signed = $json['certificates'][1]['signed'];
$revoked = $json['certificates'][1]['revoked'];
$newTimeAdd = DateTime::createFromFormat('d/m/Y H:i:s', $signed);
$newTimeRead = DateTime::createFromFormat('d/m/Y H:i:s', $revoked);
$interval = $newTimeAdd->diff($newTimeRead);
echo $interval->days;
Output
2
Demo

FOREACH with a DATE COMPARE condition (PHP)

I have a JSON source and I am trying to loop trough it and show some results (up to 9 results) which is not a problem
The problem is that I want to show only the results that are matching a certain date, where the date might be exact or between 2 dates.
For example I want to show only the events where let say the date 2019-11-17 is within timeFrom timeTo of the event or timeFrom or timeTo is equal to it. In that example it will be event 1 and 3
This is the source sample
{
"title":"event 1",
"timeFrom":"2019-11-16 19:00:00",
"timeTo":"2019-11-18 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
},
{
"title":"event 2",
"timeFrom":"2019-11-20 19:00:00",
"timeTo":"2019-11-20 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
},
{
"title":"event 3",
"timeFrom":"2019-11-17 19:00:00",
"timeTo":"2019-11-17 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
And this is the foreach I have at the moment
foreach(array_slice($arr, 0, 9) as $data) {
//then I will show the result
}
So, I can't figure out how to make that condition within the foreach.
This function iterates through the events data, looking for events whose from and to dates surround the given date:
function find_events($events, $date) {
$date = new DateTime($date);
foreach ($events as $event) {
$from = (new DateTime($event['timeFrom']))->setTime(0,0,0);
$to = (new DateTime($event['timeTo']))->setTime(0,0,0);
if ($date >= $from && $date <= $to) {
echo "{$event['title']} ({$event['listText']}) from {$event['timeFrom']} to {$event['timeTo']}\n";
}
}
}
$events = json_decode($json, true);
find_events($events, '2019-11-17');
Output:
event 1 (text of the event) from 2019-11-16 19:00:00 to 2019-11-18 22:00:00
event 3 (text of the event) from 2019-11-17 19:00:00 to 2019-11-17 22:00:00
Demo on 3v4l.org
Try this code:
$date = "2019-11-17";
$events = json_decode($json_output, true);
foreach ($events as $event)
{
if (($date > $event['timeFrom'] && $date < $event['timeTo']) || in_array($date, array($event['timeFrom'], $event['timeTo'])))
{
$filtered_events[] = $event;
}
}
$sliced_events = array_slice($filtered_events, 0, 9);
print_r($sliced_events);

PHP how to add a list items inside another list items

I have a list of financial launch. Each launch may or may not have multiple payments. So for every financial launch I look for a list of payments. I would like this list to be within its corresponding financial launch.
My complete function:
public function customerInvoice()
{
$_customer = filtra_int($this->input->post('cliente_id'));
$this->redireciona_id_nula($_customer, $this->url . '/ficha');
$_view = [];
$this->load->helper(['filter', 'string', 'currency', 'validate', 'phone']);
$_view['glyph'] = 'user';
$_view['enterprise'] = $this->enterprise;
$_view['buttons'] = $this->_getFormButtons($_customer, $this->url . '/ficha');
$this->load->model('lancamento_model', 'lancamentoModel');
$_view['releases'] = $this->lancamentoModel->getCustomerRelease($_customer);
foreach ($_view['releases'] as $i => $value) {
// $_view['releases']['order'][$i] = $this->lancamentoModel->getCustomerOrder($value->id);
$value['order'] = $this->lancamentoModel->getCustomerOrder($value->id);
}
$this->addBreadcrumb('Lançamentos', base_url() . 'lancamentos');
$this->addBreadcrumb('Ficha', base_url() . 'lancamentos/ficha');
$this->addBreadcrumb('Exibir');
$this->extras['css'][] = $this->load->view('lancamentos/consulta/ficha_cliente/form/css', null, true);
$this->extras['scripts'][] = $this->load->view('lancamentos/consulta/ficha_cliente/form/js', $_view, true);
// $pagina = $this->getHtmlPagina('Ficha cliente', $_view);
// $this->load->view('lancamentos/consulta/ficha_cliente/view/view', $pagina);
$this->output->set_content_type('application/json');
$this->output->set_output(json_encode($_view));
}
json result:
{
"release":{
"0":{
"id":"380",
"data_vcto":"2016-01-15",
"data_emissao":"2016-01-15",
"documento":"292\/1",
"vlr":"67.00",
"vlr_divida":"0.00"
},
"order":[
[
{
"id":"142206",
"data_vcto":"2016-01-15 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"67.00",
"tipo_pagamento_nome":"Dinheiro"
},
{
"id":"213",
"data_vcto":"2016-01-13 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"22.00",
"tipo_pagamento_nome":"Dinheiro"
}
]
]
}
}
I would like something like that
{
"release":{
"0":{
"id":"380",
"data_vcto":"2016-01-15",
"data_emissao":"2016-01-15",
"documento":"292\/1",
"vlr":"67.00",
"vlr_divida":"0.00",
"order":[
{
"id":"142206",
"data_vcto":"2016-01-15 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"67.00",
"tipo_pagamento_nome":"Dinheiro"
},
{
"id":"213",
"data_vcto":"2016-01-13 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"22.00",
"tipo_pagamento_nome":"Dinheiro"
}
]
}
}
}
it is possible ? And what do I have to do in the foreach?
Update: I did as #Yulio Aleman Jimenez suggested...but after that the error appeared
Fatal error: Cannot use object of type stdClass as array in C:\xampp\htdocs\beauty\application\controllers\Lancamentos.php on line 829
Message: Cannot use object of type stdClass as array
Error Print
I think you must change your code like this:
$_releases = $this->lancamentoModel->getCustomerRelease($_customer);
foreach ($_releases as $i => $value) {
// try with this changes
$value = $this->lancamentoModel->getCustomerOrder($value->id);
$_releases[$i] = (object)array_merge((array)$_releases[$i], array('order' => $value));
}
The thing is to store the array of orders in the order of each release.
Update
You have working with objects, it's the reazon you have to cast to array, add new values in order and then cast to object.

php split start time and end time with merge new array

First all; I'm sorry if my question is not irrelevant. I'm new on array's with PHP.
I have an array;
[
{
"order_id":"7",
"order_start_time":"08:00:00",
"order_end_time":"11:00:00",
"order_date":"29\/03\/2018"
},
{
"order_id":"8",
"order_start_time":"10:00:00",
"order_end_time":"01:00:00",
"order_date":"29\/03\/2018"
}
]
I want to split time ranges from start to end by hours. Desired output;
[
{
"hour_selected":"08:00:00"
},
{
"hour_selected":"09:00:00"
},
{
"hour_selected":"10:00:00"
},
{
"hour_selected":"11:00:00"
},
{
"hour_selected":"12:00:00"
},
{
"hour_selected":"13:00:00"
}
]
But i'm lost how can i do this with time hour ranges.
Any help greatly appricated.
PS: I'm creating array from mysql datetime field.
the simpliest solution is to use unix timestamp:
<?php
$timeFrom = '08:00:00';
$timeTo = '15:00:00';
function rangeBetweenHours($from, $to)
{
$timeFrom = strtotime('today ' . $from);
$timeTo = strtotime('today ' . $to);
$out = [];
foreach (range($timeFrom, $timeTo, 60 * 60) as $timestamp) { // 60 * 60 is a hour
$out[] = date('H:i:s', $timestamp);
}
return $out;
}
var_dump(rangeBetweenHours($timeFrom, $timeTo));
Here you can see working example:
http://sandbox.onlinephpfunctions.com/code/8fec4a2f6b067dc66705732b3c43301cc8722d3f
[
{
"order_id":"7",
"order_start_time":"08:00:00",
"order_end_time":"11:00:00",
"order_date":"29/03/2018"
},
{
"order_id":"8",
"order_start_time":"10:00:00",
"order_end_time":"01:00:00",
"order_date":"29/03/2018"
}
]
Apply for each on this and get order_start_time & order_end_time in an array then sort as per values associating as par increasing order of time.

Accessing nested object within array in PHP (Laravel)

I am struggling for quite a while on how to access nested object.
$dt = Carbon::parse($year.'-'.$month.'-1');
$godziny = array();
$gs = $lekarz->od;
$gz = $lekarz->do;
$ile = $gz-$gs;
for($j=0; $j<4*$ile; $j++){
if($j%4==0){
$wm = "00";
}
else{
$wm = ($j%4)*15;
}
if($gs+floor(($j/4)) < 10){
$dz="0".$dz = $gs+floor(($j/4));
} else{
$dz = $gs+floor(($j/4));
}
$godziny[$j]['godzina'] = $dz;
$godziny[$j]['minuty'] = $wm;
if(!empty(Kolejka::where('data', 'LIKE', $year.'-'.$month.'-'.$day.' '.$dz.':'.$wm.'%')->get())){
$godziny[$j]['odbyta'] = Kolejka::where('data', 'LIKE', $year.'-'.$month.'-'.$day.' '.$dz.':'.$wm.'%')->get();
dd(get_object_vars($godziny[$j]['odbyta']));
// $godziny[$j]['pacjent'] = Pacjent::where('id', '=', $godziny[$j]['odbyta']->{0}->pacjent_id);
} else {
$godziny[$j]['odbyta'] = '';
}
}
Everything works except for the last part. It seems like whatever way i try to access this data ( by using $godziny[$j]['odbyta']['pacjent_id'] or by $godziny[$j]['odbyta']->pacjent_id) it just won't work. I really don't know what to do.
That's my [$j]['odbyta] data:
{
"id": 1,
"pacjent_id": "13",
"lekarz_id": "1",
"data": "2017-04-05 10:15:00",
"odbyta": "0",
"created_at": "2017-04-05 16:14:42",
"updated_at": "2017-04-05 16:14:42"
}
That is code that generates data with a pattern:
$j's max number is 36
$godziny[0]['godzina'] = $dz //That's for setting hour to array
$godziny[0]['godzina'] = $wm; //That's for assigning minutes
$godziny[0]['odbyta'] <- that's of value of object that i listed above
How can i possibly access data from this object?
so $godziny[0]['odbyta'] can give me an value of object it contains?
Can't you just use Model->where...first()? and than access it as object:
$godziny[$j]['odbyta'] = Kolejka::where('data', 'LIKE', $year.'-'.$month.'-'.$day.' '.$dz.':'.$wm.'%')->first();
$godziny[$j]['pacjent'] = Pacjent::where('id', '=', $godziny[$j]['odbyta']->pacjent_id);

Categories