Últimos artículos
Loading...
sábado, 23 de enero de 2010

HowTo: Facebook connect en KumbiaPHP

sábado, enero 23, 2010

Buenas compañeros, después de varios días de mucho trabajo al fin me hago un tiempo para publicar este post, hace ya varios días lo quería hacer pero  el tiempo es tirano :D

Si más vueltas vamos al grano. Les voy a mostrar como hacer una conexión desde Facebook Connect tomando algunos datos del usuario y agregarlo como usuario a nuestra web de manera automática, para hacer esto primero verificamos si el usuario existe, si no existe en nuestra BD lo agregamos y logeamos, de lo contrario si ya existe lo logeamos directamente. También esta el login normal de un usuario de nuestra web, no les voy a enseñar como hacer un registro de usuario ya que esto sale del alcance de este tutorial.

 Así  de simple y fácil.

¿Y que logramos con esto?  Creo que las ventajas saltan a la vista, nuestro nuevo usuario no necesita llenar el formulario de registro, solo con presionar el botón de FacebookConnect y aceptar,  automáticamente le creamos una cuenta y lo logueamos. ¿Supremo no? Bueno empecemos entonces.



Primero lo primero, los ingredientes:

  1. Una porción de KumbiaPHP(Spirit)
  2. Una cuenta de Facebook activa(nosotros mismos seremos el conejillo de indias) y para crear nuestra APP por supuesto.
  3. Conocimiento de Javascript(lo básico y necesario)
  4. Descargar la API de Facebook desde acá.
  5. Una lectura rápida a la Wiki oficial  
  6. Una buena taza de café y si hace calor una cerveza bien fría. Les aseguro que se van a divertir!

Preparación 

Una vez que descarguen la api de Facebook lo descomprimen y lo guardan como librería en su carpeta libs de su app.
Yo la he renombrado a fb



 Ahora vamos a Facebook y creamos una nueva app, en un tutorial anterior les mostré como hacerlo, para poder hacer nuestra conexión hay algunas variaciones. Quedaría de esta manera:




Obviamente reemplazan la ruta a donde va a estar alojada su aplicación en mi caso al hacer las pruebas en mi servidor local esta en http://anuncios.stc/kumbia mi app esta en la carpeta kumbia.

A partir de acá les voy a resumir un poco lo principal y las funciones de la api que podemos usar y como lo estoy usando para lograr los objetivos planteados que comente al principio del post. Al final del post les dejo la app completa para que puedan probarlo en su servidor local o vean la estructura de los archivos necesarios.

Esta es la estructura de nuestra base de datos. Como ven hay dos tablas, en la tabla users agregamos ademas un usuario de pruebas:

 User: admin
 Password : admin (en md5)

