Diferencia entre revisiones de «Como hacer un CRUD en KumbiaPHP Framework»

De KumbiaPHP Framework Wiki
 
(No se muestran 49 ediciones intermedias de 17 usuarios)
Línea 1: Línea 1:
Este manual nos permitirá de manera sencilla conocer y entender la implementación de un CRUD Crear, Obtener, Actualizar y Borrar (Create, Read, Update y Delete en inglés).
+
{{cleanupbox
 +
|image=[[Archivo:Information_icon4.png|45px]]
 +
|texto ='''Este Artículo cumple con todos los requererimientos de los Kumbieros.'''<br />
 +
}}
 +
{{cleanupbox
 +
|texto ='''Este ejemplo es funcional para la [[KumbiaPHP_Framework_Versión_1.0_Spirit | Versión Beta1]]'''<br />
 +
}}
 +
== Texto de titular ==
 +
Este ejemplo nos permitirá de manera sencilla conocer y entender la implementación de un CRUD (Create, Read, Update y Delete en inglés) sin la necesidad de un Scaffold (<s>StandardForm</s>) y un manejo correcto del MVC en KumbiaPHP.
  
 +
== Configurando database.ini ==
 +
Configurar el archivo [[KumbiaPHP_Framework_Versión_1.0_Spirit#databases.ini|databases.ini]], con los datos y motor de Base de Datos a utilizar.
  
== El modelo ==
+
== Modelo ==
 +
'''Crear el Modelo''' el cual esta viene dado por la definición de una tabla en la BD, para efecto del ejemplo creamos la siguiente tabla (la misma del ejemplo de [[AutoCarga_de_Objetos_KumbiaPHP | Auto Carga de Objetos]])
  
Vamos ahora a definir el modelo, este arhivo va en la carpeta '''models''' de nuestra aplicación y lo nombramos como: parte_maquina.php
+
<pre>
 +
CREATE TABLE menus
 +
(
 +
id          int            unique not null auto_increment,
 +
nombre      varchar(100),
 +
titulo      varchar(100)  not null,
 +
primary key(id)
 +
)
 +
</pre>
  
'''Modelo:'''
+
Vamos ahora a definir el modelo el cual nos permite interactuar con la BD.
 +
 
 +
'''''[app]/models/menus.php:'''''
 
<source lang="php" line>
 
<source lang="php" line>
 
<?php
 
<?php
class ParteMaquina extends ActiveRecord{
+
class Menus extends ActiveRecord
      
+
{
 +
    /**
 +
    * Retorna los menu para ser paginados
 +
    *
 +
    */
 +
    public function getMenus($page, $ppage=20)
 +
    {
 +
        return $this->paginate("page: $page", "per_page: $ppage");
 +
     }
 
}
 
}
?>
 
 
</source>
 
</source>
  
== El controlador ==
+
== Controller ==
 +
 
 +
El controlador es encargado de atender las peticiones del cliente (ej. browser) y a su vez de darle una respuesta. En este controller vamos a definir todas las operaciones CRUD que necesitamos.
  
El controlador es nuestro eje principal, es quien recibe las peticiones de las vistas y se las pasa al modelo.
+
En esta parte es importante que se haya visto el [[AutoCarga_de_Objetos_KumbiaPHP | Tutorial de Auto Carga de Objetos]]
 +
 
 +
'''''[app]/controllers/menus_controller.php:'''''
  
 
<source lang="php" line>
 
<source lang="php" line>
 
<?php
 
<?php
class ParteMaquinaController extends ApplicationController {
+
/**
    //Carga del modelo ParteMaquina, porque tenemos la autocarga de modelos desactivada (off)
+
* Carga del modelo Menus...
    public $models = array('parte_maquina');  
+
*/
 +
Load::models('menus');
 +
 
 +
class MenusController extends ApplicationController {
  
     /*
+
     /**
    * Función que consulta y pagina la lista de
+
    * Obtiene una lista para paginar los menus
    * partes de máquina.
+
    */
    */
+
     public function index($page=1)  
     public function index($page=1) {
+
    {
        $cons="";
+
         $menu = new Menus();
        if(isset ($this->parameters[1])) {
+
         $this->listMenus = $menu->getMenus($page);
            $cons= "order: ".$this->parameters[1]." asc";
 
            $this->orden="/".$this->parameters[1];
 
        }else {
 
            $this->orden="";
 
        }
 
         $this->count = $this->ParteMaquina->count();
 
         $this->page = $this->ParteMaquina->paginate('per_page: 20', "page: $page");
 
    }
 
   
 
    /*
 
    * Función que muestra la información
 
    * partes de máquina. Se consulta a través de su identificador
 
    */
 
    public function show($id) {       
 
        $this->obj = $this->ParteMaquina->find($id);
 
 
     }
 
     }
 
      
 
      
     /*
+
     /**
    * Función que toma los datos del POST
+
    * Crea un Registro
    * crea una ParteMaquina y lo almacena.
+
    */
    */
+
     public function create ()
     public function create() {
+
    {
         //Si ha datos 'parte_maquina' en el POST
+
         /**
         if ($this->has_post('parte_maquina')) {
+
        * Se verifica si el usuario envio el form (submit) y si ademas
             //Se crea un nuevo objeto tipo ParteMaquina
+
        * dentro del array POST existe uno llamado "menus"
             $obj = new ParteMaquina($this->post('parte_maquina'));          
+
        * el cual aplica la autocarga de objeto para guardar los
           
+
        * datos enviado por POST utilizando autocarga de objeto
             //Si guarda el objeto
+
        */
             if ($obj->save()) {
+
         if($this->has_post('menus')){
                //Muestra un mensaje de exito y nos envía a listado
+
             /**
                 Flash::notice('Operación Exitosa');
+
            * se le pasa al modelo por constructor los datos del form y ActiveRecord recoge esos datos
                Router::route_to('controller: parte_maquina','action: index','id: 1');
+
            * y los asocia al campo correspondiente siempre y cuando se utilice la convención
            } else {
+
            * model.campo
                 //Muestra un mensaje de error,
+
            */
                 Flash::error('No se Guardo!');
+
             $menu = new Menus($this->post('menus'));
                 //Cargamos el objeto en una variable, para mostralo en la vista
+
             //En caso que falle la operación de guardar
                $this->$obj = $obj;
+
             if(!$menu->save()){
                //Se renderiza de nuevo la vista create
+
                 Flash::error('Falló Operación');
                 $this->render('create');
+
                 //se hacen persistente los datos en el formulario
 +
                 $this->menus = $this->post('menus');
 +
                 /**
 +
                * NOTA: para que la autocarga aplique de forma correcta, es necesario que llame a la variable de instancia
 +
                * igual como esta el model de la vista, en este caso el model es "menus" y quedaria $this->menus
 +
                */
 +
            }else{
 +
                 Flash::success('Operación exitosa');
 
             }
 
             }
 
         }
 
         }
 
     }
 
     }
  
     public function edit($id=0) {
+
    /**
       
+
    * Edita un Registro
         if ($this->has_post('parte_maquina')) {
+
    */
             $obj = new ParteMaquina($this->post('parte_maquina'));
+
     public function edit($id = null)
            //$obj->version=  $this->ciudad->version+1;
+
    {
             if ($obj->update()) {
+
    $menu = new Menus();
                 Flash::notice('Operación Exitosa');
+
         if($id != null){
                 Router::route_to('controller: parte_maquina','action: index','id: 1');
+
        //Aplicando la autocarga de objeto, para comenzar la edición
 +
             $this->menus = $menu->find((int)$id);
 +
    }
 +
        //se verifica si se ha enviado el formulario (submit)
 +
        if($this->has_post('menus')){
 +
           
 +
             if(!$menu->update($this->post('menus'))){
 +
                 Flash::error('Falló Operación');
 +
                 //se hacen persistente los datos en el formulario
 +
                $this->menus = $this->post('menus');
 
             } else {
 
             } else {
                 Flash::error('No se Guardo!');
+
                 Router::route_to('action: index');
                $this->render('edit');
 
 
             }
 
             }
        }else {
 
            $this->obj = $this->ParteMaquina->find($id);
 
 
         }
 
         }
 
     }
 
     }
  
     public function delete($id=0) {
+
    /**
         $obj  = $this->ParteMaquina->find($id);
+
    * Eliminar un menu
 
+
    *
        if($obj->delete()) {
+
    * @param int $id
            Flash::notice('Operación Exitosa');
+
    */
        }else{
+
     public function del($id = null)
            Flash::error('No se Eliminó!');
+
    {
 +
         $menu = new Menus();
 +
        if ($id) {
 +
            if (!$menu->delete((int)$id)) {
 +
                Flash::error('Falló Operación');
 +
            }
 
         }
 
         }
 
+
        //enrutando al index para listar los menus
         Router::route_to('controller: parte_maquina','action: index','id: 1');
+
         Router::route_to('action: index');
 
     }
 
     }
 
}
 
}
?>
 
 
</source>
 
