Paginación en PHP fácil y rápida

Read More
Formulario actualizar foto

Con este tutorial mostraremos como realizar la paginación en PHP de un listado de usuarios usando nuestro framework favorito KumbiaPHP. Utilizaremos como base el proyecto anterior, donde mostramos como subir una imagen y asignarla a un usuario, y cambiaremos el listado normal por un listado paginado.

En el controlador

Lo primero es mencionar que el ActiveRecord cuenta con un paginador muy bueno(Ver sección en el manual: Paginando en ActiveRecord), que nos permitirá con una sola línea de código implementar la paginación en php. Vamos al controlador de usuarios y añadimos la función page(…):

Archivo: app/controllers/user_controller.php


public function page(int $page = 1)//validación 'int' con php7
{        
    $this->page = (new User)->paginate("page: $page", 'per_page: 7');
}

El parametro $page tiene un valor por defecto, así que, si no le pasamos ningun valor será igual a 1. En el llamado a la función paginate() el primer parámetro es page, con el cual le indicamos el número de página que deseamos mostrar. El segundo parámetro es per_page, con el cual le indicamos el número de elementos a mostrar por página.

Continue reading «Paginación en PHP fácil y rápida»

ScaffoldController: Modificando vistas

Hasta aquí hemos invertido tiempo en revisar el uso básico del ScaffoldController con KumbiaPHP creando nuestros CRUDs de forma rápida, modificando el estilo de las vistas (al añadir un nuevo conjunto de vistas que cargan mediante la variable de controlador $scaffold), y reemplazando comportamientos particulares para modificar el conjunto de datos (al reescribir el método index).

Nueva meta u objetivo usando ScaffoldController

Este post tiene por objetivo hacer un resumen de lo que ya hemos visto en las entregas anteriores, y sacar aún más partido al uso de scaffolding con nuestro framework, de tal manera que puedas aplicar los conceptos que se describen en otras situaciones y así buscar mantener el principio DRY: No te repitas.

En sí, el uso de Scaffolding es una declaración clara del principio DRY, pues lo usamos para no tener que copiar y pegar comportamientos que son inherentes a diferentes situaciones: como crear, actualizar, eliminar y listar registros de una tabla (a modo de ejemplo, podríamos crear controladores scaffolding o heredables para otras tareas que no sean siempre la gestión de datos en tablas).

A modo de añadir más fuerza al principio, los frameworks de desarrollo web se han creado basándose primariamente en dicha idea: escribir lo necesario, evitando repetir comportamientos, y por ende se disminuye el número de líneas de código, el nivel de errores y, por ende, el tiempo de desarrollo y mantenimiento de los sistemas o aplicaciones creados con ellos.

Por eso es que existe una clasificación de carpetas: para controladores, modelos, vistas, ayudantes (helpers), librerías particulares, y librerías externas (vendors).

Si necesita comprender más los conceptos básicos de nuestro framework puede ver Kumbia Essentials.

Manos a la obra

Como ya se mencionó, un scaffolding es una estrategia para no repetir código que se usa en labores comunes. Hasta aquí lo hemos usado para tener un CRUD de la tabla que representa las categorías, y también nos ha permitido sobrescribir la forma en que hacemos la presentación de la acción index (listar los registros de la tabla).

Ahora iremos un poco más lejos

  1. Modificaremos la vista particular de la acción index.
  2. Sobrescribiremos nuestro controlador para modificar el comportamiento al guardar y actualizar los registros.

El cliente nos pide modificar la visualización de la lista de categorías para quitar de ella los atributos de fecha y renombrar el atributo nombre y categorías por Nombre Categoría y Categoría Padre. También nos solicita modificar el comportamiento de la acción crear para que el formulario aparezca limpio para agregar nuevamente, en vez de viajar a index una vez enviado el formulario.

De igual forma debe hacerse para que la acción editar recargue el formulario modificado en vez de viajar a index. Iremos de lo fácil a lo menos fácil.

Continue reading «ScaffoldController: Modificando vistas»

ScaffoldController: Modificando comportamientos y contenidos

Read More
Vista index con categoría relacionada como texto

La entrega anterior hablamos acerca del uso de la técnica de Scaffolding para CRUD con KumbiaPHP usando la clase ScaffoldController. Espero que muchos se hayan sorprendido gratamente con la funcionalidad que ciertamente ahorra mucho trabajo rutinario, ya que es altamente flexible.

Para que se entusiasmen, dentro de las posibilidades  tenemos: reescribir métodos y modificar comportamientos en controladores, modificar los archivos de vista, e incluso puedes crear tus propios scaffoldings. Pero bueno, vamos paso a paso.

Manos a la obra con ScaffoldController

Vamos a trabajar en base a supuestos. Supongamos que queremos mostrar el nombre de la categoría padre para aquellas categorías que estén anidadas.

