First, setting up the Composer

Assuming you have Composer installed, and do not want to read all that tutorial, you can create a composer.json file from zero. In your terminal (or console, or whatever its name is…), you should go to the application directory, and type “composer init”. This will open a Composer config generator which will guide you to creating the composer.json file. For the moment just refuse to install any dependencies.

The end result should be a composer.json file that looks more or less like this:

PHP

1

2

3

4

5

6

7

8

9

10

{

"name":"avenirer/application",

"authors":[

{

"name":"Avenirer",

"email":"avenir.ro@gmail.com"

}

],

"require":{}

}

Now, in your terminal, type “composer install”. This should create the vendor directory and the autoload file.

Loading the composer autoloader

Once we have the autoload.php inside our vendor directory, we must ask CodeIgniter to load it. I do this by changing the config.php file inside the application/config directory (but you can load it any way you want…)

In your config.php, look for a line with $config[‘composer_autoload’]. After that line, add the following line:

PHP

1

require_onceAPPPATH.'vendor/autoload.php';

Cool. Now we have CodeIgniter with Composer.

Installing our Facebook SDK for PHP

Now we can use Composer to install Facebook SDK for PHP. We do this by simply using the terminal (I sure hope you remained inside the application directory) and typing “composer require facebook/php-sdk-v4“.

Cool. As you can see, now the Facebook SDK is added to our application/vendor directory and also the composer.json file is looking a bit different…

PHP

1

2

3

4

5

6

7

8

9

10

11

12

{

"name":"avenirer/application",

"authors":[

{

"name":"Avenirer",

"email":"avenir.ro@gmail.com"

}

],

"require":{

"facebook/php-sdk-v4":"^5.2"

}

}

Setting up the SDK

Now, that we have Facebook SDK installed and we have an ID and an App Secret Key we can set the SDK to work with our application.

We don’t need to remember the ID and App secret key, so why not just save them inside our config.php file.

PHP

1

2

$config['facebook_app_id']='YOUR_APP_ID';

$config['facebook_app_secret']='YOUR_FACEBOOK_APP_SECRET';

The Facebook object

Considering we will use Facebook login inside most of our application, we might as well create a Facebook object inside the MY_Controller file. The added lines to the file should look like this:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

classMY_ControllerextendsCI_Controller

{

public$fb;// this will be the object that we will use across the application

function__construct()

{

parent::__construct();

// now we only need to build the object...

$this->fb=newFacebook\Facebook([

'app_id'=>$this->config->item('facebook_app_id'),

'app_secret'=>$this->config->item('facebook_app_secret'),

'default_graph_version'=>'v2.5'

]);

}

}

You must understand that I’ve only wrote THE ADDED LINES AND NOT THE ENTIRE MY_Controller, which we’ve created in the previous tutorials.

Making the login button (or rather link…)

First of all we need to know where will a visitor be sent after he agrees to login with Facebook. So let’s assume we will create a facebook() method in our User.php file, where the user will be redirected after trying to login with Facebook. In order for this to happen we will need to tell Facebook API to redirect the users. So in our view (I will use a “sidebar_view”, assuming the users will see the “Login with Facebook” button on every page of our site…) will will create a “Login with Facebook” button.

PHP

1

2

3

4

5

6

<?php

$helper=$this->fb->getRedirectLoginHelper();

$permissions=['public_profile','email'];// these are the permissions we ask from the Facebook user's profile

echoanchor($helper->getLoginUrl('http://YOURSITE.COM/user/facebook',$permissions),'Login with Facebook');

?>