</source>
  
== Las vistas ==
+
== Vistas ==
 +
Agregamos las vistas...
 +
 
 +
'''''[apps]/views/menus/index.phtml'''''
 +
<source lang="php" line>
 +
<div class="content">
 +
    <?php echo View::content(); ?>
 +
    <h3>Menus</h3>
 +
    <ul>
 +
    <?php foreach ($listMenus->items as $item) : ?>
 +
    <li>
 +
        <?php echo link_to("menus/create",'Agregar'); ?>
 +
        <?php echo link_to(array("menus/edit/$item->id/", 'Editar')) ?>
 +
        <?php echo link_to(array("menus/del/$item->id/", 'Borrar')) ?><br/>
 +
        <strong><?php echo $item->nombre ?> - <?php echo $item->titulo ?></strong>
 +
    </li>
 +
    <?php endforeach; ?>
 +
    </ul>
 +
   
 +
    <?php if($listMenus->prev) echo Html::link("menus/index/$listMenus->prev/", '<< Anterior |'); ?>
 +
    <?php if($listMenus->next) echo Html::link("menus/index/$listMenus->next/", '| Próximo >>'); ?>
 +
</div>
 +
</source>
  
create.phtml
 
  
 +
'''''[apps]/views/menus/create.phtml'''''
 
