Jun 30

Los componentes en Yii

Tagged with:
Categories: Sindicados
Estadísticas: 4 consultas Comments Off

Introducción.

  • Son objetos escritos basados en una especificación.
  • Heredan de la clase CComponent.
  • Es posible acceder y modificar sus propiedades así como lanzar y manejar sus eventos.

Propiedades.

  • Son atributos públicos de lectura y escritura.
  • Pueden definirse de dos maneras.
    • Declarando un atributo público en el componente.
      • En este caso el nombre de la propiedad es sensible a mayúsculas.
    • Definiendo los métodos setter y getter correspondientes.
      • En este caso el nombre de la propiedad no es sensible a mayúsculas.
      • Para implementar la propiedad imageType es necesario implementar los siguientes métodos.
        public function getImageType()
        {
            return $this -> _imageType;
        }
        
        public function setImageType($value)
        {
            $this -> _imageType = $value;
        }
      • Este método es mas flexible ya que permite definir una lógica del negocio que condicione el acceso a las propiedades.
      • De igual manera es posible implementar propiedades de sólo lectura (sin setter) o de sólo escritura (sin getter).

Eventos.

  • Los eventos del componente son propiedades que toman referencias a métodos (event handlers) como valores.
  • Estos métodos son invocados automáticamente cuando sucede el evento asociado.
  • Un evento del componente es definido por la implementación de un método cuyo nombre empieza por on y termina con el nombre del evento asociado (no es sensible a mayúsculas).
    • Para el evento click -> el método deberá ser entonces: onClicked.
      public function onClicked($event)
      {
          // ...
      }
  • Los eventos ($event) son instancias de la clase CEvent.
  • Los manejadores de evento se asginan de la siguiente manera.
    $component -> onClicked = $callback;
    • $callback deberá ser una referencia válida en PHP según las siguientes opciones.
      • El nombre de una función global.
      • Un método de una clase, para este caso deberá ser de la forma array($objeto, 'nombreMétodo').
  • Varios manejadores de evento pueden asociarse a un mismo evento, estos se ejecutarán en el orden en que fueron creados.
  • Un manejador de eventos puede evitar que se invoquen los demás manejadores de eventos al realizar la siguiente modificación.
    $event -> handled = true;

Comportamientos.

  • Un comportamiento es un objeto cuyos métodos pueden ser transferidos a los componentes que se le agreguen.
  • Es decir, reune funcionalidades en lugar de realizar una especialización como lo hace la herencia convencional.
  • Es posible agregar múltiples comportamientos lo que se asemeja a la herencia múltiple.
  • Son análogos a los mixins que incluyen otros lenguajes orientados a objetos (como Ruby) o que implementan otros frameworks (como Symfony).
  • Existen varias maneras de implementar un comportamiento.
    • Como una clase que implementa a la interfaz IBehaviour.
    • Como una clase que hereda de CBehaviour.
    • Si va a ser agregado a un modelo puede ser una clase que herede de CModelBehaviour o CActiveRecordBehaviour según corresponda.
  • Para utilizar un comportamiento primero debe ser agregado a un componente.
    $comportamiento -> attach($nombre, $componente);
    $componente -> métodoDelComportamiento();
  • Los comportamientos pueden ser activados y desactivados según se desee en cada componente.
    $componente -> enableBehaviour($nombre);
    $componente -> disableBehaviour($nombre);
  • Si dos o mas comportamientos agregados a un componente entran en conflicto porque tienen métodos con igual nombre, la precedencia la tendrá el comportamiento que haya sido agregado primero.

Enlaces.

Jun 30

Los módulos en Yii

Tagged with:
Categories: Sindicados
Estadísticas: 6 consultas Comments Off

Introducción.

  • Son unidades autocontenidas de software.
  • Tienen sus propios modelos, vistas, controladores y demás componentes de soporte.
  • Se asemejan a una aplicación pero no pueden ser desplegados individualmente, deben residir como parte de  una aplicación.
  • Los usuarios acceeden a los controladores de los módulos de la misma forma como se acceden los controladores convencionales.
  • Son útiles para dividir el desarrollo y mantenimiento de aplicaciones muy grandes en módulos independientes.
  • Facilitan la reutilización de código a alto nivel.
  • Se utilizan para implementar funcionalidades como autenticación, manejo de usuarios, manejo de comentarios, etc.

