
This tutorial is considered outdated, smelly, rotten and not reliable any longer. Please visit the links below for more up-to-date and less pain in the a** solutions. Thank you :)
Kebanyakan aplikasi web pada masa ini menawarkan kelebihan kepada pengguna untuk menggunakan akaun Facebook mereka untuk log masuk. Ada juga yang menawarkan lebih dari itu, seperti OpenID, Twiter dan lain lain lagi. Kelebihan utama fungsi sebegini ialah memudahkan pengguna mendaftar tanpa perlu mengisi form yang panjang berjela, hanya klik beberapa button, semua siap sedia digunakan.
Untuk project terbaru, saya cuba untuk integrate Facebook Connect di dalam aplikasi saya yang menggunakan CakePHP 1.2.6 (terbaru pada waktu artikel ini di tulis). Pada mulanya memang agak susah untuk menjadi, tapi selepas 15 kali mencuba akhirnya berjaya juga. Dan saya ingin share cara caranya di sini, untuk tujuan rujukan sesama kita pada masa akan datang.
Keperluan
Integrate Auth Component
Anda perlu buat tutorial ini terlebih dahulu sebelum boleh mula. Ini kerana kita memerlukan Auth component yang berjaya dipasang pada CakePHP kita. Jika anda belum buat, sila siapkan tutorial itu terlebih dahulu dan kemudian baru buat yang ini. Peratus untuk tutorial ini gagal jika tutorial tentang ACL itu tak disiapkan ialah 100%. Tetapi untuk pro bakers, boleh abaikan.
VirtualHost
Untuk menggunakan Facebook Connect pada local server, kita tidak boleh menggunakan address http://localhost ketika kita hendak cipta aplikasi Facebook baru. Oleh itu, apa yang kita boleh buat ialah menggunakan VirtualHost pada Apache dan kita buat satu dummy domain pada komputer kita. Untuk tujuan tutorial ini saya ingin gunakan domain fbconnect.com.
Buka fail X:\xampp\apache\conf\extra\httpd-vhosts.conf dengan code editor anda (saya gunakan PSPad) dan masukkan kod berikut:
NameVirtualHost *:80 <Virtualhost *:80> ServerAdmin syahzul@gmail.com DocumentRoot "X:/xampp/htdocs" ServerName localhost <directory "X:/xampp/htdocs"> AllowOverride FileInfo AuthConfig Limit Indexes Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <limit GET POST OPTIONS> Order allow,deny Allow from all </limit> <limitexcept GET POST OPTIONS> Order deny,allow Deny from all </limitexcept> </directory> </Virtualhost> <Virtualhost *:80> ServerAdmin syahzul@gmail.com DocumentRoot "X:/xampp/htdocs/fbconnect" ServerName fbconnect.com <directory "X:/xampp/htdocs/fbconnect"> AllowOverride FileInfo AuthConfig Limit Indexes Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <limit GET POST OPTIONS> Order allow,deny Allow from all </limit> <limitexcept GET POST OPTIONS> Order deny,allow Deny from all </limitexcept> </directory> </Virtualhost>
Kemudian, buka pula fail C:\Windows\system32\drivers\etc\hosts dengan code editor anda dan tambahkan kod berikut di dalamnya:
127.0.0.1 fbconnect.com
Dan restart Apache anda.
Nota: Sila tukarkan drive X: kepada drive di mana anda install xampp anda.
Facebook Application Client’s File
Muat turun files yang diperlukan dari sini: http://svn.facebook.com/svnroot/platform/clients/packages/facebook-platform.tar.gz, extract semuanya dan masukkan di dalam X:\xampp\htdocs\fbconnect\vendors\facebook.

Kemudian, pada folder webroot, create satu file baru dan namakan xd_receiver.htm dan masukkan kod berikut:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Cross-Domain Receiver Page</title> </head> <body> <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?2" type="text/javascript"></script> </body> </html>

Create Facebook Application
Sekarang tiba masanya untuk kita create satu Facebook Apps baru di sini: http://www.facebook.com/developers/.
1. Set up application baru

2. Berikan nama yang sesuai

3. Pada tab Basic, masukkan contact email untuk application anda

