Calling multiple FB Graph API requests in codeigniter - facebook

I'm working a Facebook login functionality which works smoothly, however I tried to Google this but couldn't find anything that I was looking for.
I need to get user profile pictures, interests, likes, books, movies, music. Code below is my controller which works fine.
class Welcome extends CI_Controller {
public function __construct() { parent::__construct();
}
public function index() {
$fb_config = array(
'appId' => '550765875685678567',
'secret' => 'e03771716c87658765843535ac38'
);
$this->load->library('facebook', $fb_config);
$user = $this->facebook->getUser();
if ($user) {
try {
$data['user_profile'] = $this->facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
if ($user) {
$data['logout_url'] = $this->facebook
->getLogoutUrl();
} else {
$data['login_url'] = $this->facebook
->getLoginUrl($params = array('scope' => "email,user_birthday,
user_likes, >user_interests, user_location,
read_friendlists, user_checkins,
user_religion_politics, user_photos,
user_likes, user_hometown, user_about_me"));
}
$this->load->view('welcome',$data);
}
}
Now if I wanted to run
$albums = $facebook->api('/me/albums');
in same function, how would I achieve this? or how can I run multiple api calls here and include it in my $data['user_profile']?
Thanks all

You can run as many API calls as you would like in sequential order and have them go into your data array. For example:
$data['user_profile'] = $this->facebook->api('/me');
$data['user_albums'] = $this->facebook->api('/me/albums');
Multiple calls won't cause any problems.

Related

zend session getting reset when user toggles between pages

I am learning Zend Framework and having issues with Zend_Session_Namespace.
Here is the scenario:
Homepage(user clicks on login-Index Controller)
login page(user auth is done->Login Controller)
On Successful login: Create a new zend_Session_Namespace("login") and take him to another page with home page button.
User Clicks the Home Page Button.I can Access the username from the session and display the welcome message.
User again clicks on the login page. I am checking isset($session->name) to prevent login again and take him to other page instead. --> I am failing here . The session is somehow reset , I am quite unsure what I am missing.
class IndexController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
$session = new Zend_Session_Namespace("login_session");
//Check if the session is already valid
if(isset($session->name)) {
$this->view->userLoggedIn="true";
$this->view->name=$session->name;
}
}
}
class LoginController extends Zend_Controller_Action
{
public function loginaction(){
$session = new Zend_Session_Namespace("login_session");
if(isset($session->name)){
//Redirect to New Page-Already Logged In
} else {
//Authenticate the user and if login is successful
$session->name="USER_NAME";
}
}
}
Thank You.
This code looks ok except for the previously mentioned typo.
It's possible and likely that somewhere else in your code you inadvertently overwrite the session namespace. I think we've all done that at least once.
I would suggest that instead of trying to roll your own authentication solution, use the one that ZF provides: Zend_Auth
a basic Zend_Auth login/logout might look like:
//non production code for example only
public function loginAction()
{
$form = new Application_Form_Login();
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
$data = $form->getValues();
$authAdapter = new My_Auth_Adapter($data['username'], $data['password']);
//authenticate
$result = $authAdapter->authenticate();
if ($result->isValid()) {
//store the user object
$auth = Zend_Auth::getInstance();
//access Zend_Auth session namespace
$storage = $auth->getStorage();
$storage->write($authAdapter->getUser());
//add message to flashmessenger
$this->message->addMessage('Welcome');
//redirect to the homepage
return $this->_redirect('/');
} else {
//handle authentication errors
$this->view->loginMessage =
"Sorry, your username or password was incorrect";
}
} else {
//handle form validation errors
$this->_redirect('/users/index/register');
}
} else {
//if not post render empty form
$this->view->form = $form;
}
}
public function logoutAction()
{
$authAdapter = Zend_Auth::getInstance();
$authAdapter->clearIdentity();
}
http://www.ens.ro/2012/03/20/zend-authentication-and-authorization-tutorial-with-zend_auth-and-zend_acl/
Good Luck!

