php - Recursive function until done value is true and merge each response into a big one -
i have function:
public function syncterritoriessoqlquery($veevatoken, $instanceurl, $tokenurl) { $soqlquery2 = "select id,name,lastmodifieddate territory"; $soqlurl2 = $instanceurl.'/services/data/v28.0/query/?q='.urlencode($soqlquery2); $curl = curl_init($soqlurl2); curl_setopt($curl, curlopt_header, false); curl_setopt($curl, curlopt_returntransfer, true); curl_setopt($curl, curlopt_httpheader, array("authorization: oauth $veevatoken")); $jsonresponse = curl_exec($curl); $status = curl_getinfo($curl, curlinfo_http_code); if ($status !== 200) { $respobj['error'] = "error: call token url $tokenurl failed status $status, response $jsonresponse, curl_error ".curl_error( $curl ).", curl_errno ".curl_errno($curl); return $respobj; } curl_close($curl); $soqlobj2 = json_decode($jsonresponse, true); return $soqlobj2; }
when call got response:
{ "totalsize": 6911, "done": false, "nextrecordsurl": "/services/data/v28.0/query/01g8000002ei8dmaas-2000", "records": [ ... ] }
that means complete set of records have 6911 items on first request first 2000 return since it's paginated. need call same code again , again , again until "done": true
. in every new request need change $soqlurl2
append value return on each call. example:
1st time: $soqlurl2 = $instanceurl.'/services/data/v28.0/query/?q='.urlencode($soqlquery2); 2nd time: $soqlurl2 = $instanceurl."/services/data/v28.0/query/01g8000002ei8dmaas-2000"; 3rd time: $soqlurl2 = $instanceurl."/services/data/v28.0/query/01g8000002ei8dmaas-4000"; ...
that until done
gets true
on response. should merge whole json result each iteration big one, lets said: result 2nd time should merged result first call meaning $soqlobj2
result 3d time should merge previous merge in pseudo-code:
merge($soqlobj2, 1st, 2nd, 3rd, ...)
i have been working on function:
public function performpaginatesoqlquery($veevatoken, $instanceurl, $tokenurl, $nextrecordsurl, &$datatosave = array()) { if ($nextrecordsurl !== null && $nextrecordsurl !== "") { $keeprequesting = true; while($keeprequesting){ $nextrecordsurlsoqlquery = $instanceurl.$nextrecordsurl; $curl = curl_init($nextrecordsurlsoqlquery); curl_setopt($curl, curlopt_header, false); curl_setopt($curl, curlopt_returntransfer, true); curl_setopt($curl, curlopt_httpheader, array("authorization: oauth $veevatoken")); $jsonresponse = curl_exec($curl); $status = curl_getinfo($curl, curlinfo_http_code); if ($status != 200) { $respobj['error'] = "error: call token url $tokenurl failed status $status, response $jsonresponse, curl_error ".curl_error( $curl ).", curl_errno ".curl_errno($curl); return $respobj; } curl_close($curl); $nextrecordsurlobj = json_decode($jsonresponse, true); $datatosave[] = $nextrecordsurlobj; echo "iteration 2", "\n"; echo "url: ", $nextrecordsurl, "\n"; echo "done: "; var_dump($nextrecordsurlobj['done']); echo "\n"; if($nextrecordsurlobj['done'] === true) { $keeprequesting = false; } } return array('url' => $nextrecordsurlobj, 'data' => $datatosave); } }
and call function above syncterritoriessoqlquery()
follow:
$entiresoqlobj2 = $this->performpaginatesoqlquery( $veevatoken, $instanceurl, $tokenurl, $soqlobj2['nextrecordsurl'] );
but not working since getting result:
iteration 0 url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false) iteration 2 url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false) iteration 2 url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false) iteration 2 url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false) iteration 2 url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false)
right output should like:
// 1st url: /services/data/v28.0/query/01g8000002eyb8laas-2000 done: bool(false) // 2st url: /services/data/v28.0/query/01g8000002eyb8laas-4000 done: bool(false) // 3rd url: /services/data/v28.0/query/01g8000002eyb8laas-6000 done: bool(true)
because totalsize
6911, can me fix code? mistake?
note: ask this earlier today not clear me @ i've open new question more info.
you should have $soqlobj2['nextrecordsurl']
inside recursive function , should updated $nextrecordsurl
every time. checking first page , hence getting url second pages.
also, don't understand why have code in performpaginatesoqlquery()
, want iterate on syncterritoriessoqlquery()
until done
, right?
update:
updating syncterritoriessoqlquery()
loop on pages. added comments everywhere made changes. hope helps.
<?php public function syncterritoriessoqlquery($veevatoken, $instanceurl, $tokenurl) { $soqlquery2 = "select id,name,lastmodifieddate territory"; // removed $instanceurl, we'll add inside while loop $instancepath = '/services/data/v28.0/query/?q='.urlencode($soqlquery2); $final_output = array(); // output appended array $done = false; // set variable true, once `done` true while( !$done ) { $soqlurl2 = $instanceurl . $instancepath; $curl = curl_init($soqlurl2); curl_setopt($curl, curlopt_header, false); curl_setopt($curl, curlopt_returntransfer, true); curl_setopt($curl, curlopt_httpheader, array("authorization: oauth $veevatoken")); $jsonresponse = curl_exec($curl); $status = curl_getinfo($curl, curlinfo_http_code); if ($status !== 200) { $respobj['error'] = "error: call token url $tokenurl failed status $status, response $jsonresponse, curl_error ".curl_error( $curl ).", curl_errno ".curl_errno($curl); return $respobj; } curl_close($curl); $soqlobj2 = json_decode($jsonresponse, true); // here, change $instancepath nextrecordsurl $instancepath = $soqlobj2['nextrecordsurl']; // set $done variable $done = $soqlobj2['done']; // appending data obtained $final_output array, can change string if u need. $final_output[] = $soqlobj2; } return $final_output; }
Comments
Post a Comment