I'm trying to get the Facebook user (current user) an U´m using the code:
$app_id = "xxx";
$app_secret = "yyy";
//** Get user information
//Create our application instance.
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
));
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');....
// The $user_profile = $facebook->api('/me'); line throw an exception:
'message' => string 'An active access token must be used to query
'information about the current user.' (length=80)
'type' => string 'OAuthException' (length=14)
'code' => int 2500
Why?
It seems you did not go through the OAuth 2.0 authentication/authorization process as described at Authentication.
There are some examples there explaining how to do this. I am also using the PHP SDK but I chose to do the authentication through JavaScript on the client side which was easier for me. However, both approaches are explained in the documentation.
Updated: I use this code which is a combination of PHP and JavaScript, which works great for me. The only thing that isn't handled correctly here (AFAIK) is when a user reaches the application when he is not logged in to Facebook, that is, he reaches the application directly through the URL and not through Facebook. In that case a blank page is shown instead of a notification and a login button or something.
Anyway, this is my index.php in which I pass vars from my config.inc.php such as the success (application main page) and failure pages (user didn't grant perms) to JavaScript:
<?php
require 'include/config.inc.php';
//Check whether Facebook OAuth mechanism called back to this script with access_token or error
if (isset($_GET['expires_in']) && $_GET['expires_in']>0)
{
header('Location: '.$appname_canvasPage.$appname_successPage);
exit;
}
else if (isset($_GET['error']))
{
//echo 'querystr: '.$_SERVER['QUERY_STRING'];
header('Location: '.$appname_canvasPage.$appname_failurePage);
exit;
}
else
{
require 'include/header_metadata.inc.html';
?>
</head>
<body>
<div id="fb-root"></div>
<script>
var appname_canvasURI = '<?php echo $appname_canvasURI; ?>';
var appname_canvasPage = '<?php echo $appname_canvasPage; ?>';
var appname_successPage = '<?php echo $appname_successPage; ?>';
var appname_failurePage = '<?php echo $appname_failurePage; ?>';
var appname_fbPerms = '<?php echo $appname_fbPerms; ?>';
var appname_appid= '<?php echo $appname_appid; ?>';
window.fbAsyncInit = function()
{
FB.init({
appId : appname_appid, // App ID
channelUrl : appname_canvasPage+'/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
// Additional initialization code here
FB.getLoginStatus(function(response)
{
//console.log('getLoginStatus response: ',response);
if (response.authResponse)
{
//user is already logged in and connected
facebookCheckPerms(); // ensure all requires perms are available and if not request them
}
else
{
//app is not authorized or user is logged out
facebookOAuthRedirect();
}
});
};
// Load the SDK Asynchronously
(function()
{
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
//e.src = "http://static.ak.fbcdn.net/connect/en_US/core.debug.js";
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
function facebookCheckPerms()
{
var hasReqPerms=true;
FB.api(
{
method: 'fql.query',
query: 'SELECT '+appname_fbPerms+' FROM permissions WHERE uid=me()'
},
function(response)
{
for(var key in response[0])
{
if(response[0][key]==0)
{
hasReqPerms=false;
}
}
if (hasReqPerms==false)
{
// user does not have required permissions, do OAuth 2.0 redirect to get permissions
facebookOAuthRedirect();
}
else
{
// user has required permissions, start the app.
//console.log('checkperms: user has required permissions, start the app');
top.location.href = appname_canvasPage+appname_successPage;
}
});
}
function facebookOAuthRedirect()
{
var redirectURL = 'https://www.facebook.com/dialog/oauth/?client_id='+appname_appid+'&scope='+appname_fbPerms+'&redirect_uri='+encodeURIComponent(appname_canvasURI)+'&response_type=token';
//console.log('redirectURL: '+redirectURL);
top.location.href = redirectURL;
}
</script>
<?php
}
?>
</body>
</html>
Related
I'm implenting my fb app and it's connected to its own fb fanpage. I need to get a users info like username, id etc but when I click on my "Facebook authenticate" link, I end up going to a blank white page?
You can view my code in here: http://codepad.org/f0Tuh63v
error_reporting(E_ALL);
ini_set('display_errors', true);
require 'facebook/facebook.php';
$facebook = new Facebook(array(
'appId' => '1',
'secret' => '2',
));
// See if there is a user from a cookie
$user = $facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
print_r($user_profile);
} catch (FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
}
else{
$loginUrl = $facebook->getLoginUrl(
array('scope' => 'user_about_me,user_birthday,email,publish_actions,offline_access,user_hometown,user_location',
'redirect_uri' => "https://domain.net/intro.php"
)
); // end of array
}
?>
<!DOCTYPE html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<body>
<?php if ($user) { ?>
Your user profile is
<pre>
<?php print htmlspecialchars(print_r($user_profile, true)) ?>
</pre>
<?php } else { ?>
Facebook authenticate
<?php } ?>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: '<?php echo $facebook->getAppID() ?>',
cookie: true,
xfbml: true,
oauth: true,
status: true
});
FB.Event.subscribe('auth.login', function(response) {
//window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
//window.location.reload();
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
</body>
</html>
It's also here http://codepad.org/f0Tuh63v
What am I doing wrong?
Also is there a way to get the FB user id without using phpsdk or the js sdk? Or do I have to use these plugins?
I cannot see what's wrong with your code. But, If you are using Javascript, I can tell you an alternative for getting authenticated and then getting the info you require.
I used the following code behind my button, which authenticated my Facebook app and then redirected the user to my website. It worked for me.
<a class="fb-login-button" align="center" target="_blank" href="https://www.facebook.com/dialog/oauth?client_id=CLIENT_ID&response_type=token&scope=PERMISSION_1,PERMISSION_2&redirect_uri=YOUR_WEBSITE"> TEXT </a>
Then I extracted the token which was returned in the redirected URL.
var url_t; // Get the redirected URL.
access_token = url_t.split('=')[1].split('&')[0];
Then using the access token I sent the HTTP request for getting the required data. I used GRAPH API provided by facebook. For eg: For getting the first name of the user:
var xhr = new XMLHttpRequest();
var f_url_new = "https://graph.facebook.com/fql?q=SELECT%20name%20FROM%20user%20WHERE%20uid%20=%20me()&access_token=" + access_token;
xhr.open("GET", f_url_new , true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
obj1 = JSON.parse(xhr.responseText);
var str = obj1.data[0].name.toString();
var n=str.split(" ");
document.getElementById("name").innerText = n[0];
}
}
xhr.send();
Hope it gives you some idea with regards to the alternatives. This is not the correct answer to your question, but can help in the thought process.
I have searched the web high and low and can´t figure out the problem I´m facing. I have a page tab application on Facebook, the user likes the page to start and then he can answer some questions, I can get the facebook connect to function but I can not get the user id and save it to the database.
I have this in my index page
<? include('db.php');
include_once("config.php");
// Finnur út hvaða spurninga sett á að nota
$sp_set = 1;
require_once 'facebook-php-sdk/src/facebook.php';
// Create our Application instance.
$facebook = new Facebook( array('appId' => '289393321124676',
'secret' => 'd47b7871e0a7fb475db6e2a643f675ed', 'cookie' => true, ));
$signed_request = $facebook -> getSignedRequest();
$like_status = $signed_request["page"]["liked"];
$user = $facebook->getUser();
//If the page is liked then display full app.
?>
And the user id is always null, when the user submits the questions everything is saved to the database but user is 0.
Please help
$user = $facebook->getUser();
This will not get you any user id, unless the user has connected to your app first.
So you have to implement either the client-side or the server-side Auth flow in your app. https://developers.facebook.com/docs/authentication/pagetab/
Try this example:
<?php
$secret = '********************************'; // App Secret
$app_id = '***************'; // App ID
$page_url = 'https://www.facebook.com/*******'; // FB fan page URL, where the application tab is installed
require 'src/facebook.php';
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $secret,
));
// Get User ID
$user = $facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
// Login url will be needed depending on current user state.
if (!$user) {
$loginUrl = $facebook->getLoginUrl(array('redirect_uri' => $page_url.'?sk=app_'.$app_id));
}
$signed_request = $facebook->getSignedRequest();
?><!DOCTYPE html>
<html>
<body><pre>
<?php
if (!$user): // isn't authorized
echo 'Authorize app';
else:
if ($signed_request['page']['liked']): // likes
echo 'The page is liked by user with id '.$signed_request['user_id'];
else:
echo 'The page is <strong>NOT</strong> liked by user with id '.$signed_request['user_id'];
endif;
endif;
?>
</pre></body>
</html>
I was having a similar issue. I ended up using the FB JS-SDK to invoke the oAuth dialog to allow the user to connect to my app and grant me permissions. At that point you can access their user id and whatever other info they're granted you permission for.
Add the following code to your window.fbAsyncInit call:
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
Source: https://developers.facebook.com/docs/reference/javascript/FB.login/
I want to store the full access token in my site. Is it possible to use the Facebook API and login with crontab every hour? If I can, can you point me to the documentation that talks about this?
require '../src/facebook.php';
$facebook = new Facebook(array(
'appId' => '13XXXXXXXXXX',
'secret' => 'fbXXXXXXXXXXXXXXXXXXXXXXXXX',
));
$user = $facebook->getUser();
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
$access_token = $facebook->getAccessToken();
} else {
$loginUrl = $facebook->getLoginUrl();
}
echo $access_token;
UPDATE:
My purpose is to provide a search box for the public so that everyone can search facebook without requiring a login.
I have tried
https://graph.facebook.com/search?q=mark&type=user&access_token=1xxxxxxxxxxxxxx|xxxxxxxxxxxxxxx&scope=publish_stream,offline_access,user_status,read_stream
But it returns an error "message": "A user access token is required to request this resource."
And I see someone has developed a site that does facebook search at http://www.fbsearch.us/q/mark/5
How does that work?
As an answer to your third revision...
I've accomplished saving the user state by
a) saving the last url into the user session context
b) directing the login success form to a server script that will save the credentials into the same session context and then redirects the browser to the last url or default welcome page.
The redirect url is attached to the oauth login dialog:
$params = array(
'scope' => 'read_stream, friends_likes',
'redirect_uri' => 'https://www.myapp.com/post_login_page'
);
$loginUrl = $facebook->getLoginUrl($params);
After the user authorizes your app, FB redirects the user back to the redirect_uri with the access token in the URI fragment:
https://www.myapp.com/post_login_page?access_token=...
excerpts from facebook-getLoginUrl and Authentication
You may have to append YOUR_URL with the session id if it doesn't translate directly (likely because of crossing http/https/http).
This way the user sees the least transition from the facebook login form an authenticated app page and can ignore the actual credentials.
Be careful, methods like this may be compromised by XSS and other OWASP Top 10 Vulnerabilities
<?php
if(sizeof($_GET['q']) > 0)
{
$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET";
require_once('facebook_app/facebook.php');
$facebook = new Facebook(array(
'appId' => $app_id ,
'secret' => $app_secret,
));
$fb_access_token = $facebook->getAccessToken();
$ch = curl_init("https://graph.facebook.com/search?q='{$_GET['q']}'&type=user&access_token=$fb_access_token");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 80000);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
$decoded = json_decode($data);
echo '<pre>';
print_r($decoded->data);
echo '</pre>';
}
}
else
{
?>
<script src="js/jquery-1.7.1.min.js"></script>
<script>
$('document').ready(function(){
$('#submit').click(function(event) {
event.preventDefault();
var sQuery = $('#sQuery').val();
$.get("fbsearch.php", {q: sQuery}, function(results)
{
console.log(results);
$('div#results').fadeIn(function() {
$('div#results').html(results);
});
});
return false;
});
});
</script>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<fb:login-button show-faces="false" width="200" max-rows="1"></fb:login-button>
<input type="text" id="sQuery">
<button id="submit">Search</button>
<div id="results" style="display:none;"></div>
<?php
}?>
A user access token is required to request this resource
Currently you're sending application access token (APP_ID|SECRET_TOKEN) which is not enough. To make sure you can search, you have to get user access token (for example yours) and search through that one.
So what you need is:
Go to this URL
https://www.facebook.com/dialog/oauth?scope=publish_stream,offline_access,user_status,read_stream&client_id=YOUR_APP_ID&redirect_uri=YOUR_URL
Approve all permissions
Facebook will redirect you back to your website with code parameter
Send that code to
https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=APP_SECRET&code=CODE_YOU_GOT
here you got an access token. This access token will be used for all actions like crontab execution.
Be warned
Only do this if you're sure you're not violating Facebook's privacy policy! It is fine to post on your wall with this method from crontab for example, but it's not ok to let people search others as they may be blocked!
It not possible simulate facebook account to login with crontab. Skipping the confirm step is not possible because skipping any step will not generate the access_token. The only way out is to use offline_access permission and generate an access_token. All requests performed to facebook can be done with this access_token.
The possible way out is; you provide an offine_access permission to your application and store the user access_token somewhere in the application. Maybe hard code it. Make sure you do not disclose it publicly. This access_token is hard coded somewhere on your server side files and not HTML or js files.
Submit a form with all the required parameters; eg: q=mark and type=user. From your server fire a curl request to graph.facebook.com with the parameters and access_token. You will get a JSON response that you can return back to you HTML view. You can also use ajax to make it seamless. In either of the cases; HTTP request or XHR request the access_token is never disclosed to the user.
You can make the application is bit smart by using the access_token of users who have logged into their facebook account and your access_token for users who do not have facebook accounts.
OK, I am not sure why many people never read full question about me, and why my question was edited by other user?
Firstly, I ask this question, because I see fbsearch.us, then after Atul Agrawal, Lix and more user remind me this is violation of Facebook's platform policy. I am sorry, this is my fault
So I update my question, I will obey the policy. And update my question, but I do not want a long url like state=85202ba5222f95ba7fee0c78ff1971dc&code=AQBGsJjT92gALrAjTCI0XQIXht......,
I never find a way under PHP SDK, but some way in JS SDK
<script src="https://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({ appId: '140174749371026',
status: true,
cookie: true,
xfbml: true,
oauth: true
});
function FBLogin() {
FB.login(function (response) {
if (response.authResponse) {
ConnectFacebookUser(response.authResponse.accessToken);
} else {
}
}, { scope: 'email' });
}
$('#fb-button').live('click', function (e) {
FBLogin();
e.preventDefault();
});
function ConnectFacebookUser(accesstoken) {
alert(accesstoken)
}
};
</script>
Login with facebook
<div id="fb-root"></div>
Anyone have method under PHP SDK? I hope now people cauld stop talking about policy, and discuss web technology. Thanks.
Here I am using Facebook Login button plugin and javascript sdk
I am able to successfully login and logout by using above.
When a first time user has gone through authentication process I need to store user basic information i.e. Facebook login name, email in my database.
Please suggest how I can do this.
<p><fb:login-button autologoutlink="true"></fb:login-button></p>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({ appId: '123456', status: true, cookie: true,
xfbml: true
});
};
(function () {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
} ());
</script>
Subscribe to the event auth.login. If you do this, Facebook will call your handler after a login as happened.
In that handler, use FB.api to call the Graph API to get any information you desire. For example calling /me as shown in the second example will get you basic information about the logged in user.
Now you have all the data in JavaScript. To send that up to your server, do a plain old XMLHttpRequest/AJAX request. Your JavaScript library probably makes this easy -- in jQuery this is jQuery.ajax() -- but worst case you can use XHR directly.
Now you have the data on your server and you can do whatever you want, like store it in the database. If you only want to store the data once, just check that you haven't already stored info about that user ID yet.
It's also possible to use a combination of PHP SDK and JS SDK, with the latter performing the login and the former storing data on the server. Something like:
<?php
require_once 'config.php';
require_once 'lib/facebook.php';
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_APP_SECRET,
));
?>
<!DOCTYPE html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({
appId:'<?php echo $facebook->getAppID() ?>',
cookie:true,
xfbml:true,
oauth:true
});
FB.Event.subscribe('auth.login', function (response) {
window.location = "showUser.php"; //redirect to showUser.php on Login
});
FB.Event.subscribe('auth.logout', function (response) {
window.location.reload();
});
};
(function () {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
<div class="fb-login-button" data-show-faces="true" data-width="200"
data-max-rows="1"></div>
</body>
</html>
And in showUser.php you have something like:
<?php
#showUser.php
require_once 'config.php';
require_once 'lib/facebook.php';
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_APP_SECRET,
));
$user = $facebook->getUser();
if($user)
{
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
var_dump($user_profile); //You can now save this data
} catch (FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
}
}
?>
There's a hole in that solution -- this means the user can make up any information he wants and post an XHR back to my server. The server is going to need to check with Facebook directly.
//very simple just change this line
fb:login-button autologoutlink="true"
//with this one
fb:login-button autologoutlink="true" onlogin='your_ajax_fun_that_store_in_db()'
function your_ajax_fun_that_store_in_db(){
FB.api('/me', function(response) {
$.post( "ajax/store_user_info.php",response, function( data ) {
//write you js code here !
//you can use the (response) from facebook directly in your store_user_info.php as it will be sent in POST array
});
});
}
//last thing when you face such a problem the first thing to do is to go back to facebook reference of fun.
I have the following script which works, i.e. it goes to the facebook login page if the user is not already logged in, and asks them if they are ok with the app to post messages on their wall:
<?php
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed for security reasons',
'secret' => 'removed for security reasons',
'cookie' => true,
));
$session = $facebook->getSession();
if ($session) {
if (isset($_GET[id])) {
$post = $facebook->api("/" . $_GET['id'] . "/feed", "POST", array('message' => 'Hello!'));
echo 'A message has been posted on your friends wall';
} else {
$friends = $facebook->api('/me/friends');
foreach ($friends as $key=>$value) {
echo 'You have ' . count($value) . ' friends<br />';
foreach ($value as $fkey=>$fvalue) {
echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - post message<br />';
}
}
}
} else {
$loginUrl = $facebook->getLoginUrl(array(
'req_perms' => 'publish_stream',
'next' => 'http://'.$_SERVER['SERVER_NAME'].'/stage1.php',
'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php',
));
header('Location: '.$loginUrl);
}
?>
How can this be improved so it does not ask for extended permissions in the start. It should only ask for basic permissions to display the friends list, and only ask for extended permissions if the user clicks on the friend to post a message.
Here's a rewrite of your code, with what I think are best practices:
<?php
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed for security reasons',
'secret' => 'removed for security reasons',
'cookie' => true,
));
$session = $facebook->getSession();
// Prepare the login url with the right permission
$loginUrl = $facebook->getLoginUrl(array(
'req_perms' => 'publish_stream',
'next' => 'http://'.$_SERVER['SERVER_NAME'].'/stage1.php',
'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php',
));
if ($session) {
try {
// Before processing the request
// check if we got the right permission
$perms = $facebook->api(array(
"method" => "fql.query",
"query" => "SELECT publish_stream FROM permissions WHERE uid=me()"
));
if($perms[0]['publish_stream']==='1') {
// We have the right permission
if (isset($_GET['id'])) {
// A small security measure
$id = (int) $_GET['id'];
$post = $facebook->api("/$id/feed", "POST", array('message' => 'Hello!'));
echo 'A message has been posted on your friends wall';
} else {
$friends = $facebook->api(array(
"method" => "fql.query",
"query" => "SELECT uid,name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me())"
));
foreach($friends as $friend)
echo "friend id = {$friend['uid']} - friend name = {$friend['name']} - post message<br />";
}
} else {
// We don't have the right permission
header('Location: '.$loginUrl);
}
} catch (FacebookApiException $e) {
error_log($e);
}
} else {
header('Location: '.$loginUrl);
}
?>
How to check for a permission is explained here. Also I've added comments to save writing an explanation.
Quickly, there is something I want to point out regarding the following block of code:
foreach ($friends as $key=>$value) {
echo 'You have ' . count($value) . ' friends<br />';
foreach ($value as $fkey=>$fvalue) {
echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - post message<br />';
}
}
Your 1st foreach loop is really misleading and not good practice at all. The Graph API isn't overly consistent in how it presents data, but the reason you are doing the foreach is to deal with the data key in the JSON object that is returned. This is generally a bad idea, because that data key is typically present along with other keys (like paging). Instead, I would check to see that $friends['data'] is not empty, and then re-assign the $friends array like so: $friends = $friends['data'];.
Example:
if (!empty($friends['data']))
{
$friends = $friends['data'];
}
else
{
$friends = array();
}
now, for your question.
You mentioned that you don't want to over-ask for permissions. That's a great thing to want, but the problem with it is that Facebook doesn't make it exceedingly easy to check for which permissions you do have or do not have. There is an FQL table that allows you check if your user has a certain set of permissions, but this table doesn't get updated with any kind of urgency. If you obtain extra permissions from a user (or if a user retracts permissions) and you then check this FQL table for the status of the permission, it can (and probably will) read the incorrect value and you will get a false positive.
You have three options to deal with this, that I can think of right off the top of my head.
Continue on your stage1.php code, as you are - there's nothing wrong with the way you're obtaining the installation and the session for the user there. You change page 2 to redirect your user through the OAuth endpoint requesting the publish-stream permission every time the user loads the page. The OAuth endpoint will not re-prompt the user to install, and will send them on their way.
The cons with this approach is, every request to post to a friends' wall turns into 3 requests.
The initial page load
The OAuth redirect / load
The redirect from OAuth back to your application
This approach also requires that you add a flag to your next key in your loginURL, which you can look for to make sure the user went through the OAuth endpoint, otherwise you're going to get an infinite redirect error.
Utilize the FB Javascript SDK to check for your users' current set of permissions. To do this, you'll utilize the FB.getLoginStatus method.
Example:
<div id="fb-root"></div>
<script src="http://code.jquery.com/jquery-1.5.2.min.js"
type="text/javascript" charset="utf-8">
</script>
<script src="http://connect.facebook.net/en_US/all.js"
type="text/javascript" charset="utf-8">
</script>
<script type="text/javascript">
(function($)
{
FB.init({
appId: '<?= FB_APP_ID; ?>',
cookie: true,
status: true,
xfbml: true
});
$('a').click(function(event)
{
var self = this;
event.preventDefault();
FB.getLoginStatus(function(session)
{
if (session.perms.match(/\"publish_stream\"/))
{
/* This user has publish stream, so we don't need
* to ask again
**/
window.location = $(self).attr('href');
}
else
{
/* This user does not have publish stream, so we need
* to ask.
**/
FB.login(function(response)
{
if (response && response.perms.match(/publish_stream/))
{
/* We now have publish stream access! */
window.location = $(self).attr('href');
}
}, {
perms: 'publish_stream'
});
}
})
return false;
})
})(jQuery);
Don't utilize any extended permissions, use the Javascript SDK (again) and give the user a publish-dialog for each user they would like to publish on the wall of. This is a relatively easy thing to do, also.
Example:
given your links for users:
Friend 1
Friend 2
Friend 3
You can do something like this:
<div id="fb-root"></div>
<script src="http://code.jquery.com/jquery-1.5.2.min.js"
type="text/javascript" charset="utf-8">
</script>
<script src="http://connect.facebook.net/en_US/all.js"
type="text/javascript" charset="utf-8">
</script>
<script type="text/javascript">
(function($)
{
$('a').click(function(event)
{
var user_id = $(this).data('id');
FB.ui({
method: 'feed',
message: 'Hello!',
to: user_id
}, function(response)
{
//this gets called whether it was successful, or not.
})
});
})(jQuery);