codeigniter login with facebook getUser() return 0

Well I'm trying to implement login with facebook using codeigniter I always have 0 when I call getUser() function , I tried all the possible solution but none of them works for me I don't know why , here is my facebook library class :
<?php
include(APPPATH.'libraries/facebook/facebook.php');
class Fbconnect extends Facebook {
public $user = NULL;
public $user_id = FALSE;
public $fb = FALSE;
public $fbSession = FALSE;
public $appkey = 0;
public function Fbconnect(){
$ci =& get_instance();
$ci->config->load('facebook', TRUE);
$config = $ci->config->item('facebook');
parent::__construct($config);
parse_str( $_SERVER['QUERY_STRING'], $_REQUEST );
$this->user_id = $this->getUser();
$me = null;
if($this->user_id){
try{
$me = $this->api('/me');
$this->user = $me;
} catch(FacebookApiException $e){
error_log($e);
}
}
}
}
and here my main controller :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Main extends CI_Controller {
public function index()
{
$this->load->view('index');
}
public function fb_request()
{
$this->load->library('fbconnect');
$data = array(
'redirect_uri' => site_url('main/handle_facebook_login'),
'scope' => array('email','user_birthday')
);
redirect($this->fbconnect->getLoginUrl($data));
}
public function handle_facebook_login()
{
$this->load->library('fbconnect');
$user = $this->fbconnect->user;
echo "<pre>";
print_r($user);
echo "</pre>";
if($user)
{
echo "<pre>";
print_r($user);
echo "</pre>";
}
else
{
echo "Could not login ... ";
}
}
}
This same problem gave me serious migraine..lol but what solved the problem was to include index.php both in the fb login redirect url and also in your Facebook app site url. I was using htaccess with codeigniter so didnt use the index.php in my URLs even though its being called on every page request. Maybe you should try that.
Make sure you AppId and secret key are correct as per your application.some time application may take some time to get activated.

CakePHP and Facebook with Security Component turned on

I want the Security Component turned on.
BUT when you load a CakePHP app inside a Facebook tab, FB posts $_REQUEST['signed_request'] to my form - the problem with this is that the Security Component "reacts" to this "post" and gives me validation errors, black-hole, etc.
How do I go around this?
I could not find anything on the documentation to go around this problem.
What I wanted was to somehow run the Security Component "manually" so that it only "reacts" when I actually submit my form and not when Facebook posts the $_REQUEST['signed_request'] to my form.
UPDATE:
<?php
App::uses('CakeEmail', 'Network/Email');
class PagesController extends AppController {
public $helpers = array('Html','Form');
public $components = array('RequestHandler');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('*');
$this->Security->validatePost = true;
$this->Security->csrfCheck = true;
$this->Security->unlockedFields[] = 'signed_request';
}
public function home() {
$this->loadModel('Memberx');
if($this->request->is('post') && isset($this->request->data['Memberx']['name'])) {
//...save here, etc. ...
}
}
FYI: I get a "black hole" error.
FINAL UPDATE (After #tigrang's answer):
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('*');
$this->set('hasLiked', false);
if(isset($this->request->data['signed_request'])){
$this->set('hasLiked', $this->hasLiked($this->request->data['signed_request']));
}
if(isset($this->request->data['Memberx']['signed_request'])) {
$this->set('hasLiked', $this->hasLiked($this->request->data['Memberx']['signed_request']));
}
/*
To go around Facebook's post $_REQUEST['signed_request'],
we unset the $_REQUEST['signed_request'] and disable the csrfCheck
ONLY after we have set the hasLiked view variable
*/
unset($this->request->data['signed_request']);
if (empty($this->request->data)) {
$this->Security->csrfCheck = false;
}
}
Then, I do something like below in my views:
<?php
if($hasLiked) {
?>
You have liked this page!
<?php
}
?>
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('*');
$this->_validateFbRequest();
}
protected function _valdiateFbRequest() {
if (!isset($this->request->data['signed_request'])) {
// not a valid request from fb
// throw exception or handle however you want
return;
}
$signedRequest = $this->request->data['signed_request'];
unset($this->request->data['signed_request']);
if (empty($this->request->data)) {
$this->Security->csrfCheck = false;
}
// validate the request
}

