viernes, 1 de febrero de 2013

tutorial mínimo de yii




En el pasado...

En tu antigua app hecha en PHP tu seguramente habras tenido piezas de codigo, funciones y demas cosas accesibles directamente asi:

http://miapp/cosa/mas/otra/crearorden.php

Eso es totalmente inseguro, a menos que tengas muchas reglas internas y mucha protección, pero si no es asi, estaras dispuesto a aceptar que cualquier que analice uno de tus form sepa cual es la accion a donde ese form va a enviar un POST y te bombardearán.

Yii framework te da una CAPA DE PROTECCION para que la única manera de acceder a ese mismo recurso "crearorden" se haga solo mediante una URL y pasando previamente por un punto de control: EL CONTROLADOR.

Aqui entramos a hablar de MVC. Model, View y Controller.

En tu antiguo sistema, tu guardabas tu informacion en tu base de datos, seguramente desde una consulta SQL horrorosamente igual a esta:
"insert into orden(...campos...) values(...y valores aqui...)";
Eso tambien es inseguro, propenso a inyección SQL, y peor aun inmanejable y dificilmente exportable.

El MODELO

Yii Framework te provee el MODELO para gestionar facilmente objetos persistentes (cosas que se guardan en una "tabla"), el modelo es una representacion de una TABLA (Orden.php), el modelo es algo mucho mas avanzado en términos de modelado UML, pero para no enredar el papagallo aqui vamos a simplificarlo solo a una "tabla", que en realidad no se llama "tabla" sino "relacion".

Supon que tienes:


Código:
$orden = new Orden();
$orden->idorden = '123-ABC';
$orden->total = 1000;
$orden->cliente = "nombre del cliente";
// ok..simplemente usando las clases base
// que Yii te provee podrás hacer:
$orden->insert();
y listo...la cosa se guardo en la base de datos. Simple. 

Esto se llama: 
CActiveRecord. Conseguiras muchos ejemplos en el foro y en la documentacion de Yii.
Dónde guarda Yii los modelos ? En protected/models.
Cómo se accede a ese modelo ? Directamente no....sigue leyendo tigre...

LA VISTA

La vista es la forma de presentar información, no hay lógica de negocios en las vistas, la lógica se la das a UN COMPONENTE o a ciertos ACTIONS (lee mas adelante), pero nunca a las vistas.

Mi papa siempre decía: "cuando se calcula..se calcula, cuando se imprime..se imprime". Eso significa que "o cantas o silbas"....y traduciendo a codigo: O muestras o calculas...pero no ambas.

La vista se aloja en /protected/views/<controllername>/nombrevista.php

Porque dentro de un <controllername> ? Para ordenar, nada mas, desde cualquier parte puedes acceder a cualquier vista, pero este esquema ayuda a ordenar.

Cómo accedo a una vista ? 
Desde un ACTION, el cual explico mas abajo.

Qué hago en una vista ?
Mostrar el modelo, mostrar tablas, imprimir html. Podria recomendarte esta extension para escribir en una vista:
http://christiansalazar.github.com/jamboree/

EL "CONTROLLER" y EL ACTION

Por fin aqui no ? Bueno, esta es la "pega" que une el modelo con la vista. Es tambien el punto de entrada, en programacion orientada a EVENTOS (como lo es YII) esto se considera un ENTRYPOINT (del viejo esquema C en donde una funcion main() es la encargada de iniciar el programa).

Si ya creaste un modelo Orden.php y ya tienes una vista "protected/views/orden/ver.php" entonces ahora querras acceder a esta vista para ver el modelo (cual modelo ? el que seleccionaremos en el controller en base a los argumentos de la URL).
Código:
http://www.miapp.com/tuapp/index.php?r=orden/ver&idorden=123

Explico la forma de esa URL para Yii Framework:


"r=orden/ver" es la forma de decirle a Yii que vaya a la controladora "ordenController.php" localizada por defecto en "protected/controllers", y que en esa clase busque el ACTION "ver". Habrás pensado que cuando puse "ver" en la url haya sido respecto a la vista "/protected/views/orden/ver.php" pues no, es el action dentro de ordenController.php.


