Yupp Framework PHP

Modelo

Para contextualizar, el "modelo" es la "M" en MVC, o sea en Model-View-Controller, el patrón de diseño que implementa Yupp PHP Framework. Más concretamente, el "modelo" es la capa de datos e información de nuestra aplicación, lo que generalmente se denomina "modelo de datos" o "modelo de información.

En Yupp, el modelo de datos se define como clases y relaciones, y todas esas clases y relaciones son persistentes, es decir, instancias de este modelo se pueden almacenar en una base de datos de forma automática, Yupp PHP Framework se encarga de todo el trabajo de generar las tablas, guardar los datos y pedir los datos, lo que simplifica enormemente las tareas del programador.

Los objetos y relaciones antes mencionados se definen utilizando el paradigma de Programación Orientada a Objetos, como todo en Yupp Framework.

En Programación Orientada a Objetos, los objetos pueden estar relacionados de distintas formas, por ejemplo mediante referencias o mediante herencia. La relación de referencia es básicamente una asociación entre dos clases, y la relación de herencia es cuando una clase hereda de otra.

Definición de clases del modelo

La mejor forma de explicar como se define una clase del modelo es con un ejemplo:

<?php

class Usuario extends PersistentObject {

    function 
__construct$args = array() )
    {
        
$this->withTable "usuarios";

        
$this->addAttribute("name" Datatypes::TEXT);
        
$this->addAttribute("email"Datatypes::TEXT);
        
$this->addAttribute("age",   Datatypes::INT_NUMBER);
        
        
        
parent::__construct$args );
    }
}

?>

Como primer regla, todas las clases del modelo heredan de PersistentObject, que es la clase que implementa toda la lógica necesaria para definición del modelo.

En este caso definimos una clase "Usuario" con tres campos: name (nombre del usuario), email (correo electrónico del usuario) y age (edad del usuario). Para definir estos campos se utiliza el método "addAttribute" de PersistentObject. El segundo argumento de dicho método es el tipo de atributo, este tipo servirá luego para generar el tipo de la columna donde se guarden los valores correspondientes a ese atributo en la tabla en la que se almacenan las instancias de esta clase.

El atributo "withTable" de PersistentObject se utiliza para definir el nombre de la tabla donde las instancias de la clase Usuario van a ser almacenadas. Yupp Framework no tiene restricciones sobre los nombres de las tablas, por ejemplo, no exige nombres definidos en plural, como en otros frameworks donde esta regla es necesaria.

Como se puede apreciar en la última línea del constructor de "Usuario", es necesario llamar al construcor de la clase padre, en este caso "PersistentObject", para que se haga el trabajo necesario de inicialización del objeto. Esto inyecta atributos, que serán de utilidad luego, y define sus valores.

Introducción a relaciones entre clases

Yupp soporta relaciones de distinta cardinalidad entre clases del modelo de datos. La cardinalidad indica cuantas instancias de la clase relacionada se pueden tener asociadas.

Las tres posibilidades de cardinalidad de las relaciones son: 1-1, 1-N y N-N. Y las relaciones pueden ser unidireccionales o bidireccionales, en la siguiente imagen se muestran todas las opciones que soporta Yupp PHP Framework para las reslaciones entre clases:

Yupp PHP Framework class model link support

Nota: Yupp PHP Framework soporta salvar un modelo en cascada, esto quiere decir que si se salva una sola instancia de una clase, se salvan también las instancias de las clases asociadas. Para poder hacer esto, Yupp necesita saber cual es la clase "fuerte" en la relación. Yupp posee una forma de declarar explícitamente cual es la parte fuerte de la relación, esto es a través del atributo "belongsTo" en las clases del modelo, que indica que la clase pertenece a otra mediante una asociación, y esta última es la parte fuerte de esa asociación. No siempre es necesario declarar ese atributo, en los casos que no se declara Yupp Framework sigue ciertas reglas para determinar la parte fuerte de la relació, aquí se listan todas las reglas:

  1. Si la relacion es A (1) -> (1) B, entonces B belongsTo A.
  2. Si la relacion es A (1) <-> (1) B, se necesita belongsTo para saber cual es el lado fuerte.
  3. Si la relacion es A (1) -> (*) B, entonces B belongsTo A.
  4. Si la relacion es A (1) <-> (*), B entonces B belongsTo A.
  5. Si la relacion es A (*) -> (*) B, entonces B belongsTo A.
  6. Si la relacion es A (*) <-> (*) B, se necesita belongsTo para saber cual es el lado fuerte.

