Manual Kohana 1
Manual Kohana 1
Kohana es un Framework PHP, es decir: un entorno de trabajo prefabricado que ya nos soluciona algunos de los problemas ms tpicos de la programacin. Como me gusta avanzar programando, programaremos desde la primera lnea. Para ello vamos a tener como objetivo la creacin de un ToDoList Manager, es decir: vamos a crear una web que nos permita gestionar tareas. En el ejemplo se acceder a base de datos. Debo decir que me ha costado mucho encontrar ejemplos vlidos que accedan a base de datos.
Prerrequisitos
Voy a utilizar Kohana versin 3.0.8. Seguramente sea compatible con las siguientes.
Un poquito de teora
Kohana sigue un patrn Modelo-Vista-Controlador (MVC). Hay mucho escrito sobre este patrn, por lo que no me extender demasiado: Modelo: Los datos tal cual se guardan. Vista: La representacin en la pantalla. Controlador: La lgica de negocio.
Configuracin
Vamos a configurar Kohana. Hemos desplegado el framework y vamos al fichero application/bootstrap.php, en el que vamos a habilitar algunas cosas. No podis copiar a ciegas; aqu slo os doy un ejemplo de lo que tengo yo puesto. Tened tambin en cuenta que no lo pego entero, ya que nos valen la mayor parte de los valores por defecto:
<?php Kohana::init(array( 'base_url' => '/~miguel/kohana', 'index_file' => 'index.php', )); Kohana::modules(array( 'database' => MODPATH.'database', 'orm' => MODPATH.'orm', )); ?> // Database access // Object Relationship Mapping
Como es sencillo, voy rpido: Le decimos a Kohana dnde est nuestra aplicacin y cul es el archivo que va a renderizar las cosas. Como vis, yo lo tengo en /~miguel/kohana. Despus habilitamos algunos mdulos, que servirn para acceder a base de datos.
Si sois tan pijos como yo y os gustan las URLs limpias, mejor si indicis el index_file de la manera que se indica arriba y despus creis un .htaccess como el siguiente:
# Turn on URL rewriting RewriteEngine On # Installation directory RewriteBase /~miguel/kohana/
Order Deny,Allow Deny From All # Protect application and system files from being viewed RewriteRule ^(?:application|modules|system)\\b.* index.php/$0 [L] # Allow any files or directories that exist to be displayed directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # Rewrite all other URLs to index.php/URL RewriteRule .* index.php/$0 [PT]
Finalmente, configuramos la base de datos en el archivomodules/database/config/database.php. Ya tenis un patrn y es autoexplicativo. Centraros en default y olvidaros de alternate (o borradlo si queris).
El modelo
El modelo es lo que existe en la base de datos, bsicamente. As que comenzamos por crear una base de datos:
CREATE TABLE `tasks` ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'title' varchar(60) NOT NULL, 'description' longtext NOT NULL, 'created' datetime NOT NULL, 'duedate' datetime DEFAULT NULL, PRIMARY KEY ('id'), UNIQUE KEY 'title' ('title') ) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
Ahora tenemos que decirle a Kohana que use esta tabla. Para ello basta crear el archivo application/classes/model/task.php:
<?php defined("SYSPATH") OR die("No Direct Script Access"); class Model_Task extends ORM { } ?>
Bien. Paremos. Para qu queremos un archivo vaco? Realmente no est vaco. Para empezar, estamos restringiendo el acceso. Todos
nuestros archivos PHP salvo las vistas deberan comenzar as, por seguridad. Adems, estamos heredando de ORM, y esta clase padre ya nos dar todo lo que necesitamos: acceder a la base de datos y ver qu campos necesitamos aqu. Personalmente, tanto automatismo no me gusta demasiado y prefiero indicarle qu tabla es la que quiero emplear:
<?php defined("SYSPATH") OR die("No Direct Script Access"); class Model_Task extends ORM { public $_table_name = "tasks"; } ?>
El Controlador
Creamos el archivo application/classes/controller/task.php:
<?php defined('SYSPATH') OR die('No Direct Script Access'); class Controller_Task extends Controller { public function __construct(Kohana_Request $request) { parent::__construct($request); } public function action_index () { $vista = View::factory('task_index'); $vista->set ('task_list', $this->get_tasklist()); $this->request->response = $vista; } public function action_add () { $vista = View::factory('task_add'); $this->request->response = $vista; if ( ! isset($_POST) OR ! array_key_exists('title', $_POST)) return; if ( $this->create_task () ) $vista->set ('message', 'Task added'); else $vista->set ('message', 'Error al aadir'); } private function create_task () { $newtask = ORM::factory('task'); $newtask->title = $_POST['title']; $newtask->description = $_POST['description']; $newtask->created = strftime('%Y-%m-%d %H.%M.%S'); $newtask->duedate = $this->getAsDate($_POST['duedate']); $newtask->save(); return $newtask->saved();
} private function getAsDate ($value) { $result = null; if (isset ($value)) { $result = $value." 00.00.00"; } print_r($result); return $result; } private function get_tasklist () { $tasks = ORM::factory('task')->find_all(); $result = array(); foreach ($tasks as $task) $result[] = $task; } } ?> return $result;
Analicemos un poco este cdigo. Lo primero de todo es la seguridad, por lo que evitamos el acceso directo. A continuacin se crea una clase Controller_Task que hereda deController. El nombre de la clase est sujeto a una convencin de nombres, y heredamos de Controller porque somos un controlador :D El constructor no tiene mucho misterio: tenemos que implementarlo y llamamos al constructor padre. No tenemos nada ms que inicializar, por lo que podemos terminar. La funcin action_index es, como el nombre indica, una accin. Ser la accin por defecto que se ejecute cuando alguien realice una solicitud sobre el controlador. Si simplificamos su cdigo hasta un simple echo hola;, podremos comprobar que todo funciona accediendo a la misma direccin que pusimos en la configuracin, en base_url, seguido del nombre bsico del controlador, es decir, task. En mi caso, la direccin eshttp://localhost:/~miguel/kohana/task. Si no habis activado las URLs limpias, tendris que indicar quin debe renderizar esa pgina, accediendo a algo como http://localhost:/~miguel/kohana/index.php/task . Como vemos, la accin action_index crea una vista a partir de una plantilla y la devuelve como respuesta. Veremos ms sobre estas vistas en el apartado siguiente. La accin action_add va a tratar de crear una tarea nueva. Adems, voy a reutilizar esta funcin. Si viene sin datos, slo mostrar la ventana. Si viene con datos, crear una nueva tarea. Por ello, lo primero que hago es crear la vista que voy a devolver, ya que es comn a ambos casos de uso, y despus trato de insertarla, guardndome un mensaje en cada caso. La funcin create_task es quien realmente crea la tarea. Para ello hace uso del ORM, obteniendo los valores de la variable $_POST. Las fechas tengo que
modificarlas a mano para que tengan el formato esperado por mysql (YYYY-MM-DD hh.mm.ss). La funcin get_tasklist serializa la lista de tareas para pasrsela a la vista.
Cosas importantes
Aqu hay dos cosas importantes: el uso de la base de datos y el paso de parmetros con la vista. Para usar la base de datos, estamos usando el ORM. ste estbastante bien documentado. Para obtener datos de la vista, los obtenemos de la variable $_POST, ya que ste ha sido el mtodo que he decido utilizar para el envo de datos (y suele ser el ms recomendable). Los nombres de los campos son los que he puesto en la vista y que veremos ms adelante. Para enviar datos a la vista, lo que hago es establecerlos al objeto View con la funcin set. Esto funcionar como una tabla Hash cuando est en la vista.
Las vistas
Antes de entrar en materia, como no me gusta repetirme, crearemos un par de archivos. Todas las vistas deben ir en application/views. Los dos archivos a crear no tienen mayor misterio y no entrar a describirlos:
header.php
<!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>Vista para Kohana PHP <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jqueryui.css" rel="stylesheet" type="text/css"/> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jqueryui.min.js"></script> <script type="text/javascript"> Date.firstDayOfWeek = 1; Date.format = 'yyyy/mm/dd'; $(document).ready(function() { $(".date").datepicker({ dateFormat: 'yy-mm-dd', firstDay: 1 }); }); </script> </head> <body>
footer.php
</body> </html>
S, hago algo de uso de jquery, pero no os asustis que slo es para la insercin de fechas. El resto de la aplicacin ser horrible :-P Vamos con el ndice:
task_index.php
<?php include 'header.php'; ?> <table> <thead> <tr> <th>Title <th>Creation <th>Due date <th>Planned date <th>Completed </tr> </thead> <tbody> <?php foreach ($task_list as $task) { echo ""; echo ''.$task->title.""; echo "".$task->created.""; echo "".$task->duedate.""; echo ""; } ?> </tbody> </table> <?php echo "".html::anchor("task/add","Add new task"); ?> <?php include "footer.php"; ?>
Como en la funcin del controlador action_index insertamos la variable $task_list, ahora podemos recuperarla y recorrerla. De esta manera creamos una vista horrible. Dejo como tarea ponerla bonita, ya que eso no es el tema de este tutorial. Nos queda poder aadir tareas (task_add.php):
<?php include 'header.php'; ?> <?php if (isset($message)) { print $message; } print html::anchor('task','List of tasks'); print print print print form::open(); form::label('title', 'Ttulo'); form::input('title'); form::textarea('description');
form::label('duedate', 'Due Date:'); form::input('duedate', null, array ('class'=>'date') ); form::submit('submit', 'Send'); form::close();
En este caso he creado un formulario utilizando las funciones de Kohana. Como vis, los nombres de los campos se corresponden con los que utilic en la funcin create_task.
Fin
Como decan en en 1,2,3 hasta aqu puedo leer. Como primera aplicacin me parece mucho ms interesante que el triste hola mundo, ya que tiene todos los componentes de una aplicacin real: modelo, vista y controlador (el hola mundo no tiene ms que controlador), acceso a bases de datos, etc. No he entrado con el update_task ya que no es ms complicado que el create_task. Lo dejo como ejercicio. Habr segunda parte de este tutorial.
Referencias
No hay mucha documentacin de Kohana. Sin embargo, el ORM de Kohana s est bien documentado y no creo que tengis mayor problema con esa parte. Siempre prefiero utilizar sistemas que me eviten el SQL a mano, ya que ste puede tener sql-injection. Acordos de seguir las convenciones. Tambin podis echar un vistazo a otros tutoriales, como el de Ajaxman o el de Christian Gil, sin contar los tutoriales de la propia pgina de Kohana. Espero que os haya resultado interesante.