Estructura.

  • Cada módulo tiene una clase principal que hereda de CWebModule.
  • El nombre de la clase se determina de la siguiente manera: ucfirst(IdentificadorMódulo) . 'Module'.
    • Ejemplo, la clase del módulo gallery debe llamarse GalleryModule.
  • Esta clase se utiliza para almacenar información y características que son comúnes a todo el módulo.
    • CWebModule::params almacena los parámetros del módulo.
    • CWebModule:: components comparte componentes de aplicación a nivel del módulo.

Creación.

Utilizando yiic.

yiic permite crear fácilmente un esqueleto básico del módulo para empezar a trabajar sobre él.

$ cd WebRoot/MiAplicacion
$ protected/yiic shell

Yii Interactive Tool v1.0
Please type 'help' for help.  Type 'exito' to quit.

>> module gallery

Uso.

  • Copie el directorio del módulo en el directorio modules de la aplicación.
  • Declare el módulo (con su identificador) en la propiedad modules de la configuración de la aplicación de la siguiente manera.
    return array (
        // ...
        'modules' => array('gallery', /* ... */),
        // ...
    );
  • Es posible especificar valores iniciales para las propiedades del módulo de la siguiente manera.
    return array (
        // ...
        'modules' => array(
            'gallery' => array(
                'fileType' => 'png',
                'rows' => 10,
                'cols' => 3
            ),
            /* ... */
         ),
        // ...
    );
  • La instancia del módulo puede ser accedida a través de la propiedad module del controlador acrivo.
    $rows = Yii::app() -> controller -> module -> rows;
  • Los módulos se acceden con la ruta módulo/controlador/acción.
    • Para el ejemplo, gallery/image/add corresponderá entonces con el URL http://www.servidor.com/index.php?r=gallery/image/add.
  • Un módulo puede contener a su vez a otros módulos los cuales pueden ser accedidos de manera similar: móduloPadre/móduloHijo/controlador/acción.

Enlaces.

Jun 29

Plantillas para documentos XHTML y otros recursos web

Tagged with:
Categories: Sindicados
Estadísticas: 7 consultas Comments Off

En el sitio de WebStandards se puede encontrar un listado con las plantillas base para los documentos XHTML 1.0/1.1 y HTML4.

Además de estos documentos encontré otros recursos interesantes relacionados con el desarrollo web.

http://www.webstandards.org/learn/tutorials/accessible-forms/

Jun 28

Remover estilos CSS por defecto

Tagged with:
Categories: Sindicados
Estadísticas: 16 consultas Comments Off

Introducción.

El primer paso para desarrollar cualquier interfaz de usuario basada en HTML debería ser el remover los estilos introducidos por defecto por el navegador web, con esto podríamos estar [un poco mas] seguros que los estilos implementados van a tener un igual comportamiento entre los diferentes tipos de navegadores web.

Hacer esto es muy fácil, sólo es necesario incluír el siguiente estilo provisto por Yahoo! al inicio de la hoja de estilos principal (la primera que se carga).

