miércoles, 18 de agosto de 2010

Construyendo un sitio con KumbiaPHP (3)


En la entrada anterior vimos un ejemplo sencillo en kumbiaPHP donde trabajamos con vistas, partials, algunos helpers (por ejemplo link_to()). En fin, un ejemplo sencillo para ir poniéndonos en contexto con kumbia.

Tal como prometí, en esta entrada vamos a comenzar a trabajar con controladores, además retomando nuestro objetivo que no es otro que el hacer aplicaciones para twitter. Vamos a realizar una aplicación en kumbia que se conecte a twitter y permita realizar actualizaciones de estado (similar a lo que hicimos en la entrada Un nuevo comienzo, pero ahora con kumbia y mejorando algunas cosillas).


¿Qué asumo?

Asumo que has ido leyendo las entradas y que por tanto tienes:
1) Una aplicación registrada en twitter
2) El ejemplo de la entrada anterior corriendo en tu servidor web

En lo que resta de entrada, voy a asumir que hemos llamado a nuestro directorio web 'tutuitero', tal como en la entrada anterior.


Manos a la obra

Lo primero que debemos hacer es copiar nuestra Twitter Class (el archivo twitter.php) dentro del directorio app/libs, pues éste es el directorio para almacenar todas las librerías externas a kumbia.

La versión actual de twitter.php tiene un bug, ya conocido por Tijs Verkoyen, que debemos reparar. No es nada del otro mundo, vamos a la línea 231 de twitter.php y sustituimos:

private function calculateHeader(array $parameters, $url)

por:

private function calculateHeader(array $parameters, $url=self::API_URL)

Por comodidad, también he guardado en el directorio app/libs el archivo config.php, que recordemos contiene el consumerKey/consumerSecret de nuestra aplicación y la url de Callback. Ya veremos como vamos a utilizar estos datos.


Creando nuestros controladores

Ahora procedemos a crear nuestros controladores. Lo que vamos a hacer es crear un controlador para manejar todo el asunto de la conexión a twitter con Oauth, que luego podamos invocar desde cualquier otro lugar. Para que queden claros los conceptos, voy a crear otro controlador desde donde vamos a hacer 2 cosas en principio: enviar actualizaciones de estado y ver nuestro timeline.

Comencemos entonces creando nuestro controlador oauth_controller.php, dentro de app/controllers. ¿Qué va a hacer nuestro controlador? Si recordamos lo publicado en la entrada Nuevo comienzo, para realizar una actualización de estado, teníamos una variable de la clase twitter, a la cual por decirlo de alguna forma, autorizábamos (con un Access Token) y luego sobre esa variable invocábamos una función que se utilizaba la API de twitter para realizar la actualización de estado.

Ahora vamos a tener posiblemente varias páginas que van a realizar diferentes tareas (en cada una tendremos al menos una instancia de la clase twitter), queremos tener almacenados en sesión los datos de conexión para utilizarlos en todo nuestro sitio, y no tener que autorizar cada vez que vayamos a hacer algo. Bien, nuestro oauth_controller será el encargado de esta tarea.

oauth_controller se encargará de verificar si están en sesión los datos de acceso, en caso de no estarlos, se conectará a twitter, pedirá autorización al usuario y una vez otorgada, almacenará los datos correspondientes en la sesión del navegador. Voy a colocar el código y luego explicaré los aspectos relevantes:

<?php
Load
::lib("twitter");
Load::lib("config");

class
OauthController extends ApplicationController {

protected
$consumerKey;
protected
$consumerSecret;
protected
$callBack;

public function
initialize()
{
$this->callBack = OAUTH_CALLBACK;
$this->consumerKey = CONSUMER_KEY;
$this->consumerSecret = CONSUMER_SECRET;
}

public function
index()
{

// crear instancia
$twitter = new Twitter($this->consumerKey, $this->consumerSecret);

// Si no tengo tokens de acceso
if (empty($_SESSION['oauth_token']) || empty($_SESSION['oauth_token_secret']))
{
// get a request token
$twitter->oAuthRequestToken($this->callBack);

// authorize
if((!isset($_GET['oauth_token'])))
$twitter->oAuthAuthorize();

// get tokens
$token = $twitter->oAuthAccessToken($_GET['oauth_token'], $_GET['oauth_verifier']);

$_SESSION['oauth_token'] = $token['oauth_token'];
$_SESSION['oauth_token_secret'] = $token['oauth_token_secret'];

}
else
{
$token['oauth_token'] = $_SESSION['oauth_token'];
$token['oauth_token_secret'] = $_SESSION['oauth_token_secret'];
}

// set tokens
$twitter->setOAuthToken($token['oauth_token']);
$twitter->setOAuthTokenSecret($token['oauth_token_secret']);

}

}

Como vemos, el código se parece mucho a lo que hemos trabajado antes. Entre las cosas nuevas, tenemos la invocación de nuestras librerías, la cual se realiza mediante la función Load::lib(nombre_de_nuestra_biblioteca);

Luego nos conseguimos con la función initialize(), la cual es una función especial, que se ejecuta antes de invocarse el controlador. En este caso, la hemos utilizado para asignar los valores definidos en config.php.

