Páginas

Buscar

Ejemplo 1 FuelPHP

Este articulo es una versión traducida basada en el articulo: 
http://net.tutsplus.com/tutorials/php/easy-form-generation-using-fuelphp/

Gracias a la clase fieldset de FuelPHP el trabajo con Forms no podría ser más sencillo.Con unas pocas líneas de código, usted puede fácilmente generar y validar un formulario. Hoy día, vamos a aprender a hacer justamente eso!

Fieldset se utiliza para crear un formulario y gestionar su validación en una forma orientada a objetos. Utiliza las clases de Form y Validation. Esta clase, por sí misma, sólo sirve para modelar el fieldset y sus campos, mientras que las otras dos clases realizan la mayor parte del trabajo.


Configuración inicial de FuelPHP


Necesitamos una instalación con un paquete de FuelPHP con el ORM habilitado. Yo voy a usar una base de datos MySQL con una tabla de ejemplo. Mientras que la clase Fieldset puede ser configurado para usar un modelo normal, con un ORM ahorraremos mucho tiempo.

Configurar una conexión de base de datos en el fuel/app/config/development/db.php.


return array(
  'default' => array(
    'connection'  => array(
       'dsn'   => 'mysql:host=localhost;dbname=blog',
       'username' => 'root',
       'password' => 'root',
    ),
  ),
);


Activar el paquete ORM a través de fuel/app/config/config.php





'packages'  => array(
   'orm',
),


Y, finalmente, aquí está el SQL para la tabla que estoy usando para este tutorial.




