sábado, 1 de febrero de 2014

Relaciones entre modelos en Yii


Supongamos que tenemos 3 tablas: user, city y country, relacionadas de la siguiente forma: un usuario vive en una ciudad (user tiene un campo city_id que referencia a una entrada de la tabla city), y una ciudad pertenece a un país (city tiene un campo country_id que referencia a una entrada de la tabla country).

Si en alguna vista relacionada con los usuarios queremos mostrar información referente al país del usuario, la clave está en definir relaciones. Las relaciones entre modelos se establecen mediante la función relations(), y pueden ser de 4 tipos:
  • BELONGS_TO
  • HAS_MANY
  • HAS_ONE
  • MANY_MANY

En este caso, nos basta con relaciones BELONGS_TO, pero es bueno saber el significado de cada relación y cómo ha de usarse (alguien que sepa crear y administrar bases de datos, debería saber de entrada qué significa cada relación). Para profundizar en el tema, consultar la guía.

En el modelo User debemos definir una relación BELONGS_TO con relación a la ciudad:

        public function relations()
{
return array(
  'city' = array(self::BELONGS_TO, 'City', 'city_id');
);
}

En el modelo City debemos definir otra relación BELONGS_TO con relación al país:

        public function relations()
{
return array(
  'country' => array(self::BELONGS_TO, 'Country', 'country_id'),
);
}

Con esto es suficiente, no es necesario modificar la(s) función(es) de búsqueda del modelo User para incluir joins o cosas parecidas, el Active Record de Yii se encargará de todo.

Si por ejemplo vamos a mostrar una lista de usuarios en un CGridView, en el cual accedemos a los atributos de User como $data->username o $data->email, podemos acceder a los campos correspondientes al país, mediante $data->city['country']['name'] o $data->city['country']['population'].

Personalmente, a esto último llegué por ensayo y error, pero una vez asimilado creo que no se olvida. Si por ejemplo hubiese una hipotética tercera relación, digamos que un país pertenezca a un planeta, accederíamos a la data del planeta mediante $data->city['country']['planet']['name'] (siempre que hayamos definido una relación planet en el modelo country, lógicamente).

martes, 13 de agosto de 2013

Android PNG


Dimensiones: 1920x1080
Formato: PNG
Tamaño: 5.94MB

Para utilizar como Wallpaper, ícono, etc.

(Clic en la imagen para descargar en tamaño completo)


jueves, 1 de agosto de 2013

Menú desplegable simple (HTML/CSS)


Esta mañana, un cliente me pedía un menú desplegable (dropdown menu) para su sitio web (hecho en HTML puro). Cosa muy sencilla, que va de ocultar/mostrar elementos con la propiedad display de CSS.

En code-tricks tienen un excelente ejemplo de menú desplegable, hecho con listas. El menú de mi cliente está hecho con tablas, así que para modificar su código lo menos posible, adapté el ejemplo de code-tricks para tablas. Por supuesto, siendo obsoleto el uso de tablas para maquetación, recomiendo utilizar listas, pero por si acaso se presenta el caso, les muestro el código.

El HTML:

<table cellpadding="0" cellspacing="0" style="text-align:center">
  <tr>
    <td class="menu" width="120">
   <a href="#">Item 1</a>
   <ul class="sub-menu">
        <li><a href="sub1-1.htm">Sub Menu 1-1</a></li>
  <li><a href="sub1-2.htm">Sub Menu 1-2</a></li>
  <li><a href="sub1-3.htm">Sub Menu 1-3</a></li>
  <li><a href="sub1-4.htm">Sub Menu 1-4</a></li>
   </ul>
 </td>
    <td class="menu" width="120">
   <a href="#">Item 2</a>
   <ul class="sub-menu">
        <li><a href="sub2-1.htm">Sub Menu 2-1</a></li>
  <li><a href="sub2-2.htm">Sub Menu 2-2</a></li>
  <li><a href="sub2-3.htm">Sub Menu 2-3</a></li>
   </ul>
 </td>
    <td class="menu" width="120">
   <a href="#">Item 3</a>
   <ul class="sub-menu">
        <li><a href="sub3-1.htm">Sub Menu 3-1</a></li>
  <li><a href="sub3-2.htm">Sub Menu 3-2</a></li>
  <li><a href="sub3-3.htm">Sub Menu 3-3</a></li>
   </ul>
 </td>
    </tr>