/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.7.0
*/
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}body{text-align:center;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main,.yui-g .yui-u .yui-g{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g .yui-u{width:48.1%;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}.yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#hd:after,#bd:after,#ft:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#hd,#bd,#ft,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}

Otra forma de hacerlo es simplemente hacer una referencia a esta hoja de estilos desde los servidores de Yahoo!.

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/reset-fonts-grids/reset-fonts-grids.css">

Enlaces.

Jun 24

Creación de contenido traducido en Drupal 6

Tagged with:
Categories: Sindicados
Estadísticas: 7 consultas Comments Off

Introducción.

Este procedimiento permite mantener diferentes tipos de contenido en Drupal 6 traducido en los diferentes idiomas que soporta el Portal.  En esta versión, a diferencia de la versión 5, el módulo que permite esto se incluye en la distribución de core.

Configuración.

Activar el módulo de traducción de contenido.

  • Acceder a http://www.servidor.com/?q=admin/build/modules.
  • Activar el módulo Content translation encontrado en la sección opcional de core.

Asignar los permisos de traducción.

  • Acceder a http://www.servidor.com/?q=admin/user/permissions.
  • Asignar el permiso Translation > traducir contenido a los roles que estarán encargados de realizar la traducción de los contenidos.

Determinar los idiomas soportados por el portal.

  • Acceder a http://www.servidor.com/?q=admin/settings/language.
  • Agregar los idiomas necesarios además del idioma predefinido para el sitio.

Determinar cuales tipos de contenido tendrán traducción.

  • Acceder a http://www.servidor.com/?q=admin/content/types.
  • Elegir los tipos que tendrán contenido traducido.
  • Editar los tipos.
  • En la sección Workflow settings > Multilingual support seleccionar la casilla de verificación Habilitado con traducción.
  • Guardar.

En mi caso personal elegí los siguientes tipos de contenido para tener traducción: Evento, Noticia, Página, Página de grupo, Tema de foro y Enlaces web.

Activar el bloque para cambio de idiomas (opcional).

  • Acceder a http://www.servidor.com/?q=admin/build/block.
  • Activar y ubicar donde se desee al bloque Language switcher.

Utilización.

Después de realizado este el procedimiento de configuración, los tipos de contenido configurados para tal fin tendrán un nuevo campo llamado Idioma el cual permitirá elegir entre Lenguaje neutral y Español (o el idioma predeterminado elgido anteriormente).

Para acceder a la traducción del contenido es necesario editar el contenido inicial y seleccionar a Español como idioma.  Al guardar este contenido aparece una nueva opción llamada Traducción (Translate) a través de la cual es posible seleccionar cualquiera de los demás idiomas configurados para crear la traducción del contenido inicial.

Cuando se consulta un nodo este muestra con enlaces cuales son las traducciones que se encuentran disponibles y permite acceder a ellas, de igual manera es posible modificar el idioma del sitio utilizando el bloque de cambio de idioma.

Enlaces.

Jun 23

Las vistas en Yii

Tagged with:
Categories: Sindicados
Estadísticas: 7 consultas Comments Off

Introducción.

  • Son archivos PHP convencionales.
  • Pueden incluír elementos de interfaz de usuario basados en Yii.
  • Se recomienda que las vistas accedan a la información de los modelos pero que no los modifiquen.
  • Deben permanecer lo mas simples posibles, lógicas complejas deberían llevarse hasta el controlador.
  • El nombre del archivo donde se almacena la vista corresponde con el identificador junto con la extensión .php.
    • La vista edit se almacenará en el archivo edit.php.
  • Los archivos de las vistas se almacenan bajo la ruta protected/views/<Identificador del controlador>.
  • Desde la vista es posible acceder a los atributos del controlador a través del objeto $this.
  • Para procesar una vista se debe invocar el método CController::render(<Identificador de vista>).
  • Es posible pasar explícitamente información desde el controlador a la vista en el momento de su generación.
    $this -> render('edit', array (
        'variable1' => $valor1,
        'variable2' => $valor2
    ));
    • En la vista edit se podrá acceder a $variable1 y $variable2 como variables convencionales.

Layouts (diseños).

  • El layout permite especificar el diseño común y constante de la interfaz de usuario.
  • Evita la necesidad de agregar elementos comúnes (archivos javascript y css, título, subtítulo, menú izquierdo, pies, etc) a todas las páginas en cada una de ellas.
  • El layout aplica a todo el sitio web y se aplica automáticamente al invocar el método render.
  • Para generar una vista sin el layout es necesario utilizar el método renderPartial.
  • El layout utilizado por defecto se encuentra en views/layouts/main.php.
    • Es posible modificar esto alterando CWebApplication::layout para toda la aplicación o CController::layout para todas las acciones del controlador.
  • En el layout se debe incluír la variable $content para especificar la ubicación en la que se agregará el contenido de la vista específica al controlador/acción ejecutado (parte no constante de la interfaz de usuario).

Widgets.

  • Los widgets son componentes predefinidos para la presentación de la interfaz de usuario.
  • Generalmente agregan una funcionalidad gráfica compleja, específica y autocontenida.
  • Heredan de CWidget.
  • Su forma de invocarlos depende de si tienen o no contenido en su cuerpo.
    • Sin contenido en su cuerpo.
      <? php $this -> widget('ruta.a.la.ClaseWidget'); ?>
    • Con contenido en su cuerpo.
      <? php $this -> beginWidget('ruta.a.la.ClaseWidget'); ?>
      ... contenido del cuerpo del Widget ...
      <? php $this -> endWidget(); ?>
  • Es posible definir valores iniciales para los atributos del Widget durante su invocación con widget o beginWidget.
    $this -> widget('CMaskedTextField', array (
        'mask' => '99/99/9999'
    ));

Creación de nuevos Widgets.

  • El nuevo widget debe heredar de CWidget e implementar los métodos init y run.
    class NuevoWidget extends CWidget
    {
        public function init()
        {
            // Invocado por CController::beginWidget().
        }
    
        public function run()
        {
            // Invocado por CController::endWidget().
        }
    }
  • Tienen sus propias vistas y se ubican por defecto en el directorio views bajo el directorio que contiene la clase del widget.
  • Estas vistas se generan invocando CWidget::render().

Vistas del sistema.

  • Estas vistas se utilizan para mostrar errores del sistema o información de registro.
  • Las excepciones de HTTP (CHTTPException) se despliegan con las vistas errorXXX donde XXX es el código del error HTTP generado.
  • Las vistas por defecto provistas por Yii se ubican en framework/views y pueden personalizarse definiéndolas en protected/views/system.

Enlaces.

Jun 22

Los Controladores en Yii

Tagged with:
Categories: Sindicados
Estadísticas: 16 consultas Comments Off

Introducción.

Estructura de una aplicación Yii.

Estructura de una aplicación Yii.

  • El Modelo/Vista/Controlador es un patrón de diseño.
  • Su utilidad radica en separar la lógica del negocio de la interfaz de usuario.
  • El modelo representa la información y las reglas del negocio asociadas a ella.
  • La vista representa a los componentes de la interfaz de usuario y todo lo relacionado con su presentación.
  • El controlador recibe la solicitud del usuario (controlador, acción e información) e intermedia entre la vista y los modelos para elaborar la respuesta.
  • El controlador frontal (index.php) recibe directamente la solicitud del usuario, es el único que interactúa directamente con él, y se encarga de enrrutar la solicitud al controlador y acción apropiados.
  • Consultar secuencia de procesamiento de un requerimiento.

El controlador.

  • Hereda de CController.
  • Su identificador es de la forma ruta/a/xyz (ejemplo: user).
  • Corresponde con el archivo protected/controllers/ruta/a/XyzController.php (ejemplo: protected/controllers/UserController.php).
  • Si la aplicación utiliza módulos, su identificador se incluye en la ruta del identificador del controlador.
  • Incluye una o mas acciones.
  • Incluye cero o mas filtros para sus acciones.
  • La instanciación de un controlador puede realizarse de la siguientes maneras según el contexto.
    • Si se define CWebApplication::catchAllRequest, todas las solicitudes serán redireccionadas al controlador indicado ignorándose el solicitado.  Es útil para poner el sitio fuera de línea.
    • Si el identificador del controlador solicitado se encuentra en CWebApplication::controllerMap se utilizará el controlador asociado en la conversión.
    • Se busca el controlador en la ubicación específica según su ruta.
    • Si el controlador no existe se lanza una CHttpException 404.

Las acciones.

  • Definen (implementan) que hacer ante el requerimiento específico de un usuario.
  • Si no se especifica una acción se utiliza la acción por defecto (index) que puede configurarse con CController::defaultAction.
  • Pueden implementarse de dos maneras.
    • Como un método del controlador cuyo nombre deberá ser actionIdentificador.
      • La acción add corresponderá con el método addView.
    • Como una nueva clase que hereda de CAction cuyo nombre deberá ser IdentificadorAction e implementa el método run.
      • La acción add en este caso corresponderá con una instancia de la clase AddAction.
      • Para que este caso funcione se debe sobreescribir el método actions del controlador estableciendo la relación entre identificador de la acción y clase que la implementa.
        ...
        public function actions()
        {
            return array(
                'add' => 'application.controllers.post.AddAction'
            );
        }
        ...
      • Se recomienda almacenar las acciones bajo el alias de application.controllers.<identificador del controlador> que hace referencia a la ruta física protected/controllers/<identificador del controlador>.

Los filtros.

  • Permiten manipular el flujo de ejecución de la acción solicitada.
  • Se ejecutan antes y después de la acción solicitada permitiendo filtrar si esta es efectivamente invocada o no.
  • Útiles para realizar procesos previos de preparación (estadísticas, verificación de autenticación/autorización, etc.) y de limpieza (liberación de recursos, verificaciones finales, etc.).
  • Una acción puede tener cero o mas filtros.
  • Los filtros se ejecutan en el mismo orden en que fueron definidos.
  • Un filtro puede decidir si los demás filtros o la acción no deben ser ejecutados.
  • Al igual que las acciones, los filtros pueden implementarse de dos maneras.
    • Como un método del controlador cuyo nombre deberá ser filterIdentificador.
      • El filtro editPassword corresponderá con el método filterEditPassword.
        public function filterEditPassword($filterChain)
        {
            // $filterChain -> run() continúa la ejecución de los filtros.
        }
    • Como una nueva clase que hereda de CFilter cuyo nombre deberá ser IdentificadorFilter.
      • Se deben implementar los métodos preFilter y postFilter que se ejecutarán antes y después de invocarse la acción.
        class CheckAuthFilter extends CFilter
        {
            protected function preFilter($filterChain)
            {
                // Ejecutado antes de invocar la acción.
                return true;   // false si se debe abortar la ejecución de la acción.
            }
        
            protected function postFilter($filterChain)
            {
                // Ejecutado después de terminar la invocación de la acción.
            }
        }
  • Es necesario sobreescribir el método CController::filters() para asociar los filtros a las acciones.
    ...
    public function filters()
    {
        return array(
            'editPassword + edit, create',                               // filtro basado en un método
    
            array (
                 'application.filters.CheckAuthFilter - logout, index',  // filtro basado en una clase
                 'tipo' => 'usuario'
            )
        );
    }
    ...
    • El filtro editPassword está implementado por un método del controlador mientras que el filtro checkAuth está basado en una clase que hereda de CFilter.
    • El alias application.filters hace referencia a la ruta física protected/filters.
    • Es posible especificar valores para los atributos del filtro utilizando un arreglo en la definición de los filters tal y como se le asigna un valor al atributo tipo del filtro checkAuth.
    • Los operadores + y - modifican el alcance de la relación entre filtros y acciones.
      • +: el filtro se aplica a las acciones especificadas.  (incluye).
        • El filtro editPassword se aplica a las acciones edit y create únicamente.
      • -: el filtro se aplica a todas las acciones exceptuando las especificadas.  (excluye).
        • El filtro checkAuth se aplica a todas las acciones menos a logout e index.

Enlaces.

    protected function preFilter($filterChain)
    {
        // Ejecutado antes de invocar la acción.
        return true;   // false si se debe abortar la ejecución de la acción.
    }
Jun 15

Comunicación de la tarjeta Arduino con el computador

Tagged with:
Categories: Sindicados
Estadísticas: 15 consultas Comments Off

Introducción.

La tarjeta Arduino incluye un puerto serial que puede accederse a través de los pines digitales 0 (RX) y 1 (TX) o desde el computador a través del puerto USB.  Esto se realiza a través del objeto Serial con el que es posible realizar las siguientes acciones.

Descripción general de las funciones de E/S.

Establecer tasa de transmisión de datos.

void Serial.begin(int velocidad);
  • Debe realizarse como paso previo a la emisión/recepción de información a través del puerto serial.
  • La tasa puede ser una de las estándar: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 y 115200, o cualquiera personalizada.
  • La velocidad utilizada para realizar la conexión con el computador es de 9600.

Verificar bytes pendientes por lectura.

int Serial.available();
  • Como su nombre lo indica, la transmisión de información a través del puerto serial se realiza de manera serial, es decir un byte a la vez.
  • Este método permite verificar si hay bytes pendientes de lectura retornando el número de bytes disponibles en el buffer del puerto serial.
  • El buffer del puerto serial puede retener hasta 128 bytes.
  • Retorna 0 si no hay bytes pendientes de lectura en el puerto.

Leer información.

int Serial.read();
  • Obtiene el siguiente byte disponible en el buffer del puerto serial.
  • Retorna -1 si no hay información disponible.

Limpiar el buffer de entrada.

void Serial.flush();
  • Limpia el buffer de entrada del puerto serial, descartando cualquier contenido que se encuentre allí.

Enviar información.

void Serial.print(datos);
void Serial.print(datos, tipo);
void Serial.println(datos);
void Serial.println(datos, tipo);
  • Envían la información (datos) en el formato especificado (tipo) a través del puerto serial.
  • El formato (tipo) puede ser uno de los siguientes.
    • DEC: representación en cadena de un número decimal (79).
    • HEX: representación en cadena de un número hexadecimal (4F).
    • OCT: representación en cadena de un número octal (117).
    • BIN: representación en cadena de un número binario (1001111).
    • BYTE: un único byte.
  • Si no se especifica un formato (tipo), se utiliza por defecto a DEC.
  • La diferencia entre print y println es que el segundo agrega un retorno de carro (ASCII 13 o '\r') y un salto de línea (ASCII 10 o '\n') al final de de la información enviada.

Enviar información binaria.

void Serial.write(datos);
void Serial.write(buffer, longitud);
  • Envía información binaria: un byte o una secuencia de bytes, al puerto serial.
  • Los datos a enviarse pueden ser un número o una cadena.
  • Si se desea enviar un arreglo (buffer) es necesario especificar su longitud.

Depurando la transmisión de datos.

Es posible revisar fácilmente con el IDE de Arduino lo que la tarjeta está transmitiendo al computador a través del puerto USB mediante el Monitor Serial.  Esto es muy útil también para la depuración rápida de los sketches.

Para activar el Monitor Serial se debe presionar el ícono serial_monitor y utilizar las funciones de envío de información mencionadas anteriormente, de esta manera aparecerá en la sección inferior del IDE una consola donde se podrán apreciar los mensajes enviados por la Arduino.

void Serial.print(datos, tipo);

Jun 15

El cuarto sketch: The LED with fotoresistor

Tagged with:
Categories: Sindicados
Estadísticas: 9 consultas Comments Off
Sketch 'The LED with fotoresistor'.

Sketch 'The LED with fotoresistor'.

Descripción.

Este sketch utiliza una fotoresistencia como sensor, es decir, la cantidad de luz recibida por el componente determina la cantidad de voltaje que es permitido pasar a través de él.  Como actuador se utiliza el mismo LED de siempre que nos mostrará de manera visual cuanto voltaje atravieza por el sistema.

A mayor cantidad de luz percibida el LED tendrá un mayor brillo.

Implementación.

Hardware.

En términos de la implementación del hardware suceden dos cosas interesantes.

  1. Como ya se había hecho en el sketch anterior, The LED with button and fade, para provocar el efecto de intensidad de luz del LED es necesario conectarlo a uno de los pines con soporte para modulación por ancho de pulsos (PWM), es decir, a los pines 9, 10 y 11, y enviarle la inforamción correspondiente con la instrucción analogWrite.
  2. La foto resistencia, a diferencia del botón que tiene sólo dos estados: presionado o no presionado, es capaz de producir un rango de valores según la cantidad de luz que recibe en un momento específico del tiempo.  Para leer su información es necesario utilizar las entradas (pines) análogos ubicados en la parte inferior derecha de la tarjeta Arduino y leer su información con la instrucción analogRead.

Software.

En términos de software el sketch es muy sencillo, sólo debe realizar los siguientes pasos.

  1. Leer estado del sensor.
  2. Modificar la intensidad del LED de acuerdo a lo leído del sensor.
  3. Esperar un momento para reinciar la iteración.

Es muy importante tener en cuenta que la instrucción analogRead retornará un número entre 0 y 1023 mientras que la instrucción analogWrite espera un valor numérico como parámetro entre 0 y 255, por esto será necesario dividir entre 4 el valor de la lectura hacia la escritura si se va a utilizar directamente.

#define SENSOR 0                    // Analog pin for the fotoresistor
#define LED    9                    // Digital pin (PWM) for the LED

void setup()
{
  pinMode(LED, OUTPUT);            // LED pin is output

  // Analog pins are always INPUT.
}

void loop()
{
  int fr = analogRead(SENSOR);      // Read the status of the fotoresistor

  analogWrite(LED, fr/4);           // Change the brightness of the LED
                                    // acording the fotoresistor's value
  delay(10);                        // Wait a moment fot next iteration
}
Jun 11

Actualización del Kernel en Ubuntu 9.04

Tagged with:
Categories: Sindicados
Estadísticas: 10 consultas Comments Off

Introducción.

El día de hoy voy a actulizar el kernel del equipo de la oficina que tiene actualmente un 2.6.28-11-generic #42-Ubuntu SMP.  La nueva versión será la 2.6.29-4.

Supuestamente la versión actual tiene algunos problemas, en particular con las tarjetas de video Intel.  A pesar de que la tarjeta de video de este equipo es NVidia 7x si he notado a esta nueva versión de Ubuntu mas lenta, especialmente en temas de manejo de ventanas, así que voy a experimentar con la actualización a ver si se mejoran.

La versión 2.6.30 se encuentra disponible desde el día de ayer sin embargo leí en varios foros acerca de la posible incompatibildad con cierto hardware así que prefiero ir dando un pasito a la vez.

Procedimiento.

Descargar los paquetes requeridos del Kernel.

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-headers-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-headers-2.6.29-02062904_2.6.29-02062904_all.deb

$ wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.29.4/linux-image-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

Instalar los paquetes del Kernel.

$ sudo dpkg -i linux-headers-2.6.29-02062904-generic_2.6.29-02062904_i386.deb linux-headers-2.6.29-02062904_2.6.29-02062904_all.deb linux-image-2.6.29-02062904-generic_2.6.29-02062904_i386.deb

Reiniciar el sistema.

$ sudo reboot.

Enlaces.