Codeigniter facebook login

I'm trying to use the code from this Tutorial: http://www.betterhelpworld.com/codeigniter/how-to-use-facebook-php-sdk-v-3-0-0-with-codeigniter to do login via facebook: My controller code looks like:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class User extends CI_Controller {
public function __construct()
{
parent::__construct();
}
function index() {
$this->loginByFacebook();
}
function facebook() {
$this->load->library('fb_connect');
if (!$this->fb_connect->user_id) {
echo 'not ok';
}
else
{
$fb_uid = $this->fb_connect->user_id;
$fb_usr = $this->fb_connect->user;
print_r($fb_usr); // Printing to show all available variables
// Do your processing here after login. May be you can check if first time user then can register in your database.
echo 'ok';
}
}
function loginByFacebook() {
$this->load->library('fb_connect');
$param['redirect_uri'] = site_url("user/facebook");
$param['scope'] = 'email, publish_stream,user_birthday,offline_access'; // Set the required access here
redirect($this->fb_connect->getLoginUrl($param));
}
}
After calling the login I'll be redirected to facebook, asked for permissions and redirected to my application but then I get always the not ok message string which means, that the user is not connected. So what am I doing wrong?

logout facebook connect session

I'm trying to integrate my site with facebook connection to handle facebook signup and facebook login. i'm using codeigniter framework. But I got this problem now:
current facebook login user is "test1". I go to my site to sign up with facebook, everything works fine and "test1"'s info are stored in my database. However, after I log test1 out from facebook, and login "test2" in on facebook, I go back to my site and do a signup with facebook again, it still "test1"'s info stored.
I use ion auth library to handle user logout from my site. However, after I switch facebook test user accounts and do a "login with facebook" again, it still get the previous facebook user.
Based on the 2 cases above, it seems that the facebook session wasn't cleared up? I'm struggling on this problem for a long time, please help!
I user this to get user data:
$fb_usr = $this->fb_connect->user;
(it seems that no matter how the facebook user changs, fb_connect always return same user)
and fb_connect is sth like this:
<?php
include(APPPATH.'libraries/facebook/facebook.php');
class Fb_connect extends Facebook{
//declare public variables
public $user = NULL;
public $user_id = FALSE;
public $fbLoginURL = "";
public $fbLogoutURL = "";
public $fb = FALSE;
public $fbSession = FALSE;
public $appkey = 0;
//constructor method.
public function __construct()
{
$CI = & get_instance();
$CI->config->load("facebook",TRUE);
$config = $CI->config->item('facebook');
parent::__construct($config);
$this->user_id = $this->getUser(); // New code
$me = null;
if ($this->user_id) {
try {
$me = $this->api('/me');
$this->user = $me;
} catch (FacebookApiException $e) {
error_log($e);
}
}
if ($me) {
$this->fbLogoutURL = $this->getLogoutUrl();
} else {
$this->fbLoginURL = $this->getLoginUrl();
}
} //end Fb_connect() function
}
I think what you need to do is set the "next" param for your getLogoutUrl() call. Something like this:
$args['next'] = site_url('logout'); // replace "logout" with your controller which will clear the session
$fbLogoutURL = $facebook->getLogoutUrl($args);
Then, in the controller set as "next" you'll need to clear the session data.
class Logout extends CI_Controller {
public function index() {
$facebook->destroySession();
$this->session->sess_destroy(); // Assuming you have session helper loaded
$this->load->view('logout');
}
}
Let me know if that helps.