I have a cURL call to this services/data/v28.0/query/?q=SELECT Id,Name,LastModifiedDate FROM Territory and the response looks like:
{
"totalSize": 6911,
"done": false,
"nextRecordsUrl": "/services/data/v28.0/query/01g8000002eI8dMAAS-2000",
"records": [ ... ]
}
That means complete set of records will have 6911 items but on first request just the first 2000 are return, now if I change a bit the cURL call into this /services/data/v28.0/query/01g8000002eI8dMAAS-2000 I will get the next 2000 items for the first 6911 and so on.
I should call the cURL recursive until done = true or nextRecordsUrl will be NULL or doesn't exists anymore on the response, how? I need some advice or pseudo-code that illustrate me how to achieve this since I am a bit stucked.
This shows the complete set of recursive calls I should perform (this could be dynamic so hard code won't work):
call:
/services/data/v28.0/query/?q=SELECT Id,Name,LastModifiedDate FROM Territory
response:
{
"totalSize": 6911,
"done": false,
"nextRecordsUrl": "/services/data/v28.0/query/01g8000002eI8dMAAS-2000",
"records": [ ... ]
}
call:
/services/data/v28.0/query/01g8000002eI8dMAAS-2000
response:
{
"totalSize": 6911,
"done": false,
"nextRecordsUrl": "/services/data/v28.0/query/01g8000002eI8dMAAS-4000",
"records": [ ... ]
}
call:
/services/data/v28.0/query/01g8000002eI8dMAAS-4000
response:
{
"totalSize": 6911,
"done": false,
"nextRecordsUrl": "/services/data/v28.0/query/01g8000002eI8dMAAS-6000",
"records": [ ... ]
}
call:
/services/data/v28.0/query/01g8000002eI8dMAAS-6000
response:
{
"totalSize": 6911,
"done": true,
"records": [ ... ]
}
UPDATE
I have figured out, more or less, how to achieve this but now the my problem turns in how to merge recursive the values from each response. See code below:
$soqlQuery2 = "SELECT Id,Name,LastModifiedDate FROM 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);
curl_close($curl);
$soqlObj2 = json_decode($jsonResponse, true);
$this->performPaginateSOQLQuery($veevaToken, $instanceUrl, $tokenUrl, $soqlObj2['nextRecordsUrl']);
Above in $soqlObj2['done'] and $soqlObj2['nextRecordsUrl'] I will have the values I need for the second and recursive calls. So, I built this function:
public function performPaginateSOQLQuery($veevaToken, $instanceUrl, $tokenUrl, $nextRecordsUrl)
{
if (isset($nextRecordsUrl) && $nextRecordsUrl !== null && $nextRecordsUrl !== "") {
$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 to token URL $tokenUrl failed with status $status, response $jsonResponse, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$nextRecordsUrlObj = json_decode($jsonResponse, true);
while ($nextRecordsUrlObj['done'] !== true) {
$this->performPaginateSOQLQuery($veevaToken, $instanceUrl ,$tokenUrl, $nextRecordsUrlObj['nextRecordsUrl']);
}
return $nextRecordsUrlObj;
}
}
But I need to merge the whole $soqlObj2 with $nextRecordsUrlObj from each iteration on performPaginateSOQLQuery() call, how? Any help?
UPDATE 2: Losing values on 1st iteration
I've updated my code to this:
public function performPaginateSOQLQuery(
$veevaToken,
$instanceUrl,
$tokenUrl,
&$nextRecordsUrl,
&$dataToSave = array()
) {
if (isset($nextRecordsUrl) && $nextRecordsUrl !== null && $nextRecordsUrl !== "") {
$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 to token URL $tokenUrl failed with status $status, response $jsonResponse, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$nextRecordsUrlObj = json_decode($jsonResponse, true);
echo $nextRecordsUrlObj['nextRecordsUrl'] . "\n";
print_r($nextRecordsUrlObj);
$dataToSave[] = $nextRecordsUrlObj;
$i = 0;
while ($nextRecordsUrlObj['done'] !== true) {
echo "time ".$i;
$i++;
$this->performPaginateSOQLQuery(
$veevaToken,
$instanceUrl,
$tokenUrl,
$nextRecordsUrlObj['nextRecordsUrl'],
$dataToSave
);
}
return array('url' => $nextRecordsUrlObj, 'data' => $dataToSave);
}
}
But on iteration time 1 I am getting this error:
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Undefined index: nextRecordsUrl
Why is that?
You can use a while loop with a boolean variable.
Once the response you get is the last one (done property is true) change the value of that boolean variable and the loop should stop.
<?php
//Assuming $response contains the response you're getting
//and that it's JSON-encoded.
$keepRequesting = true;
while($keepRequesting){
//Your curl code over here
// ...
$response = json_decode($response);
if($response->done == true) {
$keepRequesting = false;
}
}
Regarding your update:
While I don't think you should use recursive methods for this problem,
just add the data you want to "save" as a reference to the function and use array_merge. Something like that:
public function performPaginateSOQLQuery($veevaToken, $instanceUrl, $tokenUrl, $nextRecordsUrl, &$dataToSave = array()) { //1 new parameters.
//More code here...
$nextRecordsUrlObj = json_decode($jsonResponse, true);
$dataToSave[] = $nextRecordsUrlObj;
while ($nextRecordsUrlObj['done'] !== true) {
$this->performPaginateSOQLQuery($veevaToken, $instanceUrl ,$tokenUrl, $nextRecordsUrlObj['nextRecordsUrl'], $dataToSave);
}
return array('url' => $nextRecordsUrlObj, 'data' => $dataToSave);
The problem is that you should return it, otherwise it will get lost.
You'll have to change the function a bit so it would return the URL and the data you want.
Maybe this post would help you:
php recursion global variable?
Related
I have returned data using GraphQL / curl that looks like this:
{
"data" : {
"publisher" : {
"contracts" : {
"totalCount" : 11,
"count" : 1,
"resultList" : [
I want to get the resultList array and keep getting an error 'Warning: Attempt to read property "data" on string' when trying to do $result->data to move into the first object. What am I doing wrong?
My variable from the curl request is $result.
Update: I HAVE TRIED DECODING AND THE RETURNED DATA IS OF TYPE INT? How?
function getData($data_String){
$endpoint = "https://programs.api.cj.com/query";
$authToken = "pass";
$qry = '{"query":"{ publisher { contracts(publisherId: \"xxxxxxx\", limit: 1, filters: {advertiserId: \"'.$advertiser_id.'\"}) { totalCount count resultList { startTime endTime status advertiserId programTerms { id name specialTerms { name body } isDefault actionTerms { id actionTracker { id name description type } lockingMethod { type durationInDays } performanceIncentives { threshold { type value } reward { type commissionType value } currency } commissions { rank situation { id name } itemList { id name } promotionalProperties { id name } rate { type value currency } } } } } } } }","variables":null}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer '.$authToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$data = json_decode($result);
return $data;
}
First, be sure to check if the result is a valid json.
Then use json_decode to get an object
$result = json_decode($result);
if (is_object($result)) {
if (!empty($result->data->publisher->contracts->resultList)) {
$resultList = $result->data->publisher->contracts->resultList;
}
} else {
// Log or something
error_log("json decode return: " . print_r($result, true))
}
I've created two method in my controller in Laravel to fetch data from another website using PHP CURL and pass to view.
I will used httpData method for initial ID and URL and getHttpCode method to get HTTP_code to find any errors will happen when I fetch data from another website But I don't much understand about this below code performance and how can I testing In PHPstrom to make sure with performance
Here is my function
private function httpData($url =null, $id = null)
{
if($id){
$url = 'http://assignment.gae.golgek.mobi/api/v1/items/'.$id;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLINFO_PRETRANSFER_TIME, 30);
curl_setopt($ch, CURLINFO_HTTP_CODE, true);
curl_setopt($ch, CURLOPT_PRIVATE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if (!$executed = curl_exec($ch)) {
$res = $executed;
$data = false;
curl_close($ch);
} else {
if ($this->http_code = $this->getHttpCode(curl_getinfo($ch))) {
$res = $this->http_code;
$data = $executed;
} else {
$res = false;
}
}
return ['s_respond' => $res, 'data' => $executed];
}
private function getHttpCode($http)
{
if (is_array($http)) {
if (!empty($http['http_code'] || $http['http_code'] != 0)) {
return $http['http_code'];
} else {
return false;
}
} else {
return false;
}
}
And I will call this method as below
public function sendData()
{
$url = 'website/api/v1/products';
$data = $this->httpData($url);
return view('products.list', ['data'=>$data]);
}
Thanks for help
I suggest you to addopt the 'early return pattern'.
I did a rewrite in you getHttpCode, it seems more clear to me:
private function getHttpCode($http)
{
if ( !is_array($http)
|| empty($http['http_code'])
|| $http['http_code'] === 0)
{
return false;
}
return $http['http_code'];
}
I am trying to let a Telegram bot send a message to a group without the need of a message by a user to trigger it. To be more specific i am trying to set up a birthday reminder where the bot querys a database, compares entries to the current date and broadcaststs a "Happy birthday" message in the group. As said i would like to do it via a cronjob that opens up the PHP script everyday and lets the bot broadcast it.
My problem is I checked all of Telegrams documentations and demo codes (https://core.telegram.org/bots/samples) but all of it are based on a User triggering the bot by sending a message.
My question is, if anyone was already able to implement a similar functionality and could aid me in extending my code? What might be worth mentioning is that the Bot is already integrated into the Group Chat and i have the chat id that would be needed for the bot to target the chat.
My code is as follows (i have to admit i copied it over from the demo examples):
<?php
define('BOT_TOKEN', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');
function apiRequestWebhook($method, $parameters) {
if (!is_string($method)) {
error_log("Method name must be a string\n");
return false;
}
if (!$parameters) {
$parameters = array();
} else if (!is_array($parameters)) {
error_log("Parameters must be an array\n");
return false;
}
$parameters["method"] = $method;
header("Content-Type: application/json");
echo json_encode($parameters);
return true;
}
function exec_curl_request($handle) {
$response = curl_exec($handle);
if ($response === false) {
$errno = curl_errno($handle);
$error = curl_error($handle);
error_log("Curl returned error $errno: $error\n");
curl_close($handle);
return false;
}
$http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
curl_close($handle);
if ($http_code >= 500) {
// do not wat to DDOS server if something goes wrong
sleep(10);
return false;
} else if ($http_code != 200) {
$response = json_decode($response, true);
error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n");
if ($http_code == 401) {
throw new Exception('Invalid access token provided');
}
return false;
} else {
$response = json_decode($response, true);
if (isset($response['description'])) {
error_log("Request was successfull: {$response['description']}\n");
}
$response = $response['result'];
}
return $response;
}
function apiRequest($method, $parameters) {
if (!is_string($method)) {
error_log("Method name must be a string\n");
return false;
}
if (!$parameters) {
$parameters = array();
} else if (!is_array($parameters)) {
error_log("Parameters must be an array\n");
return false;
}
foreach ($parameters as $key => &$val) {
// encoding to JSON array parameters, for example reply_markup
if (!is_numeric($val) && !is_string($val)) {
$val = json_encode($val);
}
}
$url = API_URL.$method.'?'.http_build_query($parameters);
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 60);
return exec_curl_request($handle);
}
function apiRequestJson($method, $parameters) {
if (!is_string($method)) {
error_log("Method name must be a string\n");
return false;
}
if (!$parameters) {
$parameters = array();
} else if (!is_array($parameters)) {
error_log("Parameters must be an array\n");
return false;
}
$parameters["method"] = $method;
$handle = curl_init(API_URL);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 60);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
return exec_curl_request($handle);
}
function processMessage($message) {
// process incoming message
$message_id = $message['message_id'];
$chat_id = $message['chat']['id'];
if (isset($message['text'])) {
apiRequest("sendChatAction", array('chat_id' => $chat_id, "action" => "typing"));
// incoming text message
$text = $message['text'];
//Command for intializing the backend code for the birthday check (just to check its functionality but would prefer the code to run without a command)
if (strpos($text, "/geburtstagscheck") === 0) {
include 'skripte/start.php';
}
}}
define('WEBHOOK_URL', 'XXXXXXXXXXXXXX');
if (php_sapi_name() == 'cli') {
// if run from console, set or delete webhook
apiRequest('setWebhook', array('url' => isset($argv[1]) && $argv[1] == 'delete' ? '' : WEBHOOK_URL));
exit;
}
$content = file_get_contents("php://input");
$update = json_decode($content, true);
if (!$update) {
// receive wrong update, must not happen
exit;
}
if (isset($update["message"])) {
processMessage($update["message"]);
} ?>
I'm just try to find is there is any TIMEOUT or MAX EXECUTION TIME for execute Symfony2 tasks. Why? Any time I execute the task pdone:sync it stop with this log:
Symfony > pdone:sync
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Undefined offset: 2000
pdone:sync
The command terminated with an error status (1)
This is my code which is called from task as a service and second SOQL query returns exactly 6911 items so it should insert 6911 and not stop at 2000, why? what is happening there? Any advice or help or ideas?
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use PDI\PDOneBundle\Entity;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\RequestStack;
class SyncController extends Controller
{
private $_em;
private $_container;
private $_rs;
public function __construct(Container $container, EntityManager $em, RequestStack $rs)
{
$this->_container = $container;
$this->_em = $em;
$this->_rs = $rs;
}
public function syncVeevaData()
{
$em = $this->_em;
$request = $this->_rs->getCurrentRequest();
$container = $this->_container;
// Will need this in the whole function so lets declare it here
$now = new \DateTime();
$expireTime = clone $now;
$expireTime = $expireTime->modify('+1 week');
// Request veeva token and instance URL
$token_url = $container->getParameter('login_uri')."/services/oauth2/token";
$params = "grant_type=".$container->getParameter('grant_type')
."&client_id=".$container->getParameter('client_id')
."&username=".$container->getParameter('veeva_username')
."&password=".$container->getParameter('veeva_password')
."&client_secret=".$container->getParameter('client_secret')
."&redirect_uri=".urlencode($container->getParameter('redirect_uri'));
$curl = curl_init($token_url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status != 200) {
$respObj['error'] = "Error: call to token URL $token_url failed with status $status, response $json_response, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$response = json_decode($json_response, true);
$veevaToken = $respObj['access_token'] = $response['access_token'];
$instanceUrl = $respObj['instance_url'] = $response['instance_url'];
if (!isset($veevaToken) || $veevaToken == "") {
$respObj['error'] = "Error - access token missing from response!";
return $respObj;
}
if (!isset($instanceUrl) || $instanceUrl == "") {
$respObj['error'] = "Error - instance URL missing from response!";
return $respObj;
}
// Request reps and sync against DB
$soqlQuery1 = "SELECT Id,FirstName,LastName,Username,Email,LastModifiedDate FROM User";
$soqlUrl1 = $instanceUrl.'/services/data/v28.0/query/?q='.urlencode($soqlQuery1);
$curl = curl_init($soqlUrl1);
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 to token URL $token_url failed with status $status, response $json_response, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$soqlObj1 = json_decode($jsonResponse, true);
for ($i = 0; $i < $soqlObj1['totalSize']; $i++) {
$entReps = $em->getRepository('PDOneBundle:Representative')->findOneBy(
array(
'veeva_rep_id' => $soqlObj1['records'][$i]['Id'],
)
);
if (!$entReps) {
// if there is no reps, then we add
$newReps = new Entity\Representative();
// we set the values from veeva
$newReps->setVeevaRepId($soqlObj1['records'][$i]['Id']);
$newReps->setEmail($soqlObj1['records'][$i]['Email']);
$newReps->setFirst($soqlObj1['records'][$i]['FirstName']);
$newReps->setLast($soqlObj1['records'][$i]['LastName']);
$newReps->setUsername($soqlObj1['records'][$i]['Username']);
$newReps->setLastLoginAt($now);
$newReps->setLastSyncAt($now);
$newReps->setDisplayName(
$soqlObj1['records'][$i]['FirstName'].' '.$soqlObj1['records'][$i]['LastName']
);
$newReps->setRepType("VEEVA");
$em->persist($newReps);
$em->flush();
// Put new reps into $newRepsArr
$repsArr[$newReps->getId()] = $newReps->getVeevaRepId();
} else {
$lastModifiedDate = new \DateTime(
$soqlObj1['records'][$i]['LastModifiedDate']
);
if ($lastModifiedDate > $entReps->getLastSyncAt()) {
// obtained a reps, we update its data
$entReps->setEmail($soqlObj1['records'][$i]['Email']);
$entReps->setFirst($soqlObj1['records'][$i]['FirstName']);
$entReps->setLast($soqlObj1['records'][$i]['LastName']);
$entReps->setUsername($soqlObj1['records'][$i]['Username']);
$entReps->setLastLoginAt($now);
$entReps->setLastSyncAt($now);
$entReps->setDisplayName(
$soqlObj1['records'][$i]['FirstName'].' '.$soqlObj1['records'][$i]['LastName']
);
$entReps->setRepType("VEEVA");
// Put updated reps into $updRepsArr
$repsArr[$entReps->getId()] = $entReps->getVeevaRepId();
}
}
}
$em->flush();
// Get territories and sync against DB
$soqlQuery2 = "SELECT Id,Name,LastModifiedDate FROM 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 to token URL $token_url failed with status $status, response $json_response, curl_error ".curl_error(
$curl
).", curl_errno ".curl_errno($curl);
return $respObj;
}
curl_close($curl);
$soqlObj2 = json_decode($jsonResponse, true);
for ($i = 0; $i < $soqlObj2['totalSize']; $i++) {
$entTerritory = $em->getRepository('PDOneBundle:Territory')->findOneBy(
array(
'veeva_territory_id' => $soqlObj2['records'][$i]['Id']
)
);
if (!$entTerritory) {
// if there is no territory, then we add
$newTerritory = new Entity\Territory();
// we set the values from veeva
if ($soqlObj2['records'][$i]['Id'] !== null || $soqlObj2['records'][$i]['Id'] !== "") {
$newTerritory->setVeevaTerritoryId($soqlObj2['records'][$i]['Id']);
$newTerritory->setName($soqlObj2['records'][$i]['Name']);
$em->persist($newTerritory);
$em->flush();
}
$terrArr[] = $newTerritory->getId();
$terrFailArr[] = $soqlObj2['records'][$i]['Name'];
} else {
$lastModifiedDate = new \DateTime(
$soqlObj2['records'][$i]['LastModifiedDate']
);
if ($lastModifiedDate > $entTerritory->getUpdatedAt()) {
// obtained a territory, we update its data
$entTerritory->setName($soqlObj2['records'][0]['Name']);
}
$terrArr[] = $entTerritory->getId();
}
}
$em->flush();
return $respObj;
}
}
Can anyone help with the following
I'm trying to make a JSON request to a RESTful API. The code below is kindly shared by Wes Furlong
The code seems to be able to decode to JSON fine but sends as a URL encoded string
<?php
function rest_helper($url, $params = null, $verb = 'GET', $format = 'json')
{
$cparams = array(
'http' => array(
'method' => $verb,
'ignore_errors' => true
)
);
if ($params !== null) {
$params = http_build_query($params);
if ($verb == 'POST') {
$cparams['http']['content'] = $params;
} else {
$url .= '?' . $params;
}
}
$context = stream_context_create($cparams);
$fp = fopen($url, 'rb', false, $context);
if (!$fp) {
$res = false;
} else {
// If you're trying to troubleshoot problems, try uncommenting the
// next two lines; it will show you the HTTP response headers across
// all the redirects:
// $meta = stream_get_meta_data($fp);
// var_dump($meta['wrapper_data']);
$res = stream_get_contents($fp);
}
if ($res === false) {
throw new Exception("$verb $url failed: $php_errormsg");
}
switch ($format) {
case 'json':
$r = json_decode($res);
if ($r === null) {
throw new Exception("failed to decode $res as json");
}
return $r;
case 'xml':
$r = simplexml_load_string($res);
if ($r === null) {
throw new Exception("failed to decode $res as xml");
}
return $r;
}
return $res;
}
I need to be able to:
Add a content type of application/json
Convert params to JSON
Can't use curl in this environment
The main thing is the content type -- currently defaults to urlencoded
Any tips or ideas appreciated - Thanks
Latest attempt
function restHelper($url, $params = null, $verb = 'GET', $format = 'json'){
$cparams = array(
'http' => array(
'method' => $verb,
'ignore_errors' => true,
'header' =>"Content-type: application/json \r\n"
)
);
if ($params !== 'None') {
$jparams = json_encode($params);
if ($verb == 'POST') {
$cparams['http']['content'] = $jparams;
} elseif ($verb =='PUT') {
$cparams['http']['content'] = $jparams;
} else {
$params = http_build_query($params);
$url .= '?' . $params;
}
}
Still not working -- API tests fine from REST IDE Seems to be from how the content type is working for JSON
In the end found a way of including CURL in scriptcase.
Here is what worked (prototype)
(Thanks Lorna Jane http://www.lornajane.net/posts/2011/posting-json-data-with-php-curl)
Thanks everyone that looked at this
$service_url = 'http://dev.eventplus.co.nz/api/logon';
$ch = curl_init($service_url);
$data = '[
{
"Header": {
"Username": "testapi#teamprema.co.nz",
"SessionId": "123"
}
},
{
"Config": {}
},
{
"Params": {"Query": {"Password": "test12345"}}
}
]';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data))
);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
$response = curl_exec($ch);
if ($response === false) {
$info = curl_getinfo($ch);
curl_close($ch);
die('error occured during curl exec. Additioanl info: ' . var_export($info));
}
curl_close($ch);
print $response;