Identify if array in object. Php - php

Working against an API for an accounting system and wondering how to handle the return of fiscals years. I want to iterate each fiscal year, which is no problem if there are multiple fiscal years. However if there is only one fiscal year the returned object/array is slightly different, how should I handle this, ie how to identify the subarray?
//Example data if multiple fiscal years
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => Array
(
[0] => stdClass Object
(
[Id] => 257c2e5e-2b5b-4eea-9405-775caef357d4
[StartingDate] => 2015-01-01T00:00:00Z
[EndingDate] => 2016-01-01T00:00:00Z
[IsLocked] =>
)
[1] => stdClass Object
(
[Id] => 376ce224-77ce-43cd-b3c4-a3703b1fc8bf
[StartingDate] => 2018-01-01T00:00:00Z
[EndingDate] => 2019-01-01T00:00:00Z
[IsLocked] =>
)
)
)
)
//Example data if one fiscal year
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => stdClass Object
(
[Id] => f2712737-9c63-4c4b-b107-1b841985cffb
[StartingDate] => 2019-01-01T00:00:00Z
[EndingDate] => 2020-01-01T00:00:00Z
[IsLocked] =>
)
)
)
//Current php code for multiple fiscal years
$Result = $Service->GetFiscalYears();
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
$YE = date('Y-m-d',(strtotime ( '-1 day' , strtotime ( $object -> EndingDate) ) ));
echo $YE
}
//EDIT With solution (identification of subarray with is_array)
$Result = $Service->GetFiscalYears();
if(is_array($Result->GetFiscalYearsResult->FiscalYear)){
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
CODE
}
} else { //if only one fiscal year
CODE
}

Related

PHP - Nesting an array from API obj response

I have a large object API response, I'm trying to load the data into a nested array so I can work with it later. Here is a sample of the object I get back from the API.
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Approved
[expr1] => 30
)
)
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Attempted
[expr1] => 11
)
)
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Contact Declined
[expr1] => 13
)
As I said, the goal is to have a nested array that would look similar to this:
Array
(
[January] => Array
(
[0] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
[1] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
)
)
Here is my Code:
$query =
"SELECT CALENDAR_MONTH(closedDate), recordType.name,status,count(id)
FROM case
WHERE owner.name ='" . $SFName . "' AND recordType.name IN('DT Case','Performance Reviews') AND closedDate = LAST_N_MONTHS:6
GROUP BY CALENDAR_MONTH(closedDate),recordType.Name,status ORDER BY CALENDAR_MONTH(closedDate)";
$counter = 0;
$mprArray = array(); //instantiate our Array
$response = $mySforceConnection->query($query);
$queryResult = new QueryResult($response);
foreach ($queryResult->records as $case) {
//turn our query Result into an Obj
$sObject = new SObject($case);
$recordType = $sObject->Name;
$status = $sObject->Status;
$month = $sObject->expr0;
$count = $sObject->expr1;
//this is a filter to weed out a portion of the cases.
if ($recordType == "Performance Reviews") {
foreach($sObject as $record) {
//change the month's number to a month's name
$dateObj = DateTime::createFromFormat('!m', $month);
$monthName = $dateObj->format('F');
// Create the nested array, it should end up looking like $mprArray[January].
// This is a dynamic name since we're creating an array for each status that exists in performance Reviews
$mprArray[$monthName] = array($monthName,$status,$count);
// Trying to append our nested array onto the $mprArray so we can work with it later.
array_push($mprArray,$mprArray[$monthName]);
}
}
//increase counter
$counter = $counter++;
}
} catch (Exception $e) {
print_r($mySforceConnection->getLastRequest());
echo $e->faultstring;
}
Instead of a nested array, only the first item in the array is named 'January', the remainder are named based on a counter, until we get to the next month of 'february', here's what it looks like.
Array
(
[January] => Array
(
[0] => January
[1] => Closed - Contact Declined
[2] => 15
)
[0] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
)
because array_push only inserts the data to the next index;
I feel you should use $mprArray[$monthName][] = array($monthName,$status,$count); only; and no need for the array_push after that

Sort array of objects by property value inside a function [duplicate]

This question already has answers here:
Sort array of objects by date field
(6 answers)
Closed 10 months ago.
I have a function which returns array of objects. This is my function
public function myFunction () {
$args = [
'post_type' => 'post',
];
$data = \WordPress\Query::get_posts($args);
$now = time();
foreach ($data as $key => $datas) {
$eventTime = $datas->endtime;
$eventTimeStr = strtotime($eventTime);
if ($eventTimeStr < $now) {
unset($data[$key]);
}
}
return $data;
}
This returns array of objects like so:
Array
(
[0] => WP_Post Object
(
[ID] => 14
[metadata] => Array
(
[post_title] => Event number 3
[starttime] => 24.11.2019
[endtime] => 25.11.2019
)
)
[1] => WP_Post Object
(
[ID] => 13
[metadata] => Array
(
[post_title] => Event number 1
[starttime] => 19.1.2017
[endtime] => 20.1.2017
)
)
[2] => WP_Post Object
(
[ID] => 10
[metadata] => Array
(
[post_title] => Event number 2
[starttime] => 19.1.2018
[endtime] => 20.1.2018
)
)
)
How can I sort the array by property "endtime" so that "Event number 1" is the first one on the list and "Event number 2" second etc. ?
I tried using usort-function inside myFunction() but didn't manage to succeed. Should I create another function outside of myFunction() and access the $data-variable from there? If so, how?
In myFunction() I have formatted the date to Unix Timestamp. I probably should use it?
as always, sorting algorithm uses a compare function behind the scene to sort the whole array by comparing two element, for sorting complex stuff like this, one should write compare function and define the logic there for ordering
function compare($a, $b)
{
return strtotime($a->metadata['endtime']) < strtotime($b->metadata['endtime']);
}
usort($yourarray, 'compare');