<source lang="php" line>
 
<source lang="php" line>
<h1>Crear parte de máquina</h1>
+
<?php View::content(); ?>
<?php View::content() ?>
+
<?php echo form_tag('menus/create/') ?>
 +
<table>
 +
    <tr>
 +
        <td>Nombre</td>
 +
        <td><?php echo text_field_tag(array('menus.nombre')) ?></td>
 +
    </tr>
 +
    <tr>
 +
        <td>Titulo</td>
 +
        <td><?php echo text_field_tag(array('menus.titulo')) ?></td>
 +
    </tr> 
 +
    <tr>
 +
        <td>&nbsp;</td>
 +
        <td><?php echo submit_tag('Agregar') ?></td>
 +
    </tr>
 +
</table>
 +
<?php echo end_form_tag() ?>
 +
</source>
  
<?php echo form_tag("parte_maquina/create")?>
 
  
<label for="parte_maquina_nombre">Nombre:</label>
+
'''''[apps]/views/menus/edit.phtml'''''
          
+
<source lang="php" line>
<?php echo textupper_field_tag('parte_maquina.nombre') ?>
+
<?php View::content(); ?>
          
+
<?php echo form_tag('menus/edit/') ?>
<?php echo submit_tag('Guardar') ?>
+
<table>
<?php echo end_form_tag(); ?>
+
    <tr>
 +
         <td>Nombre</td>
 +
        <td><?php echo text_field_tag(array('menus.nombre')) ?></td>
 +
    </tr>
 +
    <tr>
 +
        <td>Titulo</td>
 +
        <td><?php echo text_field_tag(array('menus.titulo')) ?></td>
 +
    </tr> 
 +
    <tr>
 +
         <td>&nbsp;</td>
 +
        <?php echo hidden_field_tag(array('menus.id')) ?>
 +
        <td><?php echo submit_tag('Actualizar') ?></td>
 +
    </tr>
 +
</table>
 +
