Connecting to Facebook from a Yii app

Hi,

I have a related forum post on this topic, but I think my wording of the problem was misleading, so I’ve created another topic.

Also, I’ve read everything in this forum on this subject, and haven’t found what I need, so kindly read this carefully before replying; I’d rather not be sent to another thread which is not what I’m looking for.

Here’s what I am looking for: a simple, working, complete example of a Yii application which:

  1. Uses Facebook’s Javascript SDK

  2. Uses the Graph API PHP module provided by Facebook

I do not want to re-do the way Facebook performs authentication, I.e., I do not want to build a Yii login as recommended in this forum thread:

http://www.yiiframew…cebook-connect/

I simply want a way, from inside my Yii application, for my code to get answers to 2 easy questions:

a. Has the user authenticated with Facebook?

b. If so, what is their Facebook user id?

That’s it. Willing to pay for a complete example which achieves those tasks, and works in all major browsers – MSIE, Firefox, Chrome, Safari, etc.!

Thanks!

Emily




<div id="fb-root"></div>

<script src="http://connect.facebook.net/en_US/all.js"></script>

<script>

  FB.Event.subscribe('auth.sessionChange', function(response) {

    if (response.session) {

      // A user has logged in, and a new cookie has been saved

      jQuery.post(

        '<?php echo Yii::app()->controller->createUrl('xxxxx') ?>',

        jQuery.extend({service: 'facebook'}, response.session)

      );

    }

  });

  FB.init({appId: '<?php echo $appid?>', status: true, cookie: true, xfbml: true});

</script>



Code from http://developers.facebook.com/docs/reference/javascript/

This snippet will detect if the user have an active session with facebook. It will post the user session to the xxxx url if there is a active session. From memory for this to work, the user must already sign up with your application. If you have not done that yet, you need to setup oauth and redirect the user to facebook to grant their permission to your app.

$appid is the facebook id that you get when you register your app with Facebook.

You would want to create a Widget and put those in the widget.

Hello,

Thanks so much for your post. It looks as though what you’ve written is listening for a session changing event. Again, what I"m really interested in is a working example which gets the login status of the user. 99% of the time, my user is ALREADY logged into facebook; I just need to know his or her Facebook user id.

And, most of all, I’d like to see a complete example. I’ve gotten a Facebook app to work outside of the Yii framework. But somethng about the way the Yii framework operates is making it impossible for me to use Facebook’s session.

A complete example would be one which specifies, e.g., “put this javascript into index.php”… “add this action to the main controller”… etc. Can anyone provide me a small, working–but COMPLETE Facebook app, which does what I’ve described? Again, I’d be willing to pay for this; I’ve struggled too long to figure this out and I am not a Javascript expert.

Thanks!

Emily

The solution turned out to be rather simple.

The facebook PHP SDK, distributed by facebook as “Facebook.php”, attempts to set the local session using PHP’s built-in session handling. But Yii handles sessions differently, using CHttpCookie.

So, the fix involved these steps:

  1. Modify the Facebook.php file distributed by Facebook.

    Wherever the built-in PHP cookies are referred to, use

    Yii’s cookies instead. There are several spots to edit.

    One for example, is shown below. Instead of:




setcookie($cookieName, $value, $expires, '/', $domain);



Do this


 

$yiiCookie = new CHttpCookie($cookieName, $value); 

$yiiCookie->expire = time() + 31536000; // one year from now 

Yii::app()->request->cookies[$cookieName] = $yiiCookie;



  1. In the main layout file protected/views/layout/main.php, we can now get/set the session variable

    like this:




// Get an instance of the Facebook class distributed as the PHP SDK by facebook:

$facebook = new Facebook(array(

		'appId'  => 'MY-APP-ID',

		'secret' => 'MY-APP-SECRET',

		'cookie' => true,

));

$session = $facebook->getSession();

$encodedSession = json_encode($session);


