Escaping "?" in URL with PHP functions - php

function prepareHeader($url, $method, $ctype = null)
{
$accInfo = json_decode(file_get_contents("etradeAccountInfo.json"), true);
$consumerKey = $accInfo['consumerKey'];
$consumerSecret = $accInfo['consumerSecret'];
$requestInfo = json_decode(file_get_contents("etrade_oauth.json"), true);
$oauth = array(
'oauth_consumer_key' => $consumerKey,
'oauth_nonce' => md5(mt_rand()),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_version' => '1.0',
'oauth_token' => $requestInfo['oauth_token']
);
$base_info = buildBaseString($url, $method, $oauth);
$composite_key = rawurlencode($consumerSecret) . '&' . rawurlencode($requestInfo['oauth_token_secret']);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:', 'Accept:application/json', $ctype);
return $header;
}
$count100 = '?count=100';
$urlFragment = "accounts/$accountIdKey/portfolio";
$URL = $url . $urlFragment . $count100;
$header = prepareHeader($URL, 'GET');
// Prepare new cURL resource
$options = array(
CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CUSTOMREQUEST => "GET"
);
$feed = curl_init();
curl_setopt_array($feed, $options);
$response = curl_exec($feed);
// curl_close($feed);
print_r($response);
I'm trying to PHP CURL the following URL but it wouldn't work - it skipped the entire function above because of the ?count=100 if I were to take it out then it works fine... Here's the url I'm trying to curl it with https://api.etrade.com/v1/accounts/asdfsd34545/portfolio?count=100
any kind of help on this is greatly appreciated!

Related

Problems to post a tweet with php

