Una de las cosas que se aprecia constantemente entre las comunidades de desarrolladores, es la vaga idea que suele existir sobre el manejo del MVC donde solo se tiene en mente el concepto de wikipedia y demas sitios donde se conceptualiza sobre el tema.

Resulta bastante difícil, de acuerdo a mi experiencia y el roce que he tenido con personas del área, ir de la teoría a la implementacion del concepto de lo que es MVC parece ser una camino ofuscado en el que muchos se pierden. La gran mayoría suele decir “estoy claro en lo es MVC…”, pero cuando se ve la aplicabilidad se termina dando cuenta que lo que dijó “estoy claro…” es inversamente proporcional.

Filosofía de un Modelo

Estos son “Lógica de Negocio” y son parte fundamental para el momento que se desarrolla una aplicación, un buen uso de estos nos permiten un gran poder al momento que se necesita escalar, mantener y rehusar código en una aplicación.; es un concepto muy simple, pero la complicacion esta en comprender lo que significa “Logica de Negocio” ya que muchos piensan que la única forma de tener “Lógica de Negocio” va estrecha y únicamente relacionada con una conexión de Base de Datos y esto no es asi!

La práctica mas común (en todos los niveles, no solo me refiero a usuarios novatos) es que dejan la lógica en los controladores, a medida que se deja código de la lógica de negocio en un controlador trae consecuencias garrafales a largo plazo siendo imposible su reutilizacion, traduciendoce en una mala implementacion (código espaguetti). Lo antes expuesto no es precisamente lo que fomenta MVC y POO donde la idea fundamental es el orden y reutilización del código.

Veamos un par de ejemplos para contextualizar.

El primero es un Modelo donde su lógica de negocio esta en una Base de Datos y por ende necesitamos una conexion a motor para trabajar con esa fuente de datos.

class Articulos extends ActiveRecord {
	public function ver($page=1,$ppage=10){
		return $this->paginate('order: creat_at desc',
					"page: $page",
					"per_page: $ppage");
	}
	public function ultimos($limit=10) {
		$today = date('now');
		return $this->find('order: creat_at desc',
				   "conditions: data >= $today",
                                    "limit: $limit");
        }
}

Lo que mencionamos arriba sobre la re-utilización de código y característica fundamental de la POO, si vemos el método ultimos() del modelo Articulos nos sirve para crear un RSS, widget (Partial en KumbiaPHP) con los artículos recientes, etc. es decir donde se necesite los últimos artículos.

El segundo es un Modelo para el manejo de fotos y su la lógica de negocio no esta ligada a una BD.

<?php
/**
* Carga la libreria upload
**/
Load::lib('upload');
/**
* Carga la libreria wideimage
**/
//Load::lib('wideimage');
/**
* Modelo para manipular las fotos de las personas
*
**/
class Foto
{
    /**
* Guarda la foto de una persona
*
* @param string $id id de la foto al guardar
* @param string $file nombre de la foto
* @return boolean
**/
    public function save ($id, $file)
    {
        if ($_FILES[$file]['error'] > 0) {
            Flash::error('Error: No se ha logrado subir el archivo');
            return false;
        }
        if (! in_array($_FILES[$file]['type'], array('image/jpeg' , 'image/pjpeg' , 'image/gif' , 'image/png'))) {
            Flash::error('Error: Solo se admiten imagenes JPEG, PNG y GIF');
            return false;
        }
        if ($_FILES[$file]['size'] > 600 * 1024) {
            Flash::error('Error: No se admiten imagenes superiores a 600KB');
            return false;
        }
        if (Upload::image($file, "$id.jpg")) {
            $file_path = APP_PATH . "public/img/upload/$id.jpg";
            // con marca de agua
            // $watermark = wiImage::load(APP_PATH . "public/img/logo.png");
            // wiImage::load($file_path)->resize(160, 213, 'fill')->merge($watermark, 40, 175)->saveToFile($file_path);
            wiImage::load($file_path)->resize(160, 213, 'fill')->saveToFile($file_path);
            chmod($file_path, 0777);
            return true;
        }
        return false;
    }
    /**
* Busca la foto y en caso de que exista retorna la ruta relativa respecto al directorio de imagenes
*
* @return string $id
* @return string
**/
    public function get ($id)
    {
        if (is_file(APP_PATH . "public/img/upload/$id.jpg")) {
            return "upload/$id.jpg";
        }
        return null;
    }
    /**
* ELimina la foto del usuario
*
* @return string $id
* @return string
**/
    public function delete ($id)
    {
        $filepath = APP_PATH . "public/img/upload/$id.jpg";
        if (is_file($filepath)) {
            return unlink($filepath);
        }
        return false;
    }
}

Como se aprecia en este segundo modelo no existe ninguna conexión a una BD y sigue teniendo lógica de negocio para la aplicación, esta historia también se puede repetir para un modelo de sessión, o como me comento el amigo Jesus Lara (Phenobarbital) tiene modelos que gestionan todas las operaciones de un servidor SAMBA.

Como Usar los Modelos en KumbiaPHP

  • Share/Bookmark