Lista de categorías

Como se ve en la lista, las categorías relacionadas sólo se ven con su identificador.
Por lo tanto, vamos a modificar la fuente de datos que pasamos a la vista Index para que ésta pueda presentar los contenidos respectivos.

En el modelo

Lo que vamos a hacer es crear un método que cumpla con lo que queremos lograr: mostrar el contenido de la tabla de categorías incluyendo el nombre de la categoría padre en aquellas categorías que heredan de otra. De este modo tendremos una modificación como la siguiente:

Archivo: models/categorias.php

<span class="token delimiter"><?php</span>

<span class="token keyword">class</span> <span class="token class-name">Categorias</span> <span class="token keyword">extends</span> <span class="token class-name">ActiveRecord</span> 
<span class="token punctuation">{</span>

    <span class="token keyword">function</span> <span class="token function">getCategorias</span><span class="token punctuation">(</span><span class="token variable">$page</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> 
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">paginate</span><span class="token punctuation">(</span>
            <span class="token string">'columns: categorias.id, categorias.nombre, cat.nombre as categorias_id, categorias.creada_at, categorias.actualizada_in'</span><span class="token punctuation">,</span> 
            <span class="token string">'join: left outer join categorias cat on categorias.categorias_id = cat.id'</span><span class="token punctuation">,</span>
            <span class="token string">"page: $page"</span><span class="token punctuation">,</span> <span class="token string">'order: categorias.id desc'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>

En el controlador

El segundo cambio lo haremos desde el controlador, para cargar los cambios que hemos hecho en el modelo. Lo que reemplazaremos (porque es una sobre escritura de index en ScaffoldController) será la función index tal como se muestra a continuación.

Archivo: controllers/categorias_controller.php

<span class="token delimiter"><?php</span>
<span class="token keyword">class</span> <span class="token class-name">CategoriasController</span> <span class="token keyword">extends</span> <span class="token class-name">ScaffoldController</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token variable">$model</span> <span class="token operator">=</span> <span class="token string">'Categorias'</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token variable">$page</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token variable">$this</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">data</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Categorias</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">></span><span class="token function">getCategorias</span><span class="token punctuation">(</span><span class="token variable">$page</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
 
<span class="token punctuation">}</span>

Continue reading «ScaffoldController: Modificando comportamientos y contenidos»

Scaffolding para CRUD (ABM) sencillos (y no tanto) – primera parte

Read More
Scaffolding para CRUD (ABM) sencillos (y no tanto) – primera parte

¿Qué es Scaffolding?

Cuando comenzó el fenómeno de los frameworks de desarrollo web, una de sus banderas de lucha estuvo de la mano de los scaffoldings (andamios).

Un scaffold es en sí una técnica que proveen muchos frameworks, con la que podrás tener un gestor de datos para una tabla particular escribiendo una cantidad mínima de código (en KumbiaPHP bastan 7 líneas de código – excluyendo 2 líneas de encabezado php – ).

En mis primeros años de kumbiero comencé creando un controlador para las acciones clásicas de CRUD (Create, Read, Update y Delete), un modelo para apuntar la tabla de la base de datos y al menos 3 archivos de vista (index, agregar y editar).

Para hacer el CRUD de otra tabla copiaba el controlador inicial en el nuevo, luego editaba todo lo que correspondía, y lo mismo hacía para el modelo y las vistas.

Como verán es un trabajo arduo, pero no es tanto trabajo… a menos que tengas más de 10 tablas.

Si pueden hacer el ejercicio de mirar el bosque desde lejos, casi todos los CRUDs creados tienen las mismas acciones, y usan las mismas vistas (con sus leves diferencias).

La iluminación

Fue entonces que un día de IRC (el chat que usábamos antes), los colegas del core de KumbiaPHP me presentaron a ScaffoldController.

Es un amigo silencioso, puesto que está alojado en default/app/libs, pero además es un amigo confiable, pues hereda de AdminController (eso quiere decir que si damos cierta habilidad de autenticación al AdminController, los controllers que hagamos usando ScaffoldController también estarán asegurados).

Configuración inicial

Si este es un proyecto que ha iniciado desde cero, deberá configurar el acceso a la base de datos antes de continuar.

Para eso usaremos el archivo default/app/config/database.ini. En él se definen los entornos de datos que usará nuestra aplicación, los que normalmente son: development (desarrollo) y production (producción)

Archivo databases.ini de KumbiaPHP

Los parámetros de configuración que debemos revisar son:

  • host: Nombre de red o dirección ip del equipo en el cual está instalada la base de datos.
  • username: usuario de la base de datos.
  • password: contraseña del usuario de la base de datos.
  • name: nombre de la base de datos.
  • type: el tipo de base de datos que usará el proyecto, como mysql, pgsql, oracle.

Para indicarle al proyecto que debe usar uno u otro entorno de base de datos, será necesario modificar el archivo de configuración default/app/config/config.php. De forma predeterminada la configuración del entorno de base de datos es ‘default’, pero lo dejaremos inicialmente como ‘development’.

Archivo config.php de KumbiaPHP

Lista la configuración, sigamos con la acción.

De la teoría a la acción

Bueno, mucho texto y poca acción (o como versa el dicho “mucho ruido y pocas nueces”).

En nuestro primer ejemplo usaremos la clásica tabla de categorías, con la siguiente estructura:


<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> categorias <span class="token punctuation">(</span>
 id <span class="token keyword">int</span><span class="token punctuation">(</span><span class="token number">11</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">AUTO_INCREMENT</span><span class="token punctuation">,</span>
 nombre <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">UNIQUE</span><span class="token punctuation">,</span>
 categorias_id <span class="token keyword">int</span><span class="token punctuation">(</span><span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
 creada_at <span class="token keyword">timestamp</span><span class="token punctuation">,</span>
 actualizada_in <span class="token keyword">timestamp</span><span class="token punctuation">,</span>
 <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

Ahora crearemos un modelo llamado Categorias.

Archivo: models/categorias.php


<span class="token delimiter"><?php</span>
<span class="token keyword">class</span> <span class="token class-name">Categorias</span> <span class="token keyword">extends</span> <span class="token class-name">ActiveRecord</span>
<span class="token punctuation">{</span>
<span class="token punctuation">}</span>

Y finalmente (sí, finalmente) añadiremos el controlador CategoriasController.

Archivo: controllers/categoria_controller.php


<span class="token delimiter"><?php</span>
<span class="token keyword">class</span> <span class="token class-name">CategoriasController</span> <span class="token keyword">extends</span> <span class="token class-name">ScaffoldController</span>
<span class="token punctuation">{</span>
 <span class="token keyword">public</span> <span class="token variable">$model</span> <span class="token operator">=</span> <span class="token string">'Categorias'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Continue reading «Scaffolding para CRUD (ABM) sencillos (y no tanto) – primera parte»

Subir imágenes y datos con el mismo formulario html

Read More
Actualizar foto de perfil
Actualizar foto de perfil

¡Hola Kumbieros! Hoy les traigo un tutorial básico para quienes deseen conocer como subir imágenes y datos con el mismo formulario. Es una pregunta recurrente que hemos tenido en nuestro chat de Slack y no es sencilla de responder por ese medio, por eso les presentaré un ejemplo práctico de la creación y actualización de usuario con foto de perfil.

Crearemos un modelo, un controlador y tres vistas, usaremos la librería Upload incluida en KumbiaPHP para gestionar la subida del archivo. Al final dejo el enlace con el código fuente en un repositorio en Github para que puedan ver el ejemplo completo, incluso descargarlo y ponerlo a funcionar.

Base de datos

Lo primero es la tabla en la base de datos:


CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL DEFAULT '0',
  `email` varchar(255) NOT NULL,
  `photo` varchar(255) DEFAULT 'default.png',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Modelo

Ahora el modelo que hereda de ActiveRecord para que nos de la capacidad de operaciones con la tabla de la base de datos:

Archivo: app/models/user.php


<?php

/**
* Clase para manejar los datos del usuario, tabla 'user'
*/
class User extends ActiveRecord 
{

}

Controlador

Ahora el controlador que nos permitirá pasar y recibir datos de las vistas. Arrancaremos con el listado de usuarios y para esto creamos la función index.

Archivo: app/controllers/user_controller.php


<?php
/**
 * Controlador para las acciones y vistas con el usuario
 */
class UserController extends AppController
{

    public function index()
    {
        $this->data = (new User)->find();
    }
}

Vistas

Y su respectiva vista.

Archivo: app/views/user/index.phtml


<h1>Lista de usuarios</h1>
<?= Html::linkAction('create', 'Crear', 'class="button"') ?>
<?php View::content() ?>
<?php if (count($data)) { ?>
    <table class="u-full-width">
        <thead>
            <tr>            
                <th>Nombre</th>
                <th>Edad</th>
                <th>Correo</th>
                <th>Foto</th>
                <th>Acciones</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($data as $item) { ?>
                <tr>
                    <td><?= $item->name ?></td>
                    <td><?= $item->age ?></td>
                    <td><?= $item->email ?></td>
                    <td><?= $item->photo ?></td>
                    <td><?= Html::linkAction("edit/$item->id", 'Editar') ?> | <?= Html::linkAction("update_photo/$item->id", 'Actualizar foto') ?></td>
                </tr> 
            <?php } ?>        
        </tbody>
    </table>
<?php } else { ?>
    <h2>No hay ningún registro</h2>
<?php } ?>

Continue reading «Subir imágenes y datos con el mismo formulario html»