</table>

El CSS:

.menu, .menu ul.sub-menu {
    padding:0;
    margin: 0;
}
.menu ul.sub-menu li {
    list-style-type: none;
    display: inline-block;
    background: url(../images/nav-bar.png) center left repeat-x;
}
.menu a, .menu ul.sub-menu li a {
    text-decoration: none;
    padding: 5px;
    display:inline-block;
}
.menu {
    position: relative;
}
/*sub menu*/
.menu ul.sub-menu {
    display:none;
    position: absolute;
    top: 40px;
    width: 100px;
}
.menu:hover ul.sub-menu {
    display:block;
}

Y el resultado es este:



Por supuesto necesitaremos darle formato para adaptarlo a las necesidades del momento. Este ejemplo es sólo una base para ello.

jueves, 25 de julio de 2013

ndiswrapper y Ubuntu 13.04

En un artículo anterior describí como logré hacer funcionar mi tarjeta Encore ENLWI-NX2 en Ubuntu 10.10, utilizando ndiswrapper para utilizar el driver de Windows, ya que no existía un driver nativo para Linux. Posteriormente conté qué tuve que hacer cuando mi tarjeta dejó de funcionar tras un upgrade a Ubuntu 12.04.

Bien, hoy realicé una instalación limpia de Ubuntu 13.04, y esto fue lo que tuve que hacer para que mi ENLWI-NX2 funcionara.


1) Descargar e instalar dkms

Asumiendo que no tenemos otra forma de conexión a Internet, toca descargar los paquetes desde otra máquina y llevarlos en una memoria flash, o algo así.

El paquete se puede descargar desde aquí: dkms y luego lo instalamos con:
sudo dpkg -i dkms.deb //usar el nombre específico del .deb descargado


2) Descargar, compilar e instalar ndiswrapper

En algún foro recomendaban instalar directamente el paquete ndiswrapper-dkms (junto con ndiswrapper-common). A mí no me funcionó (Linux no reconocía el módulo, no investigué mucho por qué), por lo cual opté por bajar el código fuente desde aquí, y luego compilarlo e instalarlo con:
make
sudo make install


3) Descargar e instalar ndiswrapper-dkms

Bajar desde aquí e instalar con:
sudo dpkg -i ndiswrapper-dkms.deb //usar el nombre específico del .deb descargado


4) Instalar el controlador de la tarjeta

sudo ndiswrapper -i DRIVERNAME.inf //logicamente debemos tener el .inf


5) Cargar el módulo ndiswrapper
depmode -a
modprobe ndiswrapper


6) Agregar ndiswrapper a /etc/modules
Para que ndiswrapper se cargue cada vez que arranque el sistema, agregar ndiswrapper a
/etc/modules.


Eso es todo, ya podremos conectarnos a nuestra red Wi-Fi favorita :)






lunes, 24 de junio de 2013

Creación de Imágenes ISO en Ubuntu con Brasero

Brasero es probablemente la aplicación para creación de discos más usada en Linux, y es además realmente sencilla. A continuación, muestro dos ejemplos de uso para la creación de imágenes (ISO en este caso).


Caso 1: ISO a partir de CD/DVD

Insertamos el disco del que queremos extraer la imagen, abrimos Brasero y seleccionamos Disc Copy. A continuación seleccionamos la unidad donde insertamos el disco y escogemos Image File.

Por omisión, Brasero graba las imágenes en formato .toc, por lo que debemos hacer click en Properties y seleccionar .iso (también acá podemos seleccionar la ruta donde se guardará el archivo).


Finalmente hacemos Create Image y esperamos que se genere nuestro archivo.





Caso 2: ISO a partir de archivos/directorios

Si lo que tenemos es un conjunto de directorios y archivos en nuestro ordenador, a partir del cual queremos hacer un archivo ISO, debemos seleccionar Data Project, y añadir todos los archivos/directores que deben ir a la imagen, tal como si fueramos a crear una copia física.