4. Pada tab Authentication, masukkan URL domain yang kita gunakan.
5. Pada tab Connect, masukkan URL (beserta trailing slash), base domain (domain tanpa http://) dan URL sekali lagi.

6. Simpan API Key dan Application Secret untuk kita gunakan kemudian.

Database
Kita perlu tambahkan 2 fields baru pada table users kita.
ALTER TABLE `users` ADD `fbid` BIGINT( 20 ) NOT NULL DEFAULT '0' AFTER `password` , ADD `fbpassword` BIGINT( 20 ) NOT NULL AFTER `fbid`;
AppController.php
Buka file AppController.php dan tambahkan kod berikut:
var $uses = array('User');
var $facebook;
var $__fbApiKey = '7d8e96e4ddf047b5611f5fcbaee04133';
var $__fbSecret = '56480e8655ceecaa36ad2e599bda3604';
syahzul@gmail.com
Dan tambah kod berikut di dalam file yang sama.
function __construct() {
parent::__construct();
// Prevent the 'Undefined index: facebook_config' notice from being thrown.
$GLOBALS['facebook_config']['debug'] = NULL;
// Create a Facebook client API object.
$this->facebook = new Facebook($this->__fbApiKey, $this->__fbSecret);
}
Seterusnya, tambah kod ini di dalam method beforeFilter() di dalam file yang sama.
//check to see if user is signed in with facebook
$this->__checkFBStatus();
//send all user info to the view
$this->set('user', $this->Auth->user());
Dan kod seterusnya:
private function __checkFBStatus(){
//check to see if a user is not logged in, but a facebook user_id is set
if ( !$this->Auth->User() && $this->facebook->get_loggedin_user() ) {
//see if this facebook id is in the User database; if not, create the user using their fbid hashed as their password
$user_record =
$this->User->find('first', array(
'conditions' => array('fbid' => $this->facebook->get_loggedin_user()),
'fields' => array('User.fbid', 'User.fbpassword', 'User.password'),
'contain' => array()
));
//create new user
if(empty($user_record)):
$user_record['fbid'] = $this->facebook->get_loggedin_user();
$user_record['fbpassword'] = $this->__randomString();
$user_record['group_id'] = 3; // we have to set group_id manually here, put the lowest level
$user_record['password'] = $this->Auth->password($user_record['fbpassword']);
$this->User->create();
$this->User->save($user_record);
endif;
//change the Auth fields
$this->Auth->fields = array('username' => 'fbid', 'password' => 'password');
//log in the user with facebook credentials
$this->Auth->login($user_record);
}
// if user is logged in, and fb also logged in
elseif ( $this->Auth->User() && $this->facebook->get_loggedin_user() ) {
$user_record = $this->User->find('first', array('conditions' => array('User.id' => $this->Auth->User('id'))));
//create new user
if(empty($user_record)):
$user_record['id'] = $user['User']['id'];
$user_record['fbid'] = $this->facebook->get_loggedin_user();
$user_record['fbpassword'] = $this->__randomString();
$user_record['group_id'] = $user['User']['group_id'];
$this->User->save($user_record);
endif;
}
}
private function __randomString($minlength = 20, $maxlength = 20, $useupper = true, $usespecial = false, $usenumbers = true){
$charset = "abcdefghijklmnopqrstuvwxyz";
if ($useupper) $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ($usenumbers) $charset .= "0123456789";
if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";
if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength);
else $length = mt_rand ($minlength, $maxlength);
$key = '';
for ($i=0; $i<$length; $i++){
$key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
}
return $key;
}
Ini merupakan hasil akhir yang ada pada file AppController.php saya.
<?php
App::import('Vendor', 'facebook/facebook');
class AppController extends Controller {
var $components = array('Acl', 'Auth');
var $uses = array('User');
var $facebook;
var $__fbApiKey = '7d8e96e4ddf047b5611f5fcbaee04133';
var $__fbSecret = '56480e8655ceecaa36ad2e599bda3604';
function __construct() {
parent::__construct();
// Prevent the 'Undefined index: facebook_config' notice from being thrown.
$GLOBALS['facebook_config']['debug'] = NULL;
// Create a Facebook client API object.
$this->facebook = new Facebook($this->__fbApiKey, $this->__fbSecret);
}
function beforeFilter() {
// Configure AuthComponent
$this->Auth->authorize = 'actions';
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'pages', 'action' => 'display');
// check to see if user is signed in with facebook
$this->__checkFBStatus();
// send all user info to the view
$this->set('user', $this->Auth->user());
$this->Auth->allowedActions = array('display');
}
private function __checkFBStatus(){
//check to see if a user is not logged in, but a facebook user_id is set
if ( !$this->Auth->User() && $this->facebook->get_loggedin_user() ) {
//see if this facebook id is in the User database; if not, create the user using their fbid hashed as their password
$user_record =
$this->User->find('first', array(
'conditions' => array('fbid' => $this->facebook->get_loggedin_user()),
'fields' => array('User.fbid', 'User.fbpassword', 'User.password'),
'contain' => array()
));
//create new user
if(empty($user_record)):
$user_record['fbid'] = $this->facebook->get_loggedin_user();
$user_record['fbpassword'] = $this->__randomString();
$user_record['group_id'] = 3; // we have to set group_id manually here, put the lowest level
$user_record['password'] = $this->Auth->password($user_record['fbpassword']);
$this->User->create();
$this->User->save($user_record);
endif;
//change the Auth fields
$this->Auth->fields = array('username' => 'fbid', 'password' => 'password');
//log in the user with facebook credentials
$this->Auth->login($user_record);
}
// if user is logged in, and fb also logged in
elseif ( $this->Auth->User() && $this->facebook->get_loggedin_user() ) {
$user_record = $this->User->find('first', array('conditions' => array('User.id' => $this->Auth->User('id'))));
//create new user
if(empty($user_record)):
$user_record['id'] = $user['User']['id'];
$user_record['fbid'] = $this->facebook->get_loggedin_user();
$user_record['fbpassword'] = $this->__randomString();
$user_record['group_id'] = $user['User']['group_id'];
$this->User->save($user_record);
endif;
}
}
private function __randomString($minlength = 20, $maxlength = 20, $useupper = true, $usespecial = false, $usenumbers = true){
$charset = "abcdefghijklmnopqrstuvwxyz";
if ($useupper) $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ($usenumbers) $charset .= "0123456789";
if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";
if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength);
else $length = mt_rand ($minlength, $maxlength);
$key = '';
for ($i=0; $i<$length; $i++){
$key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
}
return $key;
}
}
?>
Default.ctp
File seterusnya yang kita perlu edit ialah D:\xampp\htdocs\fbconnect\views\layouts\default.ctp. Cari kod
<html xmlns="http://www.w3.org/1999/xhtml">
dan gantikan dengan
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
Dan tambahkan kod di bawah ini di bahagian <head>
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"></script>
<script type="text/javascript">
FB.init("7d8e96e4ddf047b5611f5fcbaee04133","<?php echo FULL_BASE_URL; ?>/xd_receiver.htm");
function logout()
{
FB.Connect.logout( function() {
window.location = '<?php echo FULL_BASE_URL; ?>/users/logout';
});
return false;
}
</script>
Nota: Jangan lupa tukarkan API Key anda!
Sekarang kita perlukan kod untuk button Facebook Connect, masukkan kod dibawah ini pada mana mana view yang sesuai. Saya gunakan file default.ctp yang sama untuk memudahkan pembelajaran.
<?php
if(empty($user)):
echo $form->create('User', array('action' => 'login'));
echo $form->inputs(array(
'legend' => __('Login', true),
'username',
'password'
));
echo $form->end('Login');
echo '<fb:login-button onlogin="window.location.reload();"></fb:login-button>';
else:
echo $user['User']['name'] . '<br />';
echo $html->link('Logout', '#', array('onclick' => 'logout();'));
if($user['User']['fbid'] == 0) :
echo '<fb:login-button onlogin="window.location.reload();"></fb:login-button>';
endif;
endif;
?>
Sekarang kita boleh test Facebook Connect kita. Katakan kita dah ada satu user dalam database, kemudian dia login, dia masih nampak button Facebook Connect dan boleh gunakan fungsi tersebut. Dan kita akan add Facebook ID dia lepas connect. Jadi kita bukan saja boleh add new user, tapi boleh integrate existing user yang ada.
Download Sample Code
Boleh download di sini: http://bit.ly/aeuwSy
Isu Yang Dikenalpasti
Lepas user yang dah login tu Connect, button FB Connect tetap wujud. Kena refresh page baru dia hilang. Boleh buang guna javascript, tapi tak disertakan di sini, minta maaf.
Kredit
Artikel asal yang menunjukkan cara menggunakan Facebook Connect oleh CutFromTheNorth.com. Pautan untuk article asal di sini.

Pingback: Tweets that mention Cara memasang Facebook Connect di CakePHP « syahzul -- Topsy.com