<?php echo end_form_tag() ?>
 
</source>
 
</source>
  
 +
== Probando el CRUD ==
 +
Ahora solo resta probar todo el código que hemos generado, en este punto es importante conocer el comportamiento de las [[Hola_Mundo_KumbiaPHP_Framework#KumbiaPHP_URLS|URL's en KumbiaPHP]].
 +
 +
* '''index''' es la acción para listar http://localhost/menus/index/
 +
  NOTA: index/ se puede pasar de forma implícita o no KumbiaPHP en caso que no se le pase una acción
 +
buscara por defecto un index, es decir si colocamos
 +
  http://localhost/menus/
 +
* '''create''' crea un menu en la Base de Datos http://localhost/menus/create/
 +
* Las acciones '''del''' y '''edit''' a ambas se debe entrar desde el index, ya que reciben el parámetros a editar o borrar según el caso.
 
[[Categoría:Tutoriales KumbiaPHP]]
 
[[Categoría:Tutoriales KumbiaPHP]]
 +
 +
== Descarga ==
 +
Descarga: [http://dl.dropbox.com/u/2807704/kumbiaPHP/v1_b1/app_crud.zip app_crud] para el '''core''' de Spirit v1.0 '''beta1'''.
 +
 +
Este ejemplo de descarga esta apuntado a la base de datos '''test''', usuario '''root''' y clave '''123'''.

Revisión actual del 11:16 21 jun 2016

{{#if:Information icon4.png |}}

{{#if:

|}}


{{#if: |}}

{{#if:

|}}


Texto de titular[editar]

Este ejemplo nos permitirá de manera sencilla conocer y entender la implementación de un CRUD (Create, Read, Update y Delete en inglés) sin la necesidad de un Scaffold (StandardForm) y un manejo correcto del MVC en KumbiaPHP.

Configurando database.ini[editar]

Configurar el archivo databases.ini, con los datos y motor de Base de Datos a utilizar.

Modelo[editar]

Crear el Modelo el cual esta viene dado por la definición de una tabla en la BD, para efecto del ejemplo creamos la siguiente tabla (la misma del ejemplo de Auto Carga de Objetos)

CREATE TABLE menus
(
 id           int            unique not null auto_increment,
 nombre       varchar(100),
 titulo       varchar(100)   not null,
 primary key(id)
)

Vamos ahora a definir el modelo el cual nos permite interactuar con la BD.

[app]/models/menus.php:

<?php
class Menus extends ActiveRecord
{
    /**
     * Retorna los menu para ser paginados
     *
     */
    public function getMenus($page, $ppage=20)
    {
        return $this->paginate("page: $page", "per_page: $ppage");
    }
}

Controller[editar]

El controlador es encargado de atender las peticiones del cliente (ej. browser) y a su vez de darle una respuesta. En este controller vamos a definir todas las operaciones CRUD que necesitamos.

En esta parte es importante que se haya visto el Tutorial de Auto Carga de Objetos

[app]/controllers/menus_controller.php:

<?php
/**
 * Carga del modelo Menus...
 */
Load::models('menus');

class MenusController extends ApplicationController {

    /**
     * Obtiene una lista para paginar los menus
     */
    public function index($page=1) 
    {
        $menu = new Menus();
        $this->listMenus = $menu->getMenus($page);
    }
    
    /**
     * Crea un Registro
     */
    public function create ()
    {
        /**
         * Se verifica si el usuario envio el form (submit) y si ademas 
         * dentro del array POST existe uno llamado "menus"
         * el cual aplica la autocarga de objeto para guardar los 
         * datos enviado por POST utilizando autocarga de objeto
         */
        if($this->has_post('menus')){
            /**
             * se le pasa al modelo por constructor los datos del form y ActiveRecord recoge esos datos
             * y los asocia al campo correspondiente siempre y cuando se utilice la convención
             * model.campo
             */
            $menu = new Menus($this->post('menus'));
            //En caso que falle la operación de guardar
            if(!$menu->save()){
                Flash::error('Falló Operación');
                //se hacen persistente los datos en el formulario
                $this->menus = $this->post('menus');
                /**
                 * NOTA: para que la autocarga aplique de forma correcta, es necesario que llame a la variable de instancia
                 * igual como esta el model de la vista, en este caso el model es "menus" y quedaria $this->menus
                 */
            }else{
                Flash::success('Operación exitosa');
            }
        }
    }

    /**
     * Edita un Registro
     */
    public function edit($id = null)
    {
    	$menu = new Menus();
        if($id != null){
    	    //Aplicando la autocarga de objeto, para comenzar la edición
            $this->menus = $menu->find((int)$id);
    	}
        //se verifica si se ha enviado el formulario (submit)
        if($this->has_post('menus')){
            
            if(!$menu->update($this->post('menus'))){
                Flash::error('Falló Operación');
                //se hacen persistente los datos en el formulario
                $this->menus = $this->post('menus');
            } else {
                Router::route_to('action: index');
            }
        }
    }

    /**
     * Eliminar un menu
     * 
     * @param int $id
     */
    public function del($id = null)
    {
        $menu = new Menus();
        if ($id) {
            if (!$menu->delete((int)$id)) {
                Flash::error('Falló Operación');
            }
        }
        //enrutando al index para listar los menus
        Router::route_to('action: index');
    }
}

Vistas[editar]

Agregamos las vistas...

[apps]/views/menus/index.phtml

<div class="content">
    <?php echo View::content(); ?>
    <h3>Menus</h3>
    <ul>
    <?php foreach ($listMenus->items as $item) : ?>
    <li>
        <?php echo link_to("menus/create",'Agregar'); ?>
        <?php echo link_to(array("menus/edit/$item->id/", 'Editar')) ?>
        <?php echo link_to(array("menus/del/$item->id/", 'Borrar')) ?><br/>
        <strong><?php echo $item->nombre ?> - <?php echo $item->titulo ?></strong>
    </li>
    <?php endforeach; ?>
    </ul>
    
    <?php if($listMenus->prev) echo Html::link("menus/index/$listMenus->prev/", '<< Anterior |'); ?>
    <?php if($listMenus->next) echo Html::link("menus/index/$listMenus->next/", '| Próximo >>'); ?>
</div>


[apps]/views/menus/create.phtml

<?php View::content(); ?>
<?php echo form_tag('menus/create/') ?>
<table>
    <tr>
        <td>Nombre</td>
        <td><?php echo text_field_tag(array('menus.nombre')) ?></td>
    </tr>
    <tr>
        <td>Titulo</td>
        <td><?php echo text_field_tag(array('menus.titulo')) ?></td>
    </tr>   
    <tr>
        <td>&nbsp;</td>
        <td><?php echo submit_tag('Agregar') ?></td>
    </tr>
</table>
<?php echo end_form_tag() ?>


[apps]/views/menus/edit.phtml

<?php View::content(); ?>
<?php echo form_tag('menus/edit/') ?>
<table>
    <tr>
        <td>Nombre</td>
        <td><?php echo text_field_tag(array('menus.nombre')) ?></td>
    </tr>
    <tr>
        <td>Titulo</td>
        <td><?php echo text_field_tag(array('menus.titulo')) ?></td>
    </tr>   
    <tr>
        <td>&nbsp;</td>
        <?php echo hidden_field_tag(array('menus.id')) ?>
        <td><?php echo submit_tag('Actualizar') ?></td>
    </tr>
</table>
<?php echo end_form_tag() ?>

Probando el CRUD[editar]

Ahora solo resta probar todo el código que hemos generado, en este punto es importante conocer el comportamiento de las URL's en KumbiaPHP.

 NOTA: index/ se puede pasar de forma implícita o no KumbiaPHP en caso que no se le pase una acción 

buscara por defecto un index, es decir si colocamos

 http://localhost/menus/
  • create crea un menu en la Base de Datos http://localhost/menus/create/
  • Las acciones del y edit a ambas se debe entrar desde el index, ya que reciben el parámetros a editar o borrar según el caso.

Descarga[editar]

Descarga: app_crud para el core de Spirit v1.0 beta1.

Este ejemplo de descarga esta apuntado a la base de datos test, usuario root y clave 123.