how to create an array using days key in php

I have an array of object with dynamic date and days. I want to sort array with days keys in php in the order of the days.
Given input like this:
array(
[17-08-2017] => stdClass Object
(
[days] => Thu
)
[21-08-2017] => stdClass Object
(
[days] => Mon
)
[22-08-2017] => stdClass Object
(
[days] => Tue
)
[23-08-2017] => stdClass Object
(
[days] => Wed
)
);
I want result like this:
array(
[21-08-2017] => stdClass Object
(
[days] => Mon
)
[22-08-2017] => stdClass Object
(
[days] => Tue
)
[23-08-2017] => stdClass Object
(
[days] => Wed
)
[17-08-2017] => stdClass Object
(
[days] => Thu
)
);
I know this is the stupid idea but how can I do this. Please help me.
convert your key to strtotime($key)
then apply ksort($dates) but it will eliminate the duplicate key.
Probably the same question
You need a custom sorting function.
$t = new DateTime('this week'); //Using this to hopefully adapt for locale wrt which day is first
$daysOrder = [];
for ($i=0;$i<7;$i++) {
$daysOrder [] = $t->format("D");
$t->add(new DateInterval("P1D"));
}
$daysOrder = array_flip($daysOrder); //Days as keys, order as values
Then you can sort:
$array = uasort($array, function ($x,$y) use ($daysOrder) {
//May need to do some checks here to determine if $x and $y are valid days
return $daysOrder[$x] <=> $daysOrder[$y]; //PHP 7 syntax
});
The PHP 5.x syntax would be something like:
return $daysOrder[$x] < $daysOrder[$y]?-1:($daysOrder[$x]==$daysOrder[$y]?0:1);

Check Array for Object with Same Key

I'm creating an array of objects (or trying to) that looks like this:
Array
(
[1] => stdClass Object
(
[date] => 2016-09-28
)
[5] => stdClass Object
(
[date] => 2016-09-28
)
[2] => stdClass Object
(
[date] => 2016-09-29
)
[0] => stdClass Object
(
[date] => 2016-09-30
)
[4] => stdClass Object
(
[date] => 2016-09-30
)
[3] => stdClass Object
(
[date] => 2016-09-30
)
)
The trouble that I'm having is that I need can't work out how to check if an object with date->$date already exists.
I need an array of 'days' that I can then go on to add workshops to the corresponding days, not to a new object each time.
Can anyone make a suggestion?
EDIT
To put this in context, I'm iterating through a bunch of wordpress posts (of type 'workshop' in this case) which all have a piece of date meta. On my way through the loop I want to
Get the date(day)
Check if that date exists in the array
If not, add the date to the array
Then add the workshop object to that date array
What I should therefor end up with is an array containing three or four unique dates, each with an array of workshop objects.
Array(
Date 1(
Workshop(
Title, etc
),
Workshop()
)
Date 2(
Workshop(
Title, etc
)
Workshop()
)
)
My apologies, I'm sure my structure is off - this is a little advanced for me. Thanks for looking.
What you need is something like this. You can have a function to group your result.
function groupWorkShopsByDate($first_array){
$result_arr = array();
foreach( $first_array as $workShop ){
$result_arr[ $workShop->date ][] = $workShop;
}
return $result_arr;
}
Hope this helps!

Code works if request returns multiple objects, error if request returns only one

I'm trying to fetch candidates depending on what industry they work in. My request returns this data when I send a request for candidates in an industry where there's only one (it's in JSON):
stdClass Object ([Candidates] => stdClass Object ([row] =>
stdClass Object ([no] => 1 [FL] => Array (
[0] => stdClass Object ( [content] => 213748000001275022 [val] => RESUMEID )
[1] => stdClass Object ( [content] => John (3) [val] => Modified by )
[2] => stdClass Object ( [content] => 11 Aug-2015 [val] => Modified time )
[3] => stdClass Object ( [content] => 3308 [val] => Candidate ID )
[4] => stdClass Object ( [content] => John (3) [val] => Recruiter )
[5] => stdClass Object ( [content] => Creative arts [val] => Branche / Industry )
[6] => stdClass Object ( [content] => Ja / Yes [val] => Accept af optagelse i Kandidatbank / Accept my registration in
candidatedatabase )))))
I use this code:
$rowArray = $data->response->result->Candidates->row;
for ($i = 0; $i < count($rowArray); $i++) {
$FL = $data->response->result->Candidates->row[$i]->FL;
}
The exact error I'm getting is that I "cannot use object of type stdClass as array", but why this error now? I works totally fine on other requests. To explain things a little further with some code, here's what $FL is used for:
if (array_key_exists(4, $FL) === true && $FL[4]->val === 'Branche / Industry') {
$industry = $FL[4]->content;
} else if (array_key_exists(5, $FL) === true && $FL[5]->val === 'Branche / Industry') {
$industry = $FL[5]->content;
} else {
$industry = $notSpecified;
}
It sets the variables of the candidate in my PHP code so I can present it in a table.
You could proceed as follows -
1. First check if it is an array then do as usual
2. Else create an array and push it then do as usual
$rowArray = $data->response->result->Candidates->row;
if(!is_array($rowArray))
{
$rowArray=array($data->response->result->Candidates->row);
//so that $rowArray is now an array and count gives 1
}
This should work:
$FL = $data->response->result->Candidates->row->FL[$i];
It's telling you "cannot use object of type stdClass as array" because you are trying to do just that; access an object as if it were an array. Maybe your server is returning a different data structure based on the specific request you send it.

Categories