CREATE TABLE  `blog`.`posts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`post_title` VARCHAR( 100 ) NOT NULL ,
`post_content` TEXT NOT NULL ,
`author_name` VARCHAR( 65 ) NOT NULL ,
`author_email` VARCHAR( 80 ) NOT NULL ,
`author_website` VARCHAR( 60 ) NULL,
`post_status` TINYINT NULL
) ENGINE = INNODB;


Modelo



Es necesario un modelo para nuestro controlador y poder interactuar con la tabla de posts. Vamos a crear un post.php el interior de app/classes/model/. Crear una clase Model_Post y asegurarse de que se extiende de \Orm\Model. El ORM utilizará automáticamente el posts de mesa en nuestra base de datos ya se ha utilizado el singular de "posts". Si desea establecer una tabla diferente, configurar una propiedad estática denominada $ _table_name.




class Model_Post extends Orm\Model
{
   protected static $_table_name = 'posts'
//set the table name manually
}


Configuración de las propiedades



Debemos especificar las columnas de nuestra tabla de los puestos dentro de nuestro modelo. Al mismo tiempo, también podemos configurar etiquetas, reglas de validación de formularios para usar con nuestra clase fieldset para generar el formulario. Todos ellos van en una matriz asociada, llamada $_properies. Con todo en su lugar, nuestro modelo final debe verse así:





class Model_Post extends Orm\Model
{
   protected static $_table_name = 'posts';
   protected static $_properties = array(
      'id',
      'post_title' => array( //column name
         'data_type' => 'string',
         'label' => 'Post Title', //label for the input field
         'validation' => array('required', 'max_length'=>array(100), 'min_length'=>array(10)) //validation rules
      ),
      'post_content' => array(
         'data_type' => 'string',
         'label' => 'Post Content',
         'validation' => array('required')
      ),
      'author_name' => array(
         'data_type' => 'string',
         'label' => 'Author Name',
         'validation' =>  array('required', 'max_length'=>array(65), 'mi n_length'=>array(2))
      ),
      'author_email' => array(
         'data_type' => 'string',
         'label' => 'Author Email',
         'validation' =>  array('required', 'valid_email')
      ),
      'author_website' => array(
         'data_type' => 'string',
         'label' => 'Author Website',
         'validation' =>  array('required', 'valid_url', 'max_length'=>array(60))
      ),
      'post_status' => array(
         'data_type' => 'string',
         'label' => 'Post Status',
         'validation' => array('required'),
         'form' => array('type' => 'select', 'options' => array(1=>'Published', 2=>'Draft')),
      )
   );
}



Vamos a examinar las opciones que podemos utilizar, data_type simplemente mantiene los campos de tipo popular. Podría ser cualquiera de cadena, un entero o mysql_date. label es la propiedad se mostrará como la etiqueta del campo una vez que el formulario se genera. validation acepta una serie de reglas de validación. De forma predeterminada, estos campos serán los campos de texto de entrada. Utilizando el form, usted puede hacer que se use un select o un texarea.

El ORM trata la columna denominada id como la primaria y no se mostrará cuando se genera un formulario. Si para la tabla la columna de clave principal es diferente, utilice la propiedad $_primary_key para especificarla.


/**
 * Post Model
 */
class Model_Post extends Orm\Model
{
   protected static $_table_name = 'posts';
   protected static $_primary_key = array('id'); 
//you can set up multiple columns, .. $_primary_key => array('id', 'user_id')
}


Controlador



Ahora que el modelo está listo, vamos a crear el controlador. Los controladores deben ser colocados dentro de fuel/app/classes/controller/. He creado un controlador llamado Controller_Posts (posts.php) y lo extiendo a partir de Controller_Template.


/**
 * Post Controller fuel/app/classes/controller/posts.php
 */
class Controller_Posts extends Controller_Template
{
   //list posts
   function action_index()
   {
   }
   //add new one
   function action_add()
   {
   }
   //edit
   function action_edit($id)
   {
   }
}


Los usuarios podrán ver una lista de posts, añadir otras nuevas, o editar una existente. Porque yo estoy usando el controlador de la plantilla, puedo usar un archivo de plantilla de base para trabajar. Plantillas de ir en fuel/app/views/template.php


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <?php echo Asset::css('bootstrap.css'); ?>
</head>
<body>
   <div id="content">
      <p>
         <?php
            echo \Html::anchor('posts/index', 'Listing'), '&nbsp;', \Html::anchor('posts/add', 'Add');
         ?>
      </p>
      <?php if(isset($messages) and count($messages)>0): ?>
      <div class="message">
         <ul>
         <?php
            foreach($messages as $message)
            {
               echo '<li>', $message,'</li>';
            }
         ?>
         </ul>
      </div>
      <?php endif; ?>
      <?php echo $content; ?>
   </div>
</body>
</html>



Esto no es más lenguaje de marcas estándar HTML con el Twitter bootstrap. La variable $content tendrá el contenido. Podemos establecer una serie de posts y si lo hacemos, se imprimirán en una lista desordenada.



Adición de nuevos posts


Aquí es donde comienza la diversión. Vamos a generar el formulario de añadido de nuevos posts.Como ya habrán adivinado, vamos a estar trabajando con el método action_add (). Vamos a generar el form y pasarlo a nuestra plantilla.




//add new one
function action_add()
{
   $fieldset = Fieldset::forge()->add_model('Model_Post');
   $form     = $fieldset->form();
   $this->template->set('content', $form->build(), false);
//false will tell fuel not to convert the html tags to safe string.
}


Fieldset::forge() devuelve una nueva instancia de la clase de fieldset. Es lo mismo que hacer new Fieldset. Sin embargo, con el método forge aquí, podemos nombrar a nuestras instancias. Si llamamos a una instancia dos veces con el mismo nombre, una instancia existente será devuelto si esta disponible [el patrón Factory]. Para el nombre de su instancia, pasar el nombre al metodo forge. Fieldset::forge('new_post')
Uso del método add_model, se pasa el modelo que queremos generar el formulario. Fieldset toma los datos de $_properties para generar el formulario. Llamar el método form() desde el objeto fieldset que devolverá una instancia de la clase Form, y llamando al método build (), podemos conseguir un html (cadena) de salida del form.

$this->template->set('content', $form, false);

Por último, pasamos form a la plantilla como el contenido. Otro método de pasar variables a una plantilla es

$this->template->content = $form.

Ingresa desde tu navegador y vaya a http://path_to_site/index.php/posts/add. Usted debe ver un formulario idéntico a éste.


Sin botón de enviar?
Vamos a arreglar eso.

Tenemos que añadir un nuevo campo a nuestro objeto de formulario.

$form->add('submit' , '' , array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
Utilizando el método add() podemos añadir campos adicionales a nuestro formulario. El primer parámetro es el nombre de nuestro nuevo campo, en segundo lugar es para label, para el tercer parámetro se pasa una matriz de atributos.

Después de la adición de esto, nuestro action_add () se verá así.





function action_add()
{
   $fieldset = Fieldset::forge()->add_model('Model_Post');
   $form     = $fieldset->form();
   $form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
   $this->template->set('content', $form->build(), false);
}


Y nuestro formulario sera..


Validación y Almacenado

Ahora que tenemos una forma agradable, vamos a validar y guardar en la base de datos. El objeto fieldset incluye una instancia de la clase de validation de FuelPHP. Todas las rules (reglas de validación) que se ha aplicado y están listo para funcionar.



function action_add()
{
   $fieldset = Fieldset::forge()->add_model('Model_Post');
   $form     = $fieldset->form();
   $form->add('submit', '', array('type' => 'submit', 'value' => 'Add', 'class' => 'btn medium primary'));
   if($fieldset->validation()->run() == true)
   {
      $fields = $fieldset->validated();
      $post = new Model_Post;
      $post->post_title     = $fields['post_title'];
      $post->post_content   = $fields['post_content'];
      $post->author_name    = $fields['author_name'];
      $post->author_email   = $fields['author_email'];
      $post->author_website = $fields['author_website'];
      $post->post_status    = $fields['post_status'];
      if($post->save())
      {
         \Response::redirect('posts/edit/'.$post->id);
      }
   }
   else
   {
      $this->template->messages = $fieldset->validation()->errors();
   }
   $this->template->set('content', $form->build(), false);
}


$fieldset->validation() devuelve una instancia de la clase de validación y accediendo a su método run() que puede comprobar si pasa la validación. Si es así, se añade una nueva entrada a la base de datos. $fieldset->validated() devolverá una matriz de campos validados. Si la validación se pasa y después se guarda, el usuario será redirigido a la página de edición, de lo contrario pasar los errores de validación a nuestra plantilla como variable de mensaje.

Si usted trata de presentar algunos datos no válidos, recibirá una salida de este modo:



Todo parece bien, excepto por una cuestión: los datos introducidos no aparece después de la actualización de la vista. No te preocupes, una llamada a un método y ya está.

$fieldset = Fieldset::forge()->add_model('Model_Post')->repopulate();
//repopulate method will populate your form with posted data

Muy bien ahora agregue datos válidos y será dirigido al método action_edit (), que no está listo todavía.



Edición de un post

Edición de una sección es más o menos lo mismo que lo explicado en la sección anterior. Salvo que tenemos que rellenar los datos con una entrada existente. Voy a basarme en el código de action_add().





function action_edit($id)
{
   $post = \Model_Post::find($id);
   $fieldset = Fieldset::forge()->add_model('Model_Post')->populate($post);
//model post object is passed to the populate method
   $form     = $fieldset->form();
   $form->add('submit', '', array('type' => 'submit', 'value' => 'Save', 'class' => 'btn medium primary'));
   if($fieldset->validation()->run() == true)
   {
      $fields = $fieldset->validated();
      //$post = new Model_Post;
      $post->post_title     = $fields['post_title'];
      $post->post_content   = $fields['post_content'];
      $post->author_name    = $fields['author_name'];
      $post->author_email   = $fields['author_email'];
      $post->author_website = $fields['author_website'];
      $post->post_status    = $fields['post_status'];
      if($post->save())
      {
         \Response::redirect('posts/edit/'.$id);
      }
   }
   else
   {
      $this->template->messages = $fieldset->validation()->errors();
   }
   $this->template->set('content', $form->build(), false);
}



Con unas pequeñas modificaciones en nuestro método action_add (), tenemos nuestro método de edición. El método repopulate() ha sido reemplazado por el método populate(). Uso del método populate, se puede rellenar un formulario con los datos de un post existente.

En este caso, tome el post de nuestra base de datos usando el parámetro $id, entonces se pasa al método requerido. No necesitamos hacer $post = new Model_Post; porque no estamos añadiendo nada a la base de datos. El objeto $post que creamos en un principio se utiliza para asignar los nuevos valores. Una vez editado volverá a dirigir de nuevo a su pantalla de edición.

Ya hemos terminado!

Agregue unos cuantos post, y trate de modificarlos.



Listando Páginas


Vamos a construir la sección de enumeración en donde los usuarios pueden ver todos los mensajes en un solo lugar.

El listado es manejado por el método action_index ().



//list posts
function action_index()
{
   $posts = \Model_Post::find('all');
   $view  = \View::forge('listing');
   $view->set('posts', $posts, false);
   $this->template->content = $view;
//In config file View objects are whitelisted so Fuelphp will not escape the html.
}



Model_Post::find('all') devuelve un array de objetos posts para todos nuestros posts. Usando View::forge(), un nuevo objeto de vista se crea. El parámetro para View::forge() es el nombre de nuestra de vista específica. Se encuentra ubicado en app/views/listing.php. El conjunto de objetos post ($posts) se pasa a nuestra vista. La vista se hará cargo de la lista y finalmente, se le asigna a la vista principal la vista de la lista como contenido $this->template->content.

En la vista listing.php, el loop que recorre $posts y generar la lista, debería ser.





<?php
/**
 * Listing view, views/listing.php
 */
if($posts):
   foreach($posts as $post):
?>
<div class="post">
   <h2><?php echo $post->post_title; ?> <small><?php echo \Html::anchor('posts/edit/'.$post->id, '[Edit]');?></small></h2>
   <p><?php echo $post->post_content; ?></p>
   <p>
      <small>By <?php echo $post->author_name; ?></small><br />
      <small><?php echo $post->author_email; ?></small><br />
      <small><?php echo $post->author_website; ?></small><br />
   </p>
</div>
<?php
   endforeach;
endif;
?>




Si tiene cualquier mensaje en la base de datos, que se verá algo como esto.






Algunas modificaciones finales


Todo parece estar funcionando correctamente, sin embargo, hay algunas cuestiones de menor importancia. El formulario generado tiene un campo de texto para el contenido del post, para este campo sería mejor un textarea.



//Model_Post
'post_content' => array(
   'data_type' => 'string',
   'label' => 'Post Content',
   'validation' => array('required'),
   'form' => array('type' => 'textarea'
//will give us a textarea
),


Puede cambiar el tipo de campo al cualquier otro siempre y cuando sea adecuado para el tipo de dato que se reciba (text, textarea, select, radio, etc) Para elementos de select o radio, puede configurar las opciones. Configuración de las opciones para un select con elementos de otra tabla también es posible. Si desea cambiar el diseño predeterminado, coloque un archivo de configuración de formulario en fuel/app/config/form.php. Si no estas seguro de qué poner allí, copia las cosas de fuel/core/config/form.php. Fuel utiliza este archivo para generar los formularios.