if ($session) {

   $facebook->setSession($session, true);

   // THE KEY TO THE PUZZLE IS THE LINE BELOW, which sets your local session variable to Facebook's session:

   $facebook->setCookieFromSession($session); 


   // And now do whate'er you fancy with facebook's API, e.g., grabbing the user's profile:

   $facebookUser = $facebook->api('/me');


    // Or perhaps a FQL query:

   $query = 'SELECT app_id, canvas_name FROM application WHERE canvas_name="onthefarm"';

   $apps = $facebook->api_client->fql_query($query);


}



Thanks for the great suggestions and I hope I’ve spared someone a future migraine. :slight_smile:

Emily

I’m not sure if anyone else ran into this … but, changing:

protected function setCookieFromSession($session=null) {

to:

public function setCookieFromSession($session=null) {

fixed my issue. (in facebook.php)

Here’s my final facebook.php file;

http://pastebin.com/iQbfGPHg

and here is an example main.php ( yiiapplication/protected/views/layouts/main.php )

http://pastebin.com/82LfVRk7

I want to note that I moved that main.php code into my base controller class which has freed me up to get the user’s FB id (or other information about the FB session) anywhere I want:

Add this to the top of your ‘protected/components/Controller.php’ file:

http://pastebin.com/5n0NH8Ri

This is especially useful when dealing with the gii generated Models:

http://pastebin.com/SebaM6dM

Adding the beforeSave and beforeFind code to the models allows you to have very simple row level security (only showing users their own information) pretty easily.

Here’s my new main.php file:

http://pastie.org/1301027

David or Emily,

I try so hard to make this work and i cant do this. Anyone can send a skeleton with facebook login working, for a base to build a aplication?

Thanks a lot!

AlecsGanzer

Hi Emily

$session = $facebook->getSession();

$me = null;

// Session based API call.

if ($session) {

try {

&#036;uid = &#036;facebook-&gt;getUser();


&#036;me = &#036;facebook-&gt;api('/me');

} catch (FacebookApiException $e) {

error_log(&#036;e);

}

}

echo “Hello, “.$me[‘name’].”<br/>”;

echo "<img src=\"https://graph.facebook.com/" . $uid . "/picture\">";

After the above processing which I can see myself, but I have 2 fatal errors following that:

$facebook->setCookieFromSession($session);

Fatal error: Call to protected method Facebook::setCookieFromSession() from context ‘’

$query = ‘SELECT user_id FROM like WHERE object_id=“122706168308”’;

$apps = $facebook->api_client->fql_query($query);

Fatal error: Call to a member function fql_query() on a non-object

Please help.

Thanks

you haven’t create an object instance to access facebook php sdk in your above mention code that is why this error is generating…please have a look again in your code…!!

Thanks Jayant

I edited the protected method setCookieSession to public and got it working as advised by David Greene above.

However, I need to find all the user_ids who ‘liked’ a particular link eg. http://myurl.com/mypic?r=pic&id=1




  $query = 'SELECT user_id FROM like WHERE object_id="10150553977435514"';


  $fql = $query;

  $param = array('method'=>'fql.query','query'=> $fql,'callback'=>'');

  $fqlResult = $facebook->api($param); 


  print_r($fqlResult);



It returned an empty array.

For the object_id in the ‘like’ table, where would I obtain it? It’s not the ‘link_id’ in the link table: http://developers.facebook.com/docs/reference/fql/links/

Please help.

i think you have to use link_id instant of object_id to get exact result…!!!

check this out and please also check your code about a query execution…because i am not sure about it…!!

help a lot , never to consider modifying the SDK file , it 's ingenious

Hi Emily,

I am using facebook PHP SDK 3.1.1 and Yii 1.1.8, your solution not works with that version. It not contains setcookie() function in facebook.php file. I am able to store the value into session through Yii::app()->session but when reading the session, it returns empty value instead of actual value. I don’t have any idea how to resolve this issue. Please give me an idea.

Regards

Varadha.