SQL table users
 CREATE TABLE IF NOT EXISTS `users` (

`id` int(11) NOT NULL auto_increment,

`fb_uid` int(11) default '0',

`email_hash` varchar(64) default NULL,

`login` varchar(50) NOT NULL,

`email` varchar(20) default NULL,

`password` varchar(35) default NULL,

`rol` tinyint(1) NOT NULL default '1',

PRIMARY KEY (`id`),

KEY `fb_id` (`fb_uid`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--

-- Volcar la base de datos para la tabla `users`

--

INSERT INTO `users` (`id`, `fb_uid`, `email_hash`, `login`, `email`, `password`, `rol`) VALUES

(1, 0, NULL, 'admin', 'admin@gmail.com', '21232f297a57a5a743894a0e4a801fc3', 0);


 SQL tabla comentarios
 CREATE TABLE IF NOT EXISTS `comentarios` (

`id` int(11) NOT NULL auto_increment,

`fb_uid` int(11) default '0',

`nombre` varchar(100) NOT NULL,

`fecha_at` varchar(15) NOT NULL,

`comentario` text NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

La segunda tabla es para insertar comentarios con los datos del usuario logueado para hacer pruebas.

Facebook Connect necesita un archivo necesario para hacer CrossBrowsing e intercambiar datos así que necesitamos crearlo, creamos un controller y una vista exclusivamente para mostrarle a Facebook connect donde esta nuestro archivo.

PHP connect_controller.php
 <?php 

class ConnectController extends ApplicationController{

function index(){

$this->render('xd_receiver', null);

}

}

Creamos nuestra vista

PHTML connect/xd_receiver.phtml
 <!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" >

<body>

<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>

</body>

</html>

Necesitamos llamar a la api de Facebook connect para poder trabajar con el framework Kumbiaphp mediante unos archivos Javascript que nos provee FBconnect,  asi que en nuestro template principal lo llamamos para que este disponible a lo largo de todo nuestro sitio

PHTML templates/default.phtml
 <!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" xmlns:fb="http://www.facebook.com/2008/fbml">

<head>

<?php echo stylesheet_link_tag('style') ?>

<?php echo stylesheet_link_tag('exception') ?>

<?php echo stylesheet_link_tags(); ?>

<head>

<meta http-equiv='Content-type' content='text/html; charset=<?php echo APP_CHARSET ?>' />

<title>Ejemplo de ZendGdata y facebook connect en kumbiaPHP</title>

<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/es_LA" type="text/javascript">

</script>

</head>

<body>

<div id='content'>

<?php View::partial('menu') ?>

<?php View::content(); ?>

</div>

<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(">>>aca-su-apiKey<<<<","/kumbia/connect/");

</script>

</body>

</html>


Tenemos ya lo básico para empezar.

Pasamos a nuestros controller, creamos un modelo para cada tabla asi que no hay más explicación para esto.

Nuestro controller principal, acá hacemos la magia :D

PHP login_controller.php
 <?php

class LoginController extends ApplicationController {

public function before_filter(){

if(Auth::is_valid()){

$this->redirect("inicio");

return false;

}

}

public function index() {

/* esta acción nos sirve para loguear a un usuario de nuestra web*/

if ($this->has_post('login','password')){

$login = $this->post("login");

$password = md5($this->post("password"));

$auth = new Auth("model", "class: users", "login: $login", "password: $password");

if ($auth->authenticate()) {

$user = $this->Users->find_by_login($login);

Session::set("userName",$user->login);

$this->redirect("inicio");

} else {

Flash::error("Falló el inicio de sesion");

}

}

}

public function loginfb(){

/* esta acción nos sirve para loguear a un usuario desde FBconnect*/

//cargamos nuestra libreria FBConnect

Load::lib('fb/facebook');

//leemos los datos de nuestro fb.ini

$keys = Config::read('fb');

$Facebook = new Facebook($keys['key']['application'], $keys['key']['keysecret']);

/*logueamos al usuario de manera automatica si ya lo tenemos

registrado de lo contrario lo cargamos a nuestra bd y lo logueamos*/

if($Facebook->get_loggedin_user())

{

$fid = $Facebook->require_login();

$user_details = $Facebook->api_client->users_getStandardInfo($fid, array('first_name'));

$nombre = $user_details[0]['first_name'];

/*encriptamos el fb_uid con md5 lo vamos a usar como password, este método no es del todo seguro, pero

nos servira para el ejemplo*/

$fb_uid = md5($fid);

$auth = new Auth("model", "class: users", "login: $nombre", "password: $fb_uid");

//en caso de lo encontremos en nuestra bd

if ($auth->authenticate()) {

$user = $this->Users->find_by_login($login);

Session::set("userName",$user->login);

$this->redirect("inicio");

} else {

// Si no esta en nuestra BD guardamos al nuevo usuario y lo logueamos.

$Users = new Users();

$Users->login = $nombre;

$Users->password = $fb_uid;

$Users->fb_uid = $fid;

if($Users->save()){

/*Guardamos al nuevo usuario, lo redirigimos a esta misma acción, como

el usuario ya existe en nuestra bd lo logueara de manera automatica*/

$this->redirect('login/loginfb');

} else {

//mensaje en caso de error

Flash::error('No se pudo cumplir la petición, intentelo de nuevo');

}

}

}

}

}



Nuestra vista respectiva a login_controller aca mostramos el formulario de inicio de sesión.

PHP login/index.phtml
 <?php View::content(); ?><br />

Inicio de Session O

<fb:login-button onlogin="location.href='/kumbia/login/loginfb'" length="long" v="2"><fb:intl>Conectate a kumbiaPHP con Facebook</fb:intl></fb:login-button>

<?php echo form_tag("login/index"); ?>

<label for="login">Login:</label>

<?php echo text_field_tag("login"); ?>

<br/>

<label for="password">Clave:</label>

<?php echo password_field_tag("password"); ?>

<br/>

<?php echo submit_tag("Ingresar"); ?>

<?php echo end_form_tag(); ?></p>

En cada controller que necesitemos que solo tenga acceso un usuario logueado le mostramos el formulario de login si no esta logueado. Por ejemplo el inicio_controller.php

Lo podemos hacer en nuestro Super Controller:  application_controller.php, para el caso práctico lo muestro en cada contoller ya que solo quiero que solo algunas secciones de la web necesiten un usuario registrado.

PHP inicio_controller.php
 <?php 

class InicioController extends ApplicationController{

public function before_filter(){

if(!Auth::is_valid()){

$this->route_to("controller: login");

return false;

}

}

function index(){

}

}

Una vez superado el proceso de login mostramos en cada vista los datos del usuario logueado, para esto hacemos uso de partials (pequeñas vistas que pueden ser incluidas en cualquier vista)

PHP views/partials/login.phtml
 <?php if(Auth::is_valid()){ ?>

Usted es el usuario numero

<?php print Auth::get('id'); ?> <br />

Su nombre es <?php print Auth::get('login'); ?>

<?php if(Auth::get('fb_uid') != 0){

print "Está logueado con su cuenta de Facebook!<br />";

print "<fb:profile-pic uid='".Auth::get('fb_uid')."' facebook-logo='true' size='small' ></fb:profile-pic><br />";

print "<fb:name linked='false' useyou='false' uid='".Auth::get('fb_uid')."'></fb:name><br />";

print "<a href='#' onclick='salir();'>Salir</a>";

}

else {print "Esta logueado con un usuario de la web. <br /> <a href='/kumbia/logout'>Salir</a>" ;} ?>

<script>

function salir(){

//Dependiendo del estado del usuario(conectado o no desde Fb) elegimos la forma de deslogueo

FB.Connect.get_status().waitUntilReady( function( status ) {

switch ( status ) {

case FB.ConnectState.connected:

FB.Connect.logoutAndRedirect("/kumbia/logout");

return false;

case FB.ConnectState.userNotLoggedIn:

location.href = '/kumbia/logout';

} });

}

</script>

<?php } else { ?>

Bienvenido a Los Kumbiatuts <a href="/kumbia/login">Login</a>

<?php } ?>

<hr />


Por ejemplo en cualquier vista llamaremos al partial de esta manera

PHP
  <?php View::partial('login') ?>   

Hasta acá la idea creo que está clara, para hacer el logout en este caso creé un nuevo controller:

PHP logout_controller.php
 <?php 

class LogoutController extends ApplicationController{

public function index(){

Auth::destroy_identity();

$this->route_to("controller: login");

}

}

Y bueno es lo principal y quizás lo más difícil de todo esto sea la lógica del sistema, así es como me lo planteo, cada uno puede tener otro razonamiento y hacerlo de distinta manera, solo es cuestión de probar.

Es un poco difícil explicar en palabras el funcionamiento, mejor seria que lo prueben online y se descarguen el Tuto completo de acá.

Nota: el usuario es user1 y el password admin

Está también el ejemplo de ZendGdata y las librerías en sus respectivas ubicaciones también un archivo de texto de ayuda. Y ya saben cualquier duda, corrección o sugerencia es más que bienvenida.


0 Comentarios:

Publicar un comentario

 
Toggle Footer