La característica importante del modelo es que es persistente, y a través del componente de ORM de Yupp (YORM), se pueden persistir y obtener datos de la base de datos sin necesidad de escribir SQL ni manejar la estructura de la base de datos (generar la estructura, obtener datos, hacer JOINs, etc).

Definiendo relaciones:

Un usuario tiene un login donde se almacena un nombre de usuario y una clave que el usuario utiliza para ingresar a nuestro sistema. Este ejemplo presenta una forma unidireccional de generar esta relación, desde el "Login" al "Usuario":

<?php

class Login extends PersistentObject {

    function 
__construct$args = array() )
    {
        
$this->withTable "login";

        
$this->addAttribute("username"Datatypes::TEXT);
        
$this->addAttribute("password",  Datatypes::TEXT);
        
        
$this->addHasOne("user"Usuario);

        
parent::__construct$args );
    }
}

?>


Con el método addHasOne, se especifica una relación 1-1 unidireccional desde Login a Usuario, mediante un atributo usuario en la clase Login.

Un ejemplo de como se utiliza el modelo es el siguiente:

<?php

$usuario 
= new Usuario( array("name" =>"Pablo",
                              
"email" =>"a@b.com",
                              
"age" =>26) );
$usuario->save();

$login = new Login( array("username"=>"unusuario""password"=>"abcd1234" );
$login->setUser$usuario );
$login->save();

?>

Yupp también soporta relaciones múltiples, por ejemplo, si el usuario escribe entradas en un blog, el usuario tiene varias entradas:

<?php

class Entrada extends PersistentObject {

   function 
__construct$args = array() )
   {
      
$this->withTable "entradas";

      
$this->addAttribute("title"Datatypes::TEXT);
      
$this->addAttribute("text",  Datatypes::TEXT);
        
      
parent::__construct$args );
   }
}

?>

Ahora agregamos la nueva relación 1-N de Usuario a Entrada:

<?php

class Usuario extends PersistentObject {

   function 
__construct$args = array() )
   {
      
$this->withTable "usuarios";

      
$this->addAttribute("name"Datatypes::TEXT);
      
$this->addAttribute("email",  Datatypes::TEXT);
      
$this->addAttribute("age",   Datatypes::INT_NUMBER);
        
      
$this->addHasMany("entradas"Entrada);
        
      
parent::__construct$args );
   }
}

?>

Como podemos ver, este es un caso de relaciones 1-N unidireccionales, por que se define la relación de Usuario a Entrada pero no de Entrada a Usuario. En la mayoría de los casos no será necesario definir relaciones bidireccionales, pero como vimos antes, Yupp Framework igualmente las soporta.

Un ejemplo de uso de la relación 1-N:

<?php

$usuario 
Usuario::get$id );
$entrada1 = new Entrada( array("title"=>"Un titulo",
                               
"text" =>"Lorem ipsum dolor sit amet...") );

$entrada2 = new Entrada( array("title"=>"Otro titulo",
                               
"text" =>"Lorem ipsum dolor sit amet...") );

$usuario->addToEntradas$entrada1 );
$usuario->addToEntradas$entrada2 );

$usuario->save();

?>

Más ejemplos de uso de clases del modelo:

  1. Crear un nuevo usuario y guardarlo en la base de datos:

    <?php

       $obj 
    = new Usuario();
       $obj->setProperties( array("name" => "Pablo"
                                  
    "email" => "a@b.com",
                                  
    "age" => 26) );
       $obj->save();

    ?>

  2. Pedir todos los usuarios guardados en la base y mostrar sus nombres:

    <?php

       $list 
    Usuario::listAll();
       foreach ( 
    $list as $usuario )
       {
          echo 
    $usuario->getNombre();
       }

    ?>

  3. Eliminar un usuario:

    <?php

    $obj 
    Usuario::get$id );
    $obj->delete();

    ?>
Yupp por defecto inyecta 3 atributos de forma implícita a cada clase, el atributo class tiene el nombre de la clase, el atributo deleted dice si el objeto está eliminado o no, sirve para eliminación lógica (Yupp por defecto utiliza eliminación lógica en lugar de física, o sea, eliminar el registro físicamente de la tabla de la base de datos), también inyecta un atributo id que guarda el identificador asignado al objeto cuando se guarda en la base de datos.

Por consultas o comentarios ir al grupo:
Grupos de Google
Suscribirte a Yupp Framework PHP
Correo electrónico:
Consultar este grupo