Maybe the code needs a little explanation (besides the fact that you need to change YOURSITE.COM with the address you need)… In order for us to allow the users to login with Facebook, we need to create a link that will tell Facebook where to redirect the user after a un/successful login took part (or a callback method, as Facebook puts it… https://developers.facebook.com/docs/php/howto/example_facebook_login). As you can see we will pass the permissions needed for our application to allow the user to login (namely email… you could of course only ask for the public_profile in order to allow the user to login, as you can find the email from there, but I wanted to make sure I get what I wanted).

The login processing

Now, returning to our User.php file, we need to create a method called facebook(). You can of course name it whatever you want, but make sure you also change the url inside the Facebook SDK for the login button.

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

publicfunctionfacebook()

{

$helper=$this->fb->getRedirectLoginHelper();

try

{

$accessToken=$helper->getAccessToken();

}

catch(Facebook\Exceptions\FacebookResponseException$e)

{

// When Graph returns an error

echo'There was an error while trying to login using Facebook: '.$e->getMessage();

exit;

}

catch(Facebook\Exceptions\FacebookSDKException$e)

{

// When validation fails or other local issues

echo'Facebook SDK returned an error: '.$e->getMessage();

exit;

}

if(isset($accessToken))

{

$this->fb->setDefaultAccessToken($accessToken);

try

{

$response=$this->fb->get('/me?fields=id,name,email');

$user=$response->getGraphUser();// we retrieve the user data

}

catch(Facebook\Exceptions\FacebookResponseException$e)

{

// When Graph returns an error

echo'Could not retrieve user data: '.$e->getMessage();

exit;

}

catch(Facebook\Exceptions\FacebookSDKException$e)

{

// When validation fails or other local issues

echo'Facebook SDK returned an error: '.$e->getMessage();

exit;

}

}

else

{

echo'oups... where is the access token???';

}

}

Now, that we have the user’s data, especially the email, we should allow the user to login. But we can’t, as the Ion_Auth doesn’t allow us to login a user with only the email. So what do we do?

Create a User_model.php

Up until this point we didn’t work directly with the users table data, so there was no point in creating a User_model.php, but now it seems that we need to create it. So inside our application/models we should create a file named User_model.php, and in it we should create a method called login_with_facebook() that will simply look for the email address inside the table and create the needed session variables for the Ion Auth to think it has a logged in user:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<?php

defined('BASEPATH')ORexit('No direct script access allowed');

classUser_modelextendsCI_Model

{

publicfunction__construct()

{

parent::__construct();

}

publicfunctionlogin_with_facebook($email)

{

$this->db->where('email',$email);

$this->db->limit(1);

$users=$this->db->count_all_results('users');// are there any users with that email address?

$_SESSION['identity']=$user->username;// if you've set up email as the login identity column, you shouls use $user->email in here...

$_SESSION['username']=$user->username;

$_SESSION['email']=$user->email;

$_SESSION['user_id']=$user->id;

$_SESSION['old_last_login']=$user->last_login;

returnTRUE;

}

}

}

Cool. Now, if there is an user with that particular email in our users table, that user should be logged in. If not, the model will return FALSE;

Returning to our User controller…

Now, returning to our facebook() method of our User controller, if the $user was retrieved successfully , we can call the User_model and try to login the user:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

//we do not actually need to verify if the user email address is correct... but we should make sure

if($this->form_validation->valid_email($user['email']))

{

$this->load->model('user_model');

if($this->user_model->login_with_facebook($user['email']))

{

redirect('dashboard');

}

else

{

redirect('user/login');

}

}

Let’s see the facebook() method again…

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

publicfunctionfacebook()

{

$helper=$this->fb->getRedirectLoginHelper();

try

{

$accessToken=$helper->getAccessToken();

}

catch(Facebook\Exceptions\FacebookResponseException$e)

{

// When Graph returns an error

echo'There was an error while trying to login using Facebook: '.$e->getMessage();

exit;

}

catch(Facebook\Exceptions\FacebookSDKException$e)

{

// When validation fails or other local issues

echo'Facebook SDK returned an error: '.$e->getMessage();

exit;

}

if(isset($accessToken))

{

$this->fb->setDefaultAccessToken($accessToken);

try

{

$response=$this->fb->get('/me?fields=id,name,email');

$user=$response->getGraphUser();// we retrieve the user data

}

catch(Facebook\Exceptions\FacebookResponseException$e)

{

// When Graph returns an error

echo'Could not retrieve user data: '.$e->getMessage();

exit;

}

catch(Facebook\Exceptions\FacebookSDKException$e)

{

// When validation fails or other local issues

echo'Facebook SDK returned an error: '.$e->getMessage();

exit;

}

//we do not actually need to verify if the user email address is correct... but we should make sure

if($this->form_validation->valid_email($user['email']))

{

$this->load->model('user_model');

if($this->user_model->login_with_facebook($user['email']))

{

redirect('dashboard');

}

else

{

redirect('user/login');

}

}

}

else

{

echo'oups... where is the access token???';

}

}

What about “auto”-registering

“But what if we want the user to be registered automatically when he wants to login with Facebook?” you may ask. So… you want the users that try to login with Facebook to be automatically registered and then logged in…

In order to do this we need to[paywall] modify the login_with_facebook() method of our User_model.php. Besides receiving the email, the method can also retrieve the user’s username:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

publicfunctionlogin_with_facebook($email,$username)

{

$this->db->where('email',$email);

$this->db->limit(1);

$users=$this->db->count_all_results('users');

if(!isset($users)||$users<1)

{

$this->load->helper('string');

$password=random_string('alnum',10);// we create a random password for the user...

$_SESSION['user_id']=$user->id;//everyone likes to overwrite id so we'll use user_id

$_SESSION['old_last_login']=$user->last_login;

}

returnTRUE;

}

Now, in our controller, we simply call the model’s method:

PHP

1

$this->user_model->login_with_facebook($user['email'],$user['name']

And that’s it.[/paywall] NOTE THAT I HAVEN’T REALLY TRIED ALL THAT YOU’VE SEEN, SO YOU MIGHT ENCOUNTER SOME PROBLEMS. IF THIS HAPPENS, PLEASE DO WRITE A COMMENT BELOW. IF IT DOESN’T, YOU CAN ALWAYS BUY ME A COFFEE (or a gift… who knows?…)