¿ Cómo se pone ese action en ordenController.php ?


asi: Editas /protected/controller/ordenController.php y dentro escribes:

Código:
<?php
public function OrdenController extends CController {
    public function actionVer($idorden){
        $model = Orden::model()->findByPk($idorden);
        if($model != null){
           $this->render("ver", array('laorden'=>$model));
        }else{
           throw new CHttpException(404, "orden no hallada");
        }
    }
}
?>

Fíjate que es dentro de actionVer en donde se invoca al modelo segun el argumento de la URL, para entonces finalmente pedirle al controller que haga una presentacion de la vista "
ver.php" ( render('ver') ), la cual "se asume que" estara localizada en:
protected/views/orden/ver.php. Pestale cuidado a por qué puse la palabra "ver" en color rojo.

El layout

Es importante, es quien da el marco html para que dentro de el se presenten las vistas, habras asumido que no tendrás que poner en cada vista el cintillo...el banner..el sidebar...estas en lo cierto. Eso lo hace el layout, veras que cada controller puede tener un atributo llamado "layout", que por defecto puede ser:
public $layout = '\layouts\main'; eso le dice a Yii que para renderizar las vistas del controller lo haga usando el layout localizado en protected/views/layouts/main.php, el cual a su vez veras que incluye otros mas, pero eso es tema mas avanzado, aqui quiero que conozcas la base sin muchos detalles.

Muy Importante:  Dónde se presenta la vista en un Layout ?

En Yii hay una variable clave llamada $content.   En donde esa variable se ponga será allí en donde la vista se dibuje.

Fíjate este ejemplo, podria estar perfectamente ubicado en:  tuapp/protected/views/layouts/prueba.php, y para que Yii lo use para renderizar una vista hay que mencionarlo en el controller en el atributo $layout.

<html>
   <body>
         <span>Aqui va el cuerpo: </span>
         <div><?php echo $content; ?></div>
   </body>
</html>

Lo que hará será incrustar allí (donde este $content) el contenido de aquella vista que en un controller qusimos "renderizar" usando una llamada a $this->render('ver');

Cómo funciona YII

1) Tu usuario pone en el browser:  http://website.com/cosa/index.php?r=site/prueba

2) El archivo index.php recibe el request (siempre lo hace, jamas otro script recibe el foco).

3) El core de Yii levanta tu archivo de config indicado en index.php y de éste se incializa.

4) Levanta a:  protected/controllers/siteController.php.  (sensible a mayusculas minusculas).

5) Busca el método: "public function actionPrueba" y lo ejecuta.

6) Si la URL incluye argumentos como: &cedula=123&nombre=christian, se los pasará como argumentos al método actionPrueba, por tanto si esperas esos argumentos, ponlos en el método asi:
public function actionPrueba($cedula="", $nombre="").
(nota el ="" detras de cada argumento, eso dice que son opcionales, si no lo pones así entonces ocurrirá una excepción si el usuario no los indica en la URL).

7) En el método actionPrueba es donde tu actuas.  Podrias levantar un modelo cualquiera asi:
public function actionPrueba($idproducto){
   $p = Producto::model()->findByPk($idproducto);
   if($p != null){
      $this->render('producto', array('cosa'=>$p));
   }
}

8) Siguiendo el ejemplo del paso 7, has indicado que quieres renderizar la vista "producto":
"/protected/views/prueba/producto.php", eso es debido a que en el paso 7 solo pusiste "producto" sin ruta, (si quisieras indicar la ruta de otra vista pondrias:
"applications.views.otrolado.detalle", eso usaría la vista: "protected/views/otrolado/detalle.php")

9) La vista "producto.php" es levantada del disco, y se le entregan variables PHP, cuales variables ? las que le diste en el paso7 mediante un array, por tanto dentro de la vista producto.php puedes escribir esto:
<?php
   echo "has invocado a la vista. el objeto entregado por el controller es: "
      .$cosa->idproducto.", ".$cosa->nombreProducto;
