I am struggling with the API of Exact Online.
Using this example code to retrieve information of the server:
$response = $exactApi->sendRequest("crm/Accounts?$filter=substringof('test', Name) eq true', 'get');
Above returns a Bad Request. Anyone got a clue how to fix this?
The function 'send request':
public function sendRequest($url, $method, $payload = NULL)
{
if ($payload && !is_array($payload)) {
throw new ErrorException('Payload is not valid.');
}
if (!$accessToken = $this->initAccessToken()) {
throw new ErrorException('Access token was not initialized');
}
$requestUrl = $this->getRequestUrl($url, array(
'access_token' => $accessToken
));
// Base cURL option
$curlOpt = array();
$curlOpt[CURLOPT_URL] = $requestUrl;
$curlOpt[CURLOPT_RETURNTRANSFER] = TRUE;
$curlOpt[CURLOPT_SSL_VERIFYPEER] = TRUE;
$curlOpt[CURLOPT_HEADER] = false;
if ($method == self::METHOD_POST) {
$curlOpt[CURLOPT_HTTPHEADER] = array(
'Content-Type:application/json',
'access_token:' . $accessToken,
'Content-length: ' . strlen(json_encode($payload))
);
$curlOpt[CURLOPT_POSTFIELDS] = json_encode($payload);
$curlOpt[CURLOPT_CUSTOMREQUEST] = strtoupper($method);
}
$curlOpt[CURLOPT_ENCODING] = '';
$curlHandle = curl_init();
curl_setopt_array($curlHandle, $curlOpt);
return curl_exec($curlHandle);
}
Tested this.
crm/Accounts?$select=Name&$filter=substringof('Lennert',Name) : OK
crm/Accounts?$select=Name&$filter=substringof('Lennert', Name) eq true : NOK, error 400
crm/Accounts?\$select=Name&$filter=substringof(Name, 'Lennert') eq true : NOK, error 400
First option works but is not according to OData v2 specifications which Exact Online uses. Will be discussed with development to see what can be done for this.
Related
I'm trying to get latitude and longitude from Google's Geocode API. The $url I'm using outputs the correct JSON however something in my script isn't working correctly. It's not outputting the $lati & $longi variables. Please check see the script below:
PHP:
<?php
$address = 'Tempe AZ';
$address = urlencode($address);
$url = "https://maps.google.com/maps/api/geocode/json?sensor=false&address={$address}";
$resp_json = file_get_contents($url);
$resp = json_decode($resp_json, true);
if ($resp['status'] == 'OK') {
// get the important data
$lati = $resp['results'][0]['geometry']['location']['lat'];
$longi = $resp['results'][0]['geometry']['location']['lng'];
echo $lati;
echo $longi;
} else {
return false;
}
?>
I brought in the Guzzle http package at the top of my Laravel file/class: use GuzzleHttp\Client;
Then, to take an address and convert it to lat and lng to save with PHP/Laravel and Google Maps API, I added this code in my save() method:
// get latitude and longitude of address with Guzzle http package and Google Maps geocode API
$client = new Client(); // GuzzleHttp\Client
$baseURL = 'https://maps.googleapis.com/maps/api/geocode/json?address=';
$addressURL = urlencode(request('street')) . ',' . urlencode(request('city')) . ',' . urlencode(request('state')) . '&key=' . env('GOOGLE_MAPS_API_KEY');
$url = $baseURL . $addressURL;
$request = $client->request('GET', $url);
$response = $request->getBody()->getContents();
$response = json_decode($response);
$latitude = $response->results[0]->geometry->location->lat;
$longitude = $response->results[0]->geometry->location->lng;
It turned out to be a proxy issue. This thread helped: Using proxy with file_get_contents
Added this:
$opts = array(
'http' => array(
'method' => "GET",
'header' => "Accept-language: en\r\n".
"Cookie: foo=bar\r\n",
'proxy' => 'tcp://proxy.proxy.com:8080',
)
);
$context = stream_context_create($opts);
// open the file using the HTTP headers set above
$file = file_get_contents($url, false, $context);
Your script works for me too. Maybe you will get an error calling:
$resp_json = file_get_contents($url);.
If that happens you should do this:
$resp_json = #file_get_contents($url);
if ($resp_json === FALSE) {
///logic for exception
} else {
///do your logic hear
}
I am using Google Tracks API to build a simple web based program to track a vehicle that has a tracking device sending latitude and longitude coordinates.
I am using PHP and the OAuth2 PHP library to make an authorized connection.
After authorizing and getting an access token I am making a request to create entities. Though I can't seem to get this working and keep getting a "400 Bad Request" response. Following all the steps shown in the documentation.
Here is my code:
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$parsedAuth['access_token'];
$data = array('entities' => array( "name"=> "Chevrolet" ));
$json_data = json_encode($data);
$data_length = http_build_query($data);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n". "Content-Length: " . strlen($data_length) . "\r\n",
'method' => 'POST',
'content' => $json_data
),
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
var_dump($response);
Exact Error is: "failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request"
Why am I getting a bad request? What would be a good request that will register these entities and return id's?
Thank you
The answer given here is wrong. The documentation states that it must be a POST see here My issue was not with the Auth but with the Tracks API itself. I ended up moving to create the request with CURL and it works just fine.
Please. This is PHP with CURL. It works 100%.
//Google maps tracks connection
//Get Files From PHP Library
require_once 'google-api-php-client/src/Google/autoload.php';
require_once 'google-api-php-client/src/Google/Service/MapsEngine.php';
//Set Client Credentials
$client_id = '*************.apps.googleusercontent.com'; //Client ID
$service_account_name = '************#developer.gserviceaccount.com'; //Email Address
$client_email = '*************#developer.gserviceaccount.com';
$private_key = file_get_contents('************.p12');
$scopes = array('https://www.googleapis.com/auth/tracks');
//Create Client
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//Send Credentials
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key
);
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$client->setAssertionCredentials($credentials);
$_SESSION['service_token'] = $client->getAccessToken();
foreach ($_SESSION as $key=> $value) {
$vars = json_decode($value);
}
$parsedAuth = (array) $vars;
$token = $parsedAuth['access_token'];
//all functions in the program use this auth token- It should be global for easy accesses.
global $token;
function createEntities(){
global $token;
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$token;
//FIX ME: fields is temporarily hard coded- should be brought from DB
$fields = array(
'entities' => array(
'name' => "DemoTruck",
'type' => "AUTOMOBILE"
),
);
//json string the data for the POST
$query_string = '';
foreach($fields as $key => $array) {
$query_string .= '{"' . urlencode($key).'":[{';
foreach($array as $k => $v) {
$query_string .= '"' . urlencode($k) . '":"' . urlencode($v) . '",';
}
}
$str = rtrim($query_string , ',');
$fstr = $str.'}]}';
$length = strlen( $fstr );
//open connection
$ch = curl_init();
//test connection
if (FALSE === $ch)
throw new Exception('failed to initialize');
//set options
$header = array('Content-type: application/json');
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fstr);
$result = curl_exec($ch);
//dump in case of error
if (FALSE === $result){
var_dump( curl_error($ch) );
var_dump( curl_getinfo($ch) );
}
//close connection
curl_close($ch);
}
I've been able to successfully log a user in and return their details. The next step is to get them to post a comment via my app.
I tried modifying code from the reddit-php-sdk -- https://github.com/jcleblanc/reddit-php-sdk/blob/master/reddit.php -- but I can't get it to work.
My code is as follows:
function addComment($name, $text, $token){
$response = null;
if ($name && $text){
$urlComment = "https://ssl.reddit.com/api/comment";
$postData = sprintf("thing_id=%s&text=%s",
$name,
$text);
$response = runCurl($urlComment, $token, $postData);
}
return $response;
}
function runCurl($url, $token, $postVals = null, $headers = null, $auth = false){
$ch = curl_init($url);
$auth_mode = 'oauth';
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 10
);
$headers = array("Authorization: Bearer {$token}");
$options[CURLOPT_HEADER] = false;
$options[CURLINFO_HEADER_OUT] = false;
$options[CURLOPT_HTTPHEADER] = $headers;
if (!empty($_SERVER['HTTP_USER_AGENT'])){
$options[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
}
if ($postVals != null){
$options[CURLOPT_POSTFIELDS] = $postVals;
$options[CURLOPT_CUSTOMREQUEST] = "POST";
}
curl_setopt_array($ch, $options);
$apiResponse = curl_exec($ch);
$response = json_decode($apiResponse);
//check if non-valid JSON is returned
if ($error = json_last_error()){
$response = $apiResponse;
}
curl_close($ch);
return $response;
}
$thing_id = 't2_'; // Not the actual thing id
$perma_id = '2daoej'; // Not the actual perma id
$name = $thing_id . $perma_id;
$text = "test text";
$reddit_access_token = $_SESSION['reddit_access_token'] // This is set after login
addComment($name, $text, $reddit_access_token);
The addComment function puts the comment together according to their API -- http://www.reddit.com/dev/api
addComment then calls runCurl to make the request. My guess is that the curl request is messed up because I'm not receiving any response whatsoever. I'm not getting any errors so I'm not sure what's going wrong. Any help would really be appreciated. Thanks!
If you are using your own oAuth solution, I would suggest using the SDK as I said in my comment, but extend it to overwrite the construct method.
class MyReddit extends reddit {
public function __construct()
{
//set API endpoint
$this->apiHost = ENDPOINT_OAUTH;
}
public function setAuthVars($accessToken, $tokenType)
{
$this->access_token = $accessToken;
$this->token_type = $tokenType;
//set auth mode for requests
$this->auth_mode = 'oauth';
}
}
You just need to make sure that you call setAuthVars before running any api calls.
I am currently writing an C# windows service, which integrates with a PHP page. I have an example of code making the request in PHP which is below however I have never developed in PHP and don't understand how the cURL function performs the request.
Is there anyway to retrieve the request which is being sent? Or can anyone provide an example of how the request would look and how the request is sent so I can replicate the request in C#.
Thank you for any help.
public function api(/* polymorphic */) {
$args = func_get_args();
if (is_array($args[0])) {
$serviceId = $this->getApiServiceId($args[0]["method"]);
unset($args[0]["method"]);
$args[0]["serviceId"] = $serviceId;
$args[0]["dealerId"] = $this->dealerId;
$args[0]["username"] = $this->username;
$args[0]["password"] = $this->password;
$args[0]["baseDomain"] = $this->baseDomain;
return json_decode($this->makeRequest($args[0]));
} else {
throw Exception("API call failed. Improper call.");
}
}
protected function makeRequest($params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}
$opts = self::$CURL_OPTS;
if ($this->useFileUploadSupport()) {
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
// disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
// for 2 seconds if the server does not support this header.
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
} else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if ($result === false) {
$e = new WPSApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
return $result;
}
Add the option CURLINFO_HEADER_OUT to curl handle, then call curl_getinfo on it after execing.
As in:
//...
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
//...
curl_exec($ch);
//...
$header = curl_getinfo(CURLINFO_HEADER_OUT);
echo $header;
Could anyone help me figure out how to post to tumblr using php.
I tried googling for a library or a sample code but couldn't find one. all I can find is this here https://github.com/alexdunae/tumblr-php/blob/master/Tumblr.php and it doesnt seem to work also I looked and tried the code on v1 api at tumblr website that doesnt work either ....
function post($data){
if(function_exists("curl_version")){
$data["email"] = $this->email;
$data["password"] = $this->password;
$data["generator"] = $this->generator;
$request = http_build_query($data);
$c = curl_init('http://www.tumblr.com/api/write');
curl_setopt($c,CURLOPT_POST,true);
curl_setopt($c,CURLOPT_POSTFIELDS,$request);
curl_setopt($c,CURLOPT_RETURNTRANSFER,true);
$return = curl_exec($c);
$status = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
if($status == "201"){
return true;
}
elseif($status == "403"){
return false;
}
else{
return "error: $return";
}
}
else{
return "error: cURL not installed";
}
}
Thanks for the help
I just noticed that this is showing up as Featured for Tumblr and I want to say this: As of 2012, you should IGNORE the above answer by Tuga because it DOES NOT work with the newest Tumblr API.
What you need is TumblrOAuth which is built from OAuth Sandbox.
It is only setup to read and write Tumblr posts, so if you want to do more than that, you'll need to alter the code. I used it as my code base for Followr.
Stolen from http://www.tumblr.com/docs/en/api
// Authorization info
$tumblr_email = 'info#davidville.com';
$tumblr_password = 'secret';
// Data for new record
$post_type = 'regular';
$post_title = 'The post title';
$post_body = 'This is the body of the post.';
// Prepare POST request
$request_data = http_build_query(
array(
'email' => $tumblr_email,
'password' => $tumblr_password,
'type' => $post_type,
'title' => $post_title,
'body' => $post_body,
'generator' => 'API example'
)
);
// Send the POST request (with cURL)
$c = curl_init('http://www.tumblr.com/api/write');
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $request_data);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($c);
$status = curl_getinfo($c, CURLINFO_HTTP_CODE);
curl_close($c);
// Check for success
if ($status == 201) {
echo "Success! The new post ID is $result.\n";
} else if ($status == 403) {
echo 'Bad email or password';
} else {
echo "Error: $result\n";
}
?>
$conskey = "CONSUMER KEY";
$conssec = "CONSUMER SECRET";
$tumblr_blog = "myblog.tumblr.com";
$to_be_posted = "This is the text to be posted";
$oauth = new OAuth($conskey,$conssec);
$oauth->fetch("http://api.tumblr.com/v2/blog/".$tumblr_blog."/post", array('type'=>'text', 'body'=>$to_be_posted), OAUTH_HTTP_METHOD_POST);
$result = json_decode($oauth->getLastResponse());
if($result->meta->status == 200){
echo 'Success!';
}
This code will let you post to your tumblr blog using tumblr API.
I hope this code helps.
The api example provided by Tuga is working for me (on Wordpress)...so I think your problem lies elsewhere, and not with the example provided. I would also be very appreciative if you guys got a version 2 api working if you could post it.