I'm trying to get some parameters passed in an OAuth fetch.
In the first script, I'm making the Oauth request this way.
$ids = array( 'a' => 1, 'b' => 2);
$oauth = new OAuth("consumer_key","consumer_secret");
$url = $this->getUrlApi();
$oauth->fetch($url,array('ids' => $ids),OAUTH_HTTP_METHOD_POST);
In the second, I'm trying to get the parametrs i've passed in the query. I'm getting an empty parameter.
$ids = $_REQUEST['ids'];
What the wrong thing in my code please. Thanks
Related
I'm using the twitter api to try to get an integer that tells me how many tweets there are to a certain string I give.
e.g. I search for "mercedes" and then want to get an integer back from twitter that says: "1249". 1249 would mean that there were so many tweets in the last 2 weeks. Twitter only returns data from the last 2 weeks as far as I know. Because of me it's also okay if I get all records back and pull them by means of php or the like. I have already sent some test requests, but always only get arrays back with a maximum of 20 entries.
Anyone have a solution?
And I already looked at similar questions but couldn't find something that helped me. Many answers in the questions I have seen no longer work, as twitter and its api has changed and evolved
Using the public search API, you will get tweets from the last 7 days only and not all tweets. So your results won't be accurate.
If you still want to test, you have to use the standard search API :
https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets.html
Set the "cout" parameter to 100, and check the "next_results" value in the results to loop 100 others tweets and so on until you get no result.
I couldn't find a solution neither, so I coded it using pieces of code and ideas as the previous #JeffProd one, and avoiding using a lib. I hope it could help you.
PS: You must apply for a Twitter Developer Account and create an app to get your TOKENs and KEYs.
<?php
//Access token & access token secret
define("TOKEN", 'XXXXXXXXXXXXXXXX'); //Access token
define("TOKEN_SECRET", 'XXXXXXXXXXXXXXXX'); //Access token secret
//Consumer API keys
define("CONSUMER_KEY", 'XXXXXXXXXXXXXXXX'); //API key
define("CONSUMER_SECRET", 'XXXXXXXXXXXXXXXX'); //API secret key
$method='GET';
$host='api.twitter.com';
$path='/1.1/search/tweets.json'; //API call path
$url="https://$host$path";
//Query parameters
$query = array(
'q' => 'wordtosearch', /* Word to search */
'count' => '100', /* Specifies a maximum number of tweets you want to get back, up to 100. As you have 100 API calls per hour only, you want to max it */
'result_type' => 'recent', /* Return only the most recent results in the response */
'include_entities' => 'false' /* Saving unnecessary data */
);
//time window in hours
define("WINDOW", 1);
//Authentication
$oauth = array(
'oauth_consumer_key' => CONSUMER_KEY,
'oauth_token' => TOKEN,
'oauth_nonce' => (string)mt_rand(), //A stronger nonce is recommended
'oauth_timestamp' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_version' => '1.0'
);
//Used in Twitter's demo
function add_quotes($str) { return '"'.$str.'"'; }
//Searchs Twitter for a word and get a couple of results
function twitter_search($query, $oauth, $url){
global $method;
$arr=array_merge($oauth, $query); //Combine the values THEN sort
asort($arr); //Secondary sort (value)
ksort($arr); //Primary sort (key)
$querystring=http_build_query($arr,'','&');
//Mash everything together for the text to hash
$base_string=$method."&".rawurlencode($url)."&".rawurlencode($querystring);
//Same with the key
$key=rawurlencode(CONSUMER_SECRET)."&".rawurlencode(TOKEN_SECRET);
//Generate the hash
$signature=rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));
//This time we're using a normal GET query, and we're only encoding the query params (without the oauth params)
$url=str_replace("&","&",$url."?".http_build_query($query));
$oauth['oauth_signature'] = $signature; //Don't want to abandon all that work!
ksort($oauth); //Probably not necessary, but twitter's demo does it
$oauth=array_map("add_quotes", $oauth); //Also not necessary, but twitter's demo does this too
//This is the full value of the Authorization line
$auth="OAuth ".urldecode(http_build_query($oauth, '', ', '));
//If you're doing post, you need to skip the GET building above and instead supply query parameters to CURLOPT_POSTFIELDS
$options=array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
//Query Twitter API
$feed=curl_init();
curl_setopt_array($feed, $options);
$json=curl_exec($feed);
curl_close($feed);
//Return decoded response
return json_decode($json);
};
//Initializing
$done = false; //Loop flag
$countTweets=0; //Tweets fetched
$twitter_data = new stdClass();
$now=new DateTime(date('D M j H:i:s O Y')); //Current search time
//Fetching starts
do{
$twitter_data = twitter_search($query,$oauth,$url);
//Partial results, updating the total amount of tweets fetched
$countTweets += count($twitter_data->statuses);
//If not all the tweets have been fetched, then redo...
if(isset($twitter_data->search_metadata->next_results)){
//Parsing information for max_id in tweets fetched
$string="?max_id=";
$parse=explode("&",$twitter_data->search_metadata->next_results);
$maxID=substr($parse[0],strpos($parse[0],$string)+strlen($string));
$query['max_id'] = -1+$maxID; //Returns results with an ID less than (that is, older than) or equal to the specified ID, to avoid getting the same last tweet
//Twitter will be queried again, this time with the addition of 'max_id'
}else{
$done = true;
}
}while(!$done);
//If all the tweets have been fetched, then we are done
echo "<p>query: ".urldecode($query['q'])."</p>";
echo "<p>tweets fetched: ".$countTweets."</p>";
?>
I need to create line chart for my twitter followers . I have used following code to list the followers details.
$parameters = array('include_user_entities' => true);
$response = $this->api->get('followers/list.json', $parameters);
Its working fine .But its doesn't probvide following date details. How can I get following date details using twitter api
If you write:
$parameters = array('include_user_entities' => true);
$parameters = array();
The second command overwrite the first. Thus $parameters contains an empty array. Try with this:
$parameters = array('include_user_entities' => true);
$response = $this->api->get('followers/list.json', $parameters);
There is no way in the API to tell when someone followed you.
Take a look at the API reference - https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list
The only date in the returned object is created_at - that refers to when the account was created, not when it followed you.
I'm trying to make a cURL GET to scrape a Facebook Graph object:
GET https://graph.facebook.com/?id=**OBJECT_URL**&scrape=true&method=post
In my case, OBJECT_URL contains GET parameters:
https://www.example.com/og.php?a=b&c=d
For that reason I can't have it as a GET parameter in file_get_contents() or CURLOPT_URL, as it'd turn out something like this:
https://graph.facebook.com/?id=**https://www.example.com/og.php?a=b&c=d**&scrape=true&method=post
Is there a way to pass it as a GET parameter in a way similar to CURLOPT_POSTFIELDS?
You need to escape your parameters, the http_build_query function will be useful:
$query = http_build_query([
'id' => 'http://foo?a=1&b=2',
'scrape' => true,
'method' => 'post'
]);
$url = "https://graph.facebook.com/?".$query;
var_dump($url);
This will output:
https://graph.facebook.com/?id=http%3A%2F%2Ffoo%3Fa%3D1%26b%3D2&scrape=1&method=post
I'm using an external class (Zebra_cURL) to execute multiple HTTP GET requests. It worked in the following way:
$items = array(
0=>array('url' => 'url0'),
1=>array('url' => 'url1'),
2=>array('url' => 'url2'),
3=>array('url' => 'url3'),
);
$curl = new Zebra_cURL();
$curl->get(array_column($urls,'url'),'scan_item',$moreimfo);
function scan_item($result,$moreimfo){
$items[$key]['size'] = strlen($result->body);
}
So my callback should fill up my $items array with more info for each url (in my case - size of the page). So there is a missing $key variable.
This class supports extra parameters in the callbacks ($moreimfo in my case). BUT as I understand the data passing to each callback will be always the same.
$result object containing the original url info ($result->info['url']). So I COULD use it to find needed array element. However this looks too inefficient in case the size of an array will be big enough.
I think that I should find how to pass an array member key information for EACH callback execution. Is it possible without modifying the original class?
If you use the url as key in the $items array the solution could be something like
<?php
$items = [
'url0'=>array('url' => 'url0'),
'url1'=>array('url' => 'url1'),
'url2'=>array('url' => 'url2'),
'url3'=>array('url' => 'url3'),
];
$curl = new Zebra_cURL();
$curl->get(
array_keys($items),
function($result) use (&$items) {
$key = $result->info['url'];
$items[$key]['size'] = strlen($result->body);
}
);
using an anymous function that "Imports" the $items array via reference.
While it doesn't solve the original problem of passing a reference to the according array element to the callback, the following should be very fast (as noted in the comments, PHP Arrays are implemented using a hashtable).
$items = array(
0=>array('url' => 'url0'),
1=>array('url' => 'url1'),
2=>array('url' => 'url2'),
3=>array('url' => 'url3'),
);
$lookup=array();
foreach($lookup as $k=>$v) {
$lookup[$v['url']]=$k;
}
$curl = new Zebra_cURL();
$curl->get(array_column($urls,'url'),'scan_item',$moreimfo);
function scan_item($result,$moreimfo){
global $lookup,$items;
$items[$lookup[$result->info['url']]]['size'] = strlen($result->body);
}
Probably you may consider using an OOP-approach, with the callback as a method, then the global-izing of the arrays shouldn't be necessary if you use $this->anyMember
I am using CakePHP 2.4
I have a url for e.g. /sent?note=123&test=abc
I want to remove the note parameter while giving me the rest of the url back. i.e.
/sent?test=abc
I have a piece of code that works but only for query parameters. I would like to find out how to improve my code so that it works with:
named parameters
passed parameters
hashtag
E.g.
/sent/name1:value1?note=123&test=abc#top
This is the code I have written so far. https://github.com/simkimsia/UtilityComponents/blob/master/Controller/Component/RequestExtrasHandlerComponent.php#L79
UPDATE PART III:
Let me illustrate with more examples to demonstrate what I mean by a more generic answer.
The more generic answer should assume no prior knowledge about the url patterns.
Assuming given this url
/sent/name1:value1?note=123&test=abc
I want to get rid of only the query parameter note and get back
/sent/name1:value1?test=abc
The more generic solution should work to give me back this url.
Another example. This time to get rid of named parameters.
Assuming given this url again
/sent/name1:value1?note=123&test=abc
I want to get rid of name1 and get back:
/sent?note=123&test=abc
Once again, the more generic solution should be able to accomplish this as well.
UPDATE PART II:
I am looking for a more generic answer. Assuming the web app does not know the url is called sent. You also do not know if the query parameters contain the word note or test. How do I still accomplish the above?
I want to be able to use the same code for any actions. That way, I can package it into a Component to be reused easily.
UPDATE PART I:
I understand that hashtag will not be passed to PHP. So please ignore that.
Clues on how to get the values from the hashtag:
https://stackoverflow.com/a/7817134/80353
https://stackoverflow.com/a/940996/80353
What about using mod_rewrite ?
You can handle your URLS in an other way :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/sent/name:(.*)?note=(.*)&test=([az-AZ])(#(.*))$ /sent/name:$1/note:$2/test:$3$4
</IfModule>
I'm not sure about the regex, but this may pass variables to cakePHP in a clean way (but I haven't tested it, though)
[EDIT]
But if you want to work without knowing urls patterns, then you can use the $this->request array : with an URL like
action/id:10/test:sample?sothertest=othersample&lorem=ipsum
I can get all the arguments using this in my controller :
// In your controller's method
$arguments= array_merge_recursive($this->request->named,$this->request->query);
Then, $arguments will be an array containing both named and passed params :
array(
'id' => '10',
'test' => 'sample',
'sothertest' => 'othersample',
'lorem' => 'ipsum'
)
Is it better ?
[EDIT 2]
If you know which parameter you have to get rid of, and directly redirect to the new URL, this should work:
action/id:10/test:sample?knownParam=value&lorem=ipsum
or with
action/id:10/knownParam:value?othertest=othersample&lorem=ipsum
In your controller/appController action:
// Name of the known param
$knownParam = 'knownParam';
// Arguments
$arguments = array_merge_recursive($this->request->named, $this->request->query);
if (key_exists($knownParam, $arguments)) {
// Unset in named params:
unset($arguments[$knownParam]);
// Creating url:
$url = array(
'admin' => $this->request->params['prefix'],
'plugin' => $this->request->params['plugin'],
'controller' => $this->request->params['controller'],
'action' => $this->request->params['action']
);
// Adding args
foreach ($arguments as $k => $v) {
$url[$k] = $v;
}
// Redirect
$this->redirect($url);
}
This will redirect both urls to
action/id:10/param1:value1/param2:value2
without the "know param"...
Let us say you have created the following routes:
Router::connect('/projects/:id/quotations/:quotation_id/*',
array(
'controller' => 'quotations',
'action' => 'get_all_by_project', "[method]" => "GET"),
array(
'pass' => array('id', 'quotation_id'),
'id' => '[0-9]+',
'quotation_id' => '[0-9]+'
),
array(
'named' => array(
'name1',
'name2',
'name3'
)
)
);
In this route:
Passed parameters will be the compulsory parameters id and quotation_id obeying the order as the first and second passed parameter
Named parameters will be the optional parameters name1, name2, and name3.
Query parameters will, of course, be optional as well and depend on what you actually have in the url.
you need the asterisk at the end so that the named parameters can pass through
Let us assume the following pretty url and the ugly url of the same action:
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (ugly)
First part of the answer:
Let us consider only the scenario of removing the query parameter note.
We should get back
/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?test=123 (ugly)
The following Component method will work. I have tested it on both the ugly and pretty urls.
public function removeQueryParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$validQueryParameters = array();
foreach($query as $param=>$value) {
if (!in_array($param, $parameters)) {
$validQueryParameters[$param] = $value;
}
}
$queryString = $this->_reconstructQueryString($validQueryParameters);
return $here . $queryString;
}
protected function _reconstructQueryString($queryParameters = array()) {
$queryString = '';
foreach($queryParameters as $param => $value) {
$queryString .= $param . '=' . $value . '&';
}
if (strlen($queryString) > 0) {
$queryString = substr($queryString, 0, strlen($queryString) - 1);
$queryString = '?' . $queryString;
}
return $queryString;
}
This is how you call the Component method.
$newUrl = $this->RequestExtrasHandler->removeQueryParameters(array('note'));
RequestExtrasHandler is the name of Component I wrote that has the above method.
Second part of the answer:
Let us consider only the scenario of removing the named parameter name2.
We should get back
/projects/1/quotations/23/name3:value3/name1:value1?test=123 (pretty)
/quotations/get_all_by_project/1/23/name3:value3/name1:value1?test=123 (ugly)
The following Component method will work. I have tested it on both the ugly and pretty urls.
public function removeNamedParameters($parameters, $here = '') {
if (empty($here)) {
$here = $this->controller->request->here;
}
$query = $this->controller->request->query;
$named = $this->controller->request->params['named'];
$newHere = $here;
foreach($named as $param=>$value) {
if (in_array($param, $parameters)) {
$namedString = $param . ':' . $value;
$newHere = str_replace($namedString, "", $newHere);
}
}
$queryString = $this->_reconstructQueryString($query);
return $newHere . $queryString;
}
This is how you call the Component method.
$newUrl = $this->RequestExtrasHandler->removeNamedParameters(array('name2'));
RequestExtrasHandler is the name of Component I wrote that has the above method.
Third part of the answer:
After I realized that passed parameters are compulsory, I found that there is no real business need to remove passed parameters if at all.
Another problem is that unlike named parameters and query parameters, passed parameters tend not to have the keys present in the $this->controller->request->params['pass']
$this->controller->request->params['pass'] is usually in the form of a numerically indexed array.
Hence, there is huge challenge to take out the correct passed parameters.
Because of that, I will not create any method to remove passed parameters.
Check out the code here in details:
https://github.com/simkimsia/UtilityComponents/blob/d044da690c7b83c72a50ab97bfa1843c14355507/Controller/Component/RequestExtrasHandlerComponent.php#L89
maybe simple php functions can do what you want
$url = '/sent?note=123&test=abc'; //for example
$unwanted_string = substr($url, 0,strrpos($url,'&') + 1);
$unwanted_string = str_replace('/sent?', '', $unwanted_string);
$url = str_replace($unwanted_string, '', $url);