I'm using this code to get the last 20 tweets I was mentioned in.
But I can't adapt it to be able to tweet a simple text tweet. can someone help me?
I tried everything but i'm stuck.
I dont know what to do...
I know I have to post to /update.json , and use update -> text
but its not working
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
function returnTweet(){
$oauth_access_token = "xxxxxxxxxxxxxxxx";
$oauth_access_token_secret = "xxxxxxxxxxxxxxxx";
$consumer_key = "xxxxxxxxxxxxxxxx";
$consumer_secret = "xxxxxxxxxxxxxxxx";
$timeline = "mentions_timeline";
// create request
$requestrt = array(
'screen_name' => 'myScreenName',
'extended_entities' => 'true',
'exclude_replies' => 'true',
'include_rts' => 'false',
'tweet_mode' => 'extended',
'count' => '20');
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
// merge request and oauth to one array
$oauth = array_merge($oauth, $requestrt);
$base_info = buildBaseString("https://api.twitter.com/1.1/statuses/$timeline.json", 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
// make request
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$timeline.json?". http_build_query($requestrt),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
return json_decode($json, true);
}
$tweet = returnTweet();

Parameters breaks OAuth

I have an array $fields with a screen_name and a count.
No matter what I try, if I add them I get an error
Could not authenticate you.
One attempt was:
$parameters = array_merge($oauth, $fields);
I'm not gonna list all attempts cause that will just be noise.
Without using the parameter fields everything works ok.
Can someone help, i'm totally lost here.
$settings = array(
'oauth_access_token' => "304291054-X3AyJrHYUswZQbXXXXXXXXXXXXXOKw53xOi9E",
'oauth_access_token_secret' => "iWuakK6iWsfXXXXXXXXXSGcW6WeqxLsiQf",
'consumer_key' => "odXXXXXXXXXXkBg6GmsTg",
'consumer_secret' => "5LoqUsXXXXXXXXXXXXXXXXi6zgmQ"
);
$base_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$http_method = 'GET';
$fields = array(
'screen_name' => 'wearethegun',
'count' => '5'
);
$oauth = array(
'oauth_consumer_key' => $settings['consumer_key'],
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $settings['oauth_access_token'],
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
// todo, fields
$parameters = $oauth;
ksort($parameters);
$base = $http_method.'&'.
rawurlencode($base_url).'&'.
rawurlencode(http_build_query($parameters));
$key = rawurlencode($settings['consumer_secret']).'&'.
rawurlencode($settings['oauth_access_token_secret']);
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
$signature = rawurlencode($signature);
$oauth_header = '';
foreach ($oauth as $key => $value) {
$oauth_header .= $key.'="'.$value.'", ';
}
$oauth_header .= 'oauth_signature="' . $signature . '"';
$curl_options = array(
CURLOPT_HTTPHEADER => array("Authorization: Oauth {$oauth_header}", 'Expect:'),
CURLOPT_HEADER => false,
CURLOPT_URL => $base_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
);
$curl_request = curl_init();
curl_setopt_array($curl_request, $curl_options);
$json_str = curl_exec($curl_request);
curl_close($curl_request);
$json = json_decode($json_str, true);
echo "<pre>";
print_r($json);
echo "</pre>";

Oauth header issue with twitter api 1.1

I've been trying to access the new twitter api (1.1) for 3 days now, the new oauth system and i are not compatible. I only want to grab 3 of my latest tweets (which are public so why the need for oauth over simple rss is annoying)
<?php
$header = 'GET /statuses/user_timeline.json?screen_name=NAME&count=3&include_rts=false HTTP/1.1
Host: https://www.twtter.com:443
Authorization: OAuth realm="https://https://www.twtter.com/statuses/user_timeline.json",
oauth_consumer_key="key",
oauth_token="mytoken",
oauth_nonce="",
oauth_timestamp="0",
oauth_signature_method="HMAC-SHA1",
oauth_version="1.0",
oauth_signature="O4yJhqnYlxMP5U97rJ%2F4UuLjh84%3D"';
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=NAME&count=3&include_rts=false";
$options = array(
CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
?>
The header seems to be the problem ( i generated it using: http://hueniverse.com/oauth/guide/authentication/ )
NAME, MYTOKEN, KEY are placeholders for posts' sake.
Can anyone see what the problem is?
This is what I use. Just call returnTweet()
For more info about 'user_timeline', visit API documentation
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
function returnTweet(){
$oauth_access_token = "xxx";
$oauth_access_token_secret = "xxx";
$consumer_key = "xxx";
$consumer_secret = "xxx";
$twitter_timeline = "user_timeline"; // mentions_timeline / user_timeline / home_timeline / retweets_of_me
// create request
$request = array(
'trim_user' => 1,
'screen_name' => 'budidino',
'count' => '3'
);
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
// merge request and oauth to one array
$oauth = array_merge($oauth, $request);
// do some magic
$base_info = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
// make request
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
return json_decode($json, true);
}
I hope it helps ;)

Twitter API not authorized when running from crontab

I have set up OAuth and I am using CURL to get the latest tweet, this works perfectly when I run it from my browser
http://mydomain.com/getstatus.php
The script write statuses into a file:
$xTIME = time();
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => $xTIME,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => $xTIME,
'oauth_version' => '1.0'
);
$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array(
CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
if(isset($twitter_data[0]->text))
{
$fp = fopen('/var/www/mydomain.com/feeds/twitter.feed', 'w');
fwrite($fp, $twitter_data[0]->text);
fclose($fp);
}
This writes to the file nicely, the idea is to have this run every hour.
So I set up a cronjob
0 * * * * lynx -accept_all_cookies http://mydomain.com/getstatus.php
But I get this returned:
[request] => /1/statuses/user_timeline.json?count=1&screen_name=twitter
[error] => Rate limit exceeded. Clients may not make more than 150 requests per hour.
Which suggests it is not authorizing and so treating the request as an unauth'd request.
My question is, why would it not be authorizing?
I have tried running it as a crontab and running it through lynx and I get the same outcome both times.
Edit:
Here are the full functions,
function buildBaseString($baseURI, $method, $params)
{
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth)
{
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
function loadTW($twID)
{
$url = "https://api.twitter.com/1/statuses/user_timeline.json&count=1&screen_name=" .$twID;
$oauth_access_token = "68161130-X4HRZje9wB3lpyeOPYDJPsqG1JfJxxxxxxxx";
$oauth_access_token_secret = "zN98CUldHN4eiVeGahZIvpNeUGljRTxxxxxxxx";
$consumer_key = "PeVEz2Z0QSKtxxxxxxx";
$consumer_secret = "An9Xh3qHHTEiTQzW5wKLFMHOrbzwFtwxxxxxxxx";
$xTIME = time();
$oauth = array( 'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => $xTIME,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => $xTIME,
'oauth_version' => '1.0');
$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
if(isset($twitter_data[0]->text))
{
$fp = fopen('/var/www/carlandalexfishing.co.uk/feeds/twitter.feed', 'w');
fwrite($fp, $twitter_data[0]->text);
fclose($fp);
}
}
It's pretty hard to know what's going on in your code, as it's not the full code. Anyway :
Your OAuth code only signs the oauth_* headers, not any query arguments.
Your $url variable seems to contain query parameters as well, judging by the error message.
To solve this, just move the query parameters into a separate array and sign the OAuth request with them.
Illustration of what's going wrong (intentionally left out url encoding and added spaces):
GET & https://api.twitter.com/1/endpoint.json?count=1&screen_name=twitter & oauth_abc=def&oauth_ghi=jkl
The query part of the URL shouldn't go in the second part of the OAuth base string. Better :
GET & https://api.twitter.com/1/endpoint.json & count=1&oauth_abc=def&oauth_ghi=jkl&screen_name=twitter

twitter API 1.1: cannot add the 'count' parameter using curl & php

I'm connecting to the new twitter API to get a list of my profiles' public tweets.
I'm basically using the following code, which I found here: Simplest PHP example for retrieving user_timeline with Twitter API version 1.1
I'm getting the last 20 tweets and I've tried many different ways to add the "count" parameter to the curl call, but nothing seems to return more results.
I tried giving a value to the $postfields:
$postfields = array(
'count' => 100,
'include_rts' => 1
);
//url-ify the data for the POST
foreach($postfields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
Giving a simple string value:
§postfields = 'count=100';
and changing the $url value into:
$url = "https://api.twitter.com/1.1/statuses/home_timeline.json?count=100";
Any other suggestions?
Thanks for your help!!
This is the complete code for reference:
function buildBaseString($baseURI, $method, $params) {
$r = array();
ksort($params);
foreach($params as $key=>$value){
$r[] = "$key=" . rawurlencode($value);
}
return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}
function buildAuthorizationHeader($oauth) {
$r = 'Authorization: OAuth ';
$values = array();
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\"";
$r .= implode(', ', $values);
return $r;
}
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
$oauth_access_token = "YOURVALUE";
$oauth_access_token_secret = "YOURVALUE";
$consumer_key = "YOURVALUE";
$consumer_secret = "YOURVALUE";
$oauth = array( 'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0');
$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
$items = '15';
$screen_name = 'YOUR SCREEN NAME';
/* the $oauth */
$oauth = array(
'screen_name' => $screen_name,
'count' => $items,
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $oauth_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0'
);
$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;
$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array(
CURLOPT_HTTPHEADER => $header,
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url . '?screen_name='.$screen_name.'&count='.$items,
CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false
);

Categories