?>

10) Cuando en el paso 7 llamaste a render, Yii le dio a tu vista unas variables, las has usado para crear la vista y ahora sera insertada en el Layout.  Yii va a levantar el Layout indicado en el controller, según la variable indicada:

public function siteController extends CController {
    public $layout = "mi-layout";
    ...
}

Se usara al achivo:  protected/views/layouts/mi-layout.php,  Yii cargará toda la vista recien renderizada en el paso 9 en una variable especial llamada: $content la cual tu vas a poner en algun lado del layout: literalmente donde te de la gana:

<!-- contenido del archivo: protected/views/layouts/prueba.php -->
<html>

   <body>
         <span>Aqui va el cuerpo: </span>
         <div>
<?php echo $content; ?></div>
   </body>
</html>

(el texto de color "verde" es lo que se repetirá siempre, no importa cual vista estes renderizando, siempre que incluyas este layout en tu controladora)

11) El resultado del paso 10 será entregado al browser del cliente, el cual dirá:

<html>
   <body>
         <span>Aqui va el cuerpo: </span>
         <div>has invocado a la vista. el objeto entregado por el controller es: 123, Arroz</div>
   </body>
</html>





EL COMPONENTE

Cómo hacer un componente. Lee eso.

basicamente un componente aloja la lógica de negocios, yo le llamo un "API" porque es la libreria de funciones core de tu aplicacion. Hay cosas que necesitas en varias partes de la aplicacion, esas "cosas que van en varias partes" que son "reutilizables" son parte del "core" de tu aplicacion, y deben estar localizadas en un punto de comun acceso para toda la app, no abuses del componente, lo hagas un desastre, úsalo pero sin abuso.
Se usa asi:
Código:
Yii::app()->micomponente->calcularNomina($idempleado);

Esa funcion de negocios puede ser llamada desde cualquier parte de tu app, va a centralizar el proceso de calculo de de nomina de un empleado.


Y por qué no va en la clase Empleado Christian..??!! (me lo han gritado), Porque este tipo de funciones de negocio involucra muchas otras clases y no solo al Empleado, invoulcra además a la Nomina, al HoarioLaboral, al TurnoQueCumple, a muchas otras clases, entonces para no adivinar en cual de esas otras debe ir...va afuera, en un API.

Dejare el tema hasta aqui. Creo ser suficientemente claro para darte un inicio en Yii.
Suerte

6 comentarios:

  1. muy bueno y claro.
    estoy usando Yii desde hace 2 años y lo encuentro muy prometedor... el start-up de una aplicacion es en cuestion de dias ...
    Seguire al tanto de tus blogs.
    Me gustaria hacerte una consultas conceptuales de OOP en php, si es posible. Saludos

    ResponderEliminar
  2. claro que si nico. te invito al grupo de yii que tenemos en facebook.
    mas info en:
    http://www.yiiframeworkenespanol.org

    ResponderEliminar
  3. Hermano cuál seria un ejemplo de abusar de los componentes¡?

    ResponderEliminar
    Respuestas
    1. cuando una persona cree que programar un software web es equivalente a hacer una pagina web con plugins, queriendo hacer software a punta de bajarse extensiones y componentes hasta para las cosas mas triviales. eso solo abulta el software y lo hipercomplica.
      hay gente que hasta se baja una extension para manejar un array...cuando php bien tiene muchas funciones.
      no es lo mismo eso a usar una extension que administre los archivos, como el caso de mi extension yiifilemanager y su familia de componentes, que son hechos para elevar el nivel del manejo de archivos, no para reinventar la rueda.

      Eliminar
  4. ese ese foro nunca responden nada...!

    ResponderEliminar
    Respuestas
    1. el foro es mas que todo historico. la actividad esta centrada en el grupo de facebook. ya publicaste tu pregunta ahi ? con que usuario ?

      Eliminar