Luego viene la función index(), en la cual tenemos nuestro algoritmo de verificación de credenciales, conexión a twitter y almacenamiento de credenciales.

Eso es básicamente nuestro controlador. Ahora veamos como sería la vista. Yo simplemente voy a colocar un mensaje que diga que la conexión ha sido exitosa y que muestre un enlace a nuestra página de actualización. Asumo que ya sabemos manejar vistas, pero para recapitular recordamos lo que hay que hacer: crear un subdirectorio oauth dentro de app/views, y dentro de este directorio creamos un archivo index.phtml (pues nuestro controlador sólo tiene una acción, y se llama index). El contenido de este archivo será el siguiente:

<div class="textboxright">
<h2>Conexi&oacute;n exitosa</h2>
<br>
<p>Se ha establecido una conexi&oacute;n exitosa con twitter, utilizando Oauth.</p>
<p><?php echo link_to('twitter/update/', 'Actualizar Estado') ?></p>
</div>

Acá estamos redireccionando hacia una vista que aún no hemos creado, nuestra vista de update. Si queremos probar nuestro oauth, podemos ir a la dirección:
http://localhost/tutuitero/oauth/

Lo que ocurrirá es que al cargar la página, el controlador se dará cuenta que no tenemos autorización, automáticamente redireccionará el navegador al sitio de twitter, y una vez obtenida la autorización nos redireccionará a la dirección del callback (yo en mi config.php he puesto la misma dirección, http://localhost/tutuitero/oauth/). Finalmente veremos el texto que colocamos en la vista, incluyendo el enlace al sitio que aún no hemos creado. Vamos a por él.


Nuestro segundo controlador

Ahora vamos a hacer nuestro segundo controlador. Dijimos que este controlador en un principio va a tener 2 funciones (y por tanto 2 vistas): una para enviar actualizaciones de estado a twitter y otra para ver nuestro timeline. Empecemos por la primera.

<?php
class TwitterController extends ApplicationController {

public function
update() {

if (empty(
$_SESSION['oauth_token']) || empty($_SESSION['oauth_token_secret']))
{
return
$this->route_to('controller: oauth', 'action: index');
}
else
{
Load::lib("twitter");
Load::lib("config");
$twitter = new Twitter(CONSUMER_KEY, CONSUMER_SECRET);
$twitter->setOAuthToken($_SESSION['oauth_token']);
$twitter->setOAuthTokenSecret($_SESSION['oauth_token_secret']);

if(
$this->request('twitter-msg'))
{
$twitter->statusesUpdate($this->request('twitter-msg'));
}

}

}

}
?>

El código se explica solo. Lo primero que verificamos es si en sesión tenemos nuestro Access Token, y de no ser así, utilizamos el helper router_to(), para redireccionar a oauth que se encargará del proceso de conexión a twitter. En caso de existir los tokens en sesión, invocamos nuestras librerías, creamos una instancia de la clase twitter y asignamos los tokens. Finalmente, utilizamos el método request(), para verificar si por get/post el controlador está recibiendo la variable 'twitter-msg', y en caso afirmativo, realizar la actualización a twitter, utilizando la función statusesUpdate().

Veamos ahora la vista:

<div class="textboxright">
<h2>Actualizar Status</h2>

<?= form_tag('twitter/update') ?>

<br>
<?= textarea_tag('twitter-msg', 'size: 80', 'rows: 2', 'cols: 60') ?>
<?= submit_tag('Update!') ?>

<?= end_form_tag() ?>

</div>

Aquí estamos creando un formulario con un textArea y un botón de submit. Importante que el nombre (primer parámetro) de nuestro textArea sea 'twitter-msg', pues este es el nombre que espera nuestro controlador.


Pequeña recapitulación

La entrada se ha vuelto un poco larga, por lo que voy a dejar la segunda parte de lo prometido (mostrar nuestro TL) para la próxima. Lo importante de esta entrada es que:
  1. Por primera vez hemos utilizado nuestros controladores para hacer algo.
  2. En nuestro controlador oauth_controller.php tenemos el algoritmo de conexión que probablemente utilizaremos sin necesidad de cambiar de ahora en adelante.
  3. Con nuestro 'update', por primera vez enviamos información desde la capa de Vista hacia la capa de Controlador, utilizando un formulario.
Más tarde, cuando mostremos nuestro timeline en una vista haremos lo contrario a lo que hicimos con 'update', pues, pasaremos información desde nuestro controlador hacia la vista.


Nota sobre los controladores y modelos

Desde que comencé a hablar de Kumbia, traté el tema de la flexibilidad y sencillez del framework. Hasta el momento no hemos hecho uso de la capa de Modelo, lo cual básicamente está mal, si estamos basándonos en una filosofía MVC. Sin embargo, hemos hecho cosas muy sencillas, y que luego podremos corregir si queremos apegarnos estrictamente a la teoría.

En breve espero estar haciendo pruebas con conexiones a bases de datos, y seguramente tocaré el tema de los modelos, y de por qué un modelo no es necesariamente una base de datos (también revisaré algunas de las cosas que hemos hecho violando las 'leyes' de la arquitectura MVC).

Espero que haya sido útil la entrada, y agradecido con cualquier comentario, duda o sugerencia.


0 comentarios:

Publicar un comentario