Seleccionamos Image File y luego hacemos clic en Burn (Si brasero no detecta un disco virgen en la unidad, mostrará un breve mensaje y seleccionará Image File por omisión).


Al hacer clic en Burn, Brasero nos pedirá el nombre y ubicación del archivo.


Para terminar, hacemos clic en Create Image y comenzará el proceso de creación de la imagen.



jueves, 7 de marzo de 2013

Marca de agua con GIMP

Conozco 2 opciones a la hora de crear una marca de agua para nuestras fotografías: guardarla como PNG (o nuestro formato de preferencia) y luego pegarla sobre cada fotografía, o guardarla como un pincel/brush. Guardar nuestra marca como imagen, permite que la podamos usar en prácticamente cualquier editor de imágenes, mientras que los brushes son relativos a la aplicación que usemos (generalmente). Sin embargo, si utilizamos siempre una misma herramienta de edición, es más fácil crear un brush una vez y usarlo luego utilizarlo, además de que seguramente así tendremos muchas más opciones.

Bien, la herramienta que yo uso es GIMP, y a continuación describo cómo guardar (y cómo usar luego) nuestras marcas de agua como archivos GBR (Gimp Brush).

Comenzamos creando un nuevo archivo fondo transparente, como se ve en la siguiente imagen.



Las dimensiones no tienen que ser exactamente esas, pueden ser mucho más pequeñas si va a ser una marca simple. Todo depende de la calidad de imágenes que vayamos a firmar, si son muy grandes, nuestra firma también debería serlo.

El siguiente paso es crear la firma... Allí es donde entran los gustos y la creatividad de cada quien. Bien, yo hice una simple para este ejemplo que es sólo el texto '@marcocamejo'.

Si hemos usado varias capas, antes de guardar, debemos mezclarlas (Image > Merge visible layers). También es muy recomendable eliminar el espacio que sobre (Image > Autocrop image).

Bien, una vez terminada la firma, guardamos con extensión .gbr. GIMP mostrará el siguiente cuadro.



Luego, para que GIMP reconozca el brush, debemos copiar el archivo gbr al directorio de brushes de GIMP. En esta máquina (con Ubuntu 12.10 y GIMP 2.6), ese directorio es $HOME/gimp-2.6/brushes.

Y eso es todo. Cada vez que queramos firmar una fotografía, sólo debemos usar la herramienta paintbrush y escoger nuestro pincel.



Como ven, y como comentaba al comienzo, de esta forma tenemos algunas opciones para configurar nuestra firma (escala, opacidad, etc).






martes, 12 de febrero de 2013

Creando parches para el kernel de Linux


Como parte del producto de mi trabajo de maestría en Computación, he requerido generar un parche para el kernel de Linux. El proceso es muy sencillo, y no es muy diferente al crear un parche de cualquier archivo o directorio común y corriente, utilizando el comando diff. Resumo el proceso en 3 pasos.

1. Preparar los directorios

Debes tener un directorio con el kernel vanilla y otro directorio con el kernel modificado. Por supuesto, deben corresponder a la misma versión. En mi caso, estoy trabajando con la versión 3.2.1, y he nombrado linux-3.2.1 a mi kernel modificado y linux-vanilla-3.2.1 al kernel vanilla.

Ambos kernels los tengo en el directorio /usr/src, pero esto no es necesario, pueden estar en un directorio cualquiera.

2. Limpiar ambos directorios

Asumiendo que los kernels se encuentran en /usr/src, basta con ejecutar:
cd /usr/src/linux-3.2.1
make mrproper
make clean
cd ../linux-vanilla-3.2.1
make mrproper
make clean

3. Generar el parche

Finalmente, usamos el comando diff para generar el parche:
cd /usr/src/
diff -Nur linux-vanilla-3.2.1 linux-3.2.1 > patch-3.2.1

¡Y eso es todo! El archivo patch-3-2.1 es nuestro parche.

NOTA: al usar el comando diff, el orden es importante, primero va el kernel vanilla y luego el modificado, no al revés.