Paginate data returned by facebook graph API - php

I am using PHP SDK 5.0. I have been able to pull posts from my FB page and display it on my site with this code below. I need help to achieve pagination of the results returned by this code.
session_start();
require_once __DIR__. '/Facebook/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => 'xxxxxxxxxxxx',
'app_secret' => 'xxxxxxxxxxxx',
'default_graph_version' => 'v2.4',
'default_access_token' => 'xxxxxxxxxxxx',
]);
$request = $fb->request('GET','/500px/feed/', array('fields' => 'created_time,message', 'limit' => '3',));
try {
$response = $fb->getClient()->sendRequest($request);
$data_array = $response->getDecodedBody();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
Facebook returns the next and previous links with every feed-result, like in the example below. How can I get pagination using those ? Or is there a better alternative.
[data] => Array
(
[0] => Array
(
[created_time] => 2015-09-23T17:00:53+0000
[message] => some message pulled from the post
[id] => 57284451149_10152992926641150
)
)
[paging] => Array
(
[previous] => https://graph.facebook.com/v2.4/57284451149/feed?fields=created_time,message&limit=1&since=1443027653&access_token=xxxxxxxxxxx&__paging_token=enc_xxxxxxxxxxxx&__previous=1
[next] => https://graph.facebook.com/v2.4/57284451149/feed?fields=created_time,message&limit=1&access_token=xxxxxxxxxxx&until=1443027653&__paging_token=enc_xxxxxxxxxxxx
)
I am still learning PHP, and at this point I have no clue how to go beyond this. Ideally there would be three results per page and the results would display on the same page. If not a solution, I would really appreciate pseudo codes or helpful suggestions or a roadmap which would help me do it myself.
TEMP SOLUTION - I could be on wrong track, but here is what I have done as a temporary solution. Seems like facebook does all the work, eg offset etc and provides us a calculated url, and all we need to do is work with the provided urls.
//set your url parameters here
function fetchUrl($url){
if(is_callable('curl_init')){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$feedData = curl_exec($ch);
curl_close($ch);
}
return $feedData;
}
if(isset($_POST['nextLink'])){
$url = $_POST['nextLink'];
} elseif(isset($_POST['prevLink'])){
$url = $_POST['prevLink'];
} else {
$url = 'https://graph.facebook.com/v2.4/'.$pageID.'/feed?fields='.$fields.'&limit='.$limit.'&access_token='.$accessToken;
}
$json_object = fetchUrl($url);
$FBdata = json_decode($json_object, true);
//parse the received data in your desired format
//display data
//get the next link, construct and set a url
$nextLink = $FBdata['paging']['next'];
$prevLink = $FBdata['paging']['previous'];
//Your next and previous form here
I would use http GET method but i don't prefer ugly long urls so I am using POST method to get next and previous urls. Note that I using cURL instead of PHP SDK. This is a simplified example and needs more work.
I am not writing this as an answer because this is just a woraround not a solution, I am still looking to do it using PHP SDK. I just could not gt hold of SDK generated url. Any inputs ?

Related

New Instagram API requesting for tagged media by user id

I am trying to create a website like Instagram where user's media are retrieved according to a specific hashtag, so every user has his/her own web page.
according to new Instagram API I'm struggling to request media using access_tokens , I have this code below but it is not working at all, logically it is correct
// function to print out images
function printImages($userID){
$url = 'https://api.instagram.com/v1/users/'.$userID.'/media/recent/? access_token='.$_GET['code'].'&count=5';
$instagramInfo = connectToInstagram($url);
$results = json_decode($instagramInfo, true);
//parse through the images one by one
foreach($results['data'] as $items){
$image_url = $items['images']['low_resolution']['url']; // goining through all result and give back url of picture to save it on the php serve.
echo '<img src" '. $image_url .' "/><br/>';
}
and here is my full code in case
<?php
//config for user PHP server
set_time_limit(0);
ini_set('default_socket_timeout', 300);
session_start();
//Make constraints using define.
define('clientID', 'my client id I have removed it');
define('clientSecret', 'my secret I have removed it');
define('redirectURI', 'my url removed too for the question');
define('ImageDirectory', 'pics/');
// function that is going to connect to instagram.
function connectToInstagram($url){
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2,
));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
if (isset($_GET['code'])){
$code = ($_GET['code']);
$url = 'https://api.instagram.com/oauth/access_token';
$access_token_settings = array ('client_id' => clientID,
'client_secret' => clientSecret,
'grant_type' => 'authorization_code',
'redirect_uri' => redirectURI,
'code' => $code
);
//function to get userID cause username doesn't allow uss to get pictures
function getUserID($userName){
$url = 'https://api.instagram.com/v1/users/search?q='.$userName.'&access_token='.$_GET['code'];
$instagramInfo = connectToInstagram($url);
$results = json_decode($instagramInfo, true);
echo $results['data']['0']['id'];
}
// function to print out images
function printImages($userID){
$url = 'https://api.instagram.com/v1/users/'.$userID.'/media/recent/?access_token='.$_GET['code'].'&count=5';
$instagramInfo = connectToInstagram($url);
$results = json_decode($instagramInfo, true);
//parse through the images one by one
foreach($results['data'] as $items){
$image_url = $items['images']['low_resolution']['url']; // goining through all result and give back url of picture to save it on the php serve.
echo '<img src" '. $image_url .' "/><br/>';
}
}
//cURL is what we use in PHP , it's a library calls to other API's.
$curl = curl_init($url); //setting a cURL session and we put in $url because that's where we are getting the data from
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $access_token_settings); // setting the POSTFIELDS to the array setup that we created above.
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // setting it equal to 1 because we are getting strings back
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // but in live work-production we want to set this to true for more security
$result = curl_exec($curl);
curl_close();
$results = json_decode($result, true);
$use
could anyone tell me what should I do to use access_tokens for every user using my app ?
Have you approved permission of your app from instagram?
Instagram has changed their api policy on 2016/6/1.

I upgraded to FQL to Graph API - am I using it correctly?

I used the FQL until a few days ago to retrieve Facebook data, but I noticed that it will be discontinued in about 1 year so I upgraded to Graph API. But am I using it correctly? Will this method work still next year? I am still using a
facebook.php,
base_facebook.php and
fb_ca_chain_bundle.crt
from 2011 but then again I only need these functions.
Here's my code, thanks for any advice you can give me :)
function get_content($URL){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URL);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$access_token = $facebook->getAccessToken();
$data = get_content("https://graph.facebook.com/" . $facebook_id . "/?fields=name,first_name,last_name,email&access_token=".$access_token);
$data_array = json_decode($data, true);
$new_array = array(
"uid" => $data_array['id'],
"name" => $data_array['name'],
"first_name" => $data_array['first_name'],
"last_name" => $data_array['last_name'],
"email" => $data_array['email']
);
That looks perfectly correct!
The only improvement to that code would be to add the API version number to the call.
So, use https://graph.facebook.com/v2.4/
$data = get_content("https://graph.facebook.com/v2.4/**" . $facebook_id . "/?fields=name,first_name,last_name,email&access_token=".$access_token);
That way, you'll not be affected by any changes until at least July 2017!
You might want to catch any connection or HTTP errors returned.
Some of the HTTP errors are documented here.
You can use the Graph API explorer for making test API calls and verifying your requests.

Scrape business listing content from google search

I am developing a simple PHP app which takes
business name,
business address
and business phone from user and then checks if that business is listed in Google or not and
Also compares the business name, address and phone returned by Google against the search terms.
The result I want to display whether the information found in Google is accurate or whether something is different or missing. Something similar as this site does
What I have tried:
I have tried to scrape page with phpQuery library but it does not include that part(which is circled in image below).
$buss_name = $_GET['business_name'];
$link = "https://www.google.com/search?q=" . urlencode($buss_name) . "&rct=j";
$resp_html = file_get_contents($link, false);
$resp_html = phpQuery::newDocumentHTML($resp_html);
echo $resp_html;
echo pq("div.kno-ecr-pt.kno-fb-ctx._hdf",$resp_html)->text();
Reason is that it is loaded via some sort of AJAX call.
I also tried this web service by google
http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=don%20jayne%20&%20assoc
But this also do not include that part I require.
Long story short >>>
Please tell me is there any API or whatever is available which checks for a business listed on Google or not?
probably you wont need this anymore but I will reply your post just for future reference.
One of the ways to check if a business is on google or not, is to check the google places api (documentation). You can preform a search and then check the results for the business you are looking for. Something like this:
$params = array(
'query' => 'mindseo',
'key' => "XXXXXXXXXXXXXXXXXXX");
$service_url = 'https://maps.googleapis.com/maps/api/place/textsearch/json';
//do the request
$placesSearch = request( $service_url, $params );
//print the result
print_r($placesSearch);
//loop the results
if ( count( $placesSearch['results'] ) >= 1 ) {
$params = array(
'placeid' => $placesSearch['results'][0]['place_id'],
'key' => "AIzaSyAc73-uGCLLIuN3Bb2idOwRbLBzoaTmPHI");
$service_url = 'https://maps.googleapis.com/maps/api/place/details/json';
$placeData = request( $service_url, $params );
//echo the place data
echo '//Place ID#'.$params['placeid'].' DATA -----------------------';
print_r($placeData);
}
//function to make the request
function request( $googleApiUrl, $params) {
$dataOut = array();
$url = $googleApiUrl . '?' . http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$dataOut = json_decode(curl_exec($ch), true);
curl_close($ch);
return $dataOut;
}

Accessing Picasa Web API using PHP

Does anyone here know about how to access Google Photos API now that Google has started using OAuth2? The PHP client library in their developer website is now obsolete and does not work!
I have used OAuth to work with Google Drive but Photos does not work! :(
First I use Google_Client to successfully authenticate user. Then in the redirect page I am trying following:
require_once("Google/Client.php");
//set up path for Zend GData, because Google Documentation uses that lib
$clientLibraryPath = '/path/to/ZendGData/library';
$oldPath = set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Photos');
try
{
$authCode = $_GET['code']; //authorization code returned from google
//next create google OAuth Client object and validate...
$webAuth= new Google_Client();
$webAuth->setClientId($clientId);
$webAuth->setClientSecret($clientSecret);
$webAuth->authenticate($authCode); //this authenticate() works fine...
//now my problem is HOW do I tie this to GData API for Picasa :(
//I tried following but it throws error
//*Token invalid - Invalid token: Request token used when not allowed.*
$client = Zend_Gdata_AuthSub::getHttpClient($authCode);
$gp = new Zend_Gdata_Photos($client, "GData:2.0");
$userFeed = $gp->getUserFeed("default");
I have also tried a bunch of third party libraries, tried hooking up my $webAuth into Zend_GData_Photos in everywhich way I can try...I even tried raw curl calls, but nothing is working!
Can anyone help me please? I am at my wits end....I can't believe Google left a fully functional library (PicasaWeb PHP API Ver 1.0) hanging like that when they updated their authentication to OAuth.
I had the same problem but finally I got it working again.
The best thing is, that you do not need any client library to get access to private photos.
I have spent two days trying to make it work with 'service account' but with no luck.
Then I have found this page:
https://holtstrom.com/michael/blog/post/522/Google-OAuth2-with-PicasaWeb.html
which helped me to achieve what I wanted.
It is pretty long article but it should not take to long to sort it out and get it working. Basically you will need to use 'OAuth 2.0 client ID' instead of 'Service account' in your project at https://console.developers.google.com
Within your 'OAuth 2.0 client ID' you will have following information:
Client ID (something-random.apps.googleusercontent.com)
Client Secret (random-client-secret)
Name (www.yoursite.com)
Authorized JavaScript origins (https://www.yoursite.com)
Authorized redirect URIs (https://www.yoursite.com/oauth2.php)
You will use this data in your verification process.
Before you begin, you will need to complete OAuth Consent Screen.
In that tutorial there is a note to store these tokens in DB, but in this case I'd rather suggest to display them directly in web page. This is much easier.
There is suggestion to use https rather than http but it should work on both.
I have used https for my application.
This is shorter version of the article from the link above.
Create oauth2.php file and place it on https://www.yoursite.com/oauth2.php
<?php
if (isset($_GET['code']))
{
$clientId = 'your-client-id.apps.googleusercontent.com';
$clientSecret = 'your-client-secret';
$referer = 'https://www.yoursite.com/oauth2.php';
$postBody = 'code='.urlencode($_GET['code'])
.'&grant_type=authorization_code'
.'&redirect_uri='.urlencode($referer)
.'&client_id='.urlencode($clientId)
.'&client_secret='.urlencode($clientSecret);
$curl = curl_init();
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'POST'
, CURLOPT_URL => 'https://accounts.google.com/o/oauth2/token'
, CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
, 'Content-Length: '.strlen($postBody)
, 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
)
, CURLOPT_POSTFIELDS => $postBody
, CURLOPT_REFERER => $referer
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
, CURLOPT_TIMEOUT => 15 // max seconds to wait
, CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
, CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
, CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
, CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
echo($response);
echo($http_code);
}
else { echo 'Code was not provided.'; }
?>
Prepare and visit this link:
https://accounts.google.com/o/oauth2/auth?scope=https://picasaweb.google.com/data/&response_type=code&access_type=offline&redirect_uri=https://www.yoursite.com/oauth2.php&approval_prompt=force&client_id=your-client-id.googleusercontent.com
fields to adjust: redirect_uri and client_id
After visiting link from step 2. you should see your consent screen where you will have to approve it and you will be redirected to your oauth.php page but this time with code parameter:
https://www.yoursite.com/oauth2.php?code=some-random-code
'code' parameter will be then sent by oauth.php to: https://accounts.google.com/o/oauth2/token
which will return(print) json formatted data containing: access_token, token_type, expires_in and refresh_token.
Http Response code should be 200.
Access_token will be the one to use to get privet albums data.
Create index.php with content:
<?php
$curl = curl_init();
$url = 'https://picasaweb.google.com/data/entry/api/user/default';
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'GET'
, CURLOPT_URL => $url
, CURLOPT_HTTPHEADER => array( 'GData-Version: 2'
, 'Authorization: Bearer '.'your-access-token' )
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl,CURLINFO_HTTP_CODE);
curl_close($curl);
echo($response . '<br/>');
echo($http_code);
?>
After running script from step 5. you should receive your default feed from picasaweb API. When I say 'default' it ,eans default when you are logged that is with private albums. From now on, you should be able to use that approach to get access to your picasa photo library.
Access token will expire after 3600 seconds (1 hour) so you will have to get new one. this can be achieved with script like this one below:
$clientId = 'your-client-id.apps.googleusercontent.com';
$clientSecret = 'your-client-secret';
$referer = 'https://www.yoursite.com/oauth2.php';
$refreshToken = 'your-refresh-token';
$postBody = 'client_id='.urlencode($clientId)
.'&client_secret='.urlencode($clientSecret)
.'&refresh_token='.urlencode($refreshToken)
.'&grant_type=refresh_token';
$curl = curl_init();
curl_setopt_array( $curl,
array( CURLOPT_CUSTOMREQUEST => 'POST'
, CURLOPT_URL => 'https://www.googleapis.com/oauth2/v3/token'
, CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
, 'Content-Length: '.strlen($postBody)
, 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
)
, CURLOPT_POSTFIELDS => $postBody
, CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
, CURLOPT_TIMEOUT => 15 // max seconds to wait
, CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
, CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
, CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
, CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
) );
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if (strlen($response) < 1)
{ echo('fail 01'); }
$NOW = time();
$responseDecoded = json_decode($response, true); // convert returned objects into associative arrays
$expires = $NOW - 60 + intval($responseDecoded['expires_in']);
if ( empty($responseDecoded['access_token'])
|| $expires <= $NOW )
{ echo('fail 02'); }
echo($http_code . '<br/>');
echo($response . '<br/>');
echo($expires . '<br/>');
?>
You can run code from step 7. in separate script manually, just to get new access-token for another 3600 seconds, but normally you would want to have it automated so when access_token expires, you automatically ask for new one using a call with refresh_token from step 4.
Ufff. That is is. I hope you'll get this up and running.

Posting to Tumblr with php & Tumblr API

I am trying to post messages automatically to my Tumblr Blog (which will run daily via Cron)
I am using the Official Tumblr PHP library here:
https://github.com/tumblr/tumblr.php
And using the Authentication method detailed here :
https://github.com/tumblr/tumblr.php/wiki/Authentication
(or parts of this, as I don't need user input!)
I have the below code
require_once('vendor/autoload.php');
// some variables that will be pretttty useful
$consumerKey = 'MY-CONSUMER-KEY';
$consumerSecret = 'MY-CONSUMER-SECRET';
$client = new Tumblr\API\Client($consumerKey, $consumerSecret);
$requestHandler = $client->getRequestHandler();
$blogName = 'MY-BLOG-NAME';
$requestHandler->setBaseUrl('https://www.tumblr.com/');
// start the old gal up
$resp = $requestHandler->request('POST', 'oauth/request_token', array());
// get the oauth_token
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// set the token
$client->setToken($data['oauth_token'], $data['oauth_token_secret']);
// change the baseURL so that we can use the desired Methods
$client->getRequestHandler()->setBaseUrl('http://api.tumblr.com');
// build the $postData into an array
$postData = array('title' => 'test title', 'body' => 'test body');
// call the creatPost function to post the $postData
$client->createPost($blogName, $postData);
However, this gives me the following error:
Fatal error: Uncaught Tumblr\API\RequestException: [401]: Not
Authorized thrown in
/home///*/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php
on line 426
I can retrieve blog posts and other data fine with (example):
echo '<pre>';
print_r( $client->getBlogPosts($blogName, $options = null) );
echo '</pre>';
So it seems it is just making a post that I cant manage.
In all honesty, I don't really understand the OAuth Authentication, so am using code that more worthy coders have kindly provided free :-)
I assume I am OK to have edited out parts of the https://github.com/tumblr/tumblr.php/wiki/Authentication as I don't need user input as this is just going to be code ran directly from my server (via Cron)
I have spent days looking around the internet for some answers (have gotten a little further), but am totally stuck on this one...
Any advice is much appreciated!
It looks like the parts that you removed in the code pertained to a portion of the OAuth process that was necessary for the desired action.
// exchange the verifier for the keys
You might try running the Authentication Example itself and removing the parts of the code that you've removed until it no longer works. This will narrow down what's causing the issue. I'm not very familiar with OAuth personally, but this looks as though it would be apart of the problem as one of the main portions you took out was surrounding the OAuth process exchanging the verifier for the OAuth keys.
function upload_content(){
// Authorization info
$tumblr_email = 'email-address#host.com';
$tumblr_password = 'secret';
// Data for new record
$post_type = 'text';
$post_title = 'Host';
$post_body = 'This is the body of the host.';
// 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('api.tumblr.com/v2/blog/gurjotsinghmaan.tumblr.com/post');
//api.tumblr.com/v2/blog/{base-hostname}/post
//http://www.tumblr.com/api/write
//http://api.tumblr.com/v2/blog/{base-hostname}/posts/text?api_key={}
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";
}
}
https://howtodofor.com/how-to-delete-tumblr-account/

Categories