Cómo instalar Guest Additions en una Debian corriendo en VirtualBox?

VirtualBox es una excelente herramienta para virtualizar sistemas operativos x86/amd64.

Una vez instalado y configurado tu sistema operativo puede interesarte instalar las Guest Additions que son un paquete de librerías y controladores proporcionados por VirtualBox que le permiten mejorar la virtualización del sistema operativo.

Algunas de las mejoras que presentan las Guest Additions de Virtualbox son:

  • Integración del mouse en el sistema operativo virtualizado permitiendo moverlo libremente dentro y fuera de él.
  • Mejoras en el soporte de vídeo.
  • Nos permite compartir carpetas entre nuestro sistema operativo real y el virtualizado.
  • Portapapeles compartido entre los dos sistemas operativos.
Cómo podemos instalar las Guest Additions en una Debian corriendo en Virtualbox?
Por suerte VirtualBox tiene preparado un pequeño sistema para facilitar la instalación de estas herramientas. Únicamente deberás seguir los siguientes pasos una vez tengas configurada tu Debian:
  1. Encender la máquina virtual.
  2. Accede a ella con un usuario con permisos de root.
  3. Haz update de los repositorios con: apt-get update;
  4. Actualiza a los últimos parches de seguridad con: apt-get upgrade;
  5. Instala los paquetes necesarios para el correcto funcionamiento de las Guest Additions con el comando: apt-get install build-essential module-assistant;
  6. Configura tu sistema para permitir instalar modulos compilados lanzando el comando: m-a prepare;
  7. Una vez hecho esto, haz click en el menú Devices the tu VirtualBox y elige la opción del sub-menú Install Guest Additions… Esto preparará una unidad que podrás montar desde Debian.
  8. Monta la unidad con el comando: mount /media/cdrom.
  9. Ahora sólo nos queda correr el script que instalará las Guest Additions lanzando: sh /media/cdrom/VBoxLinuxAdditions.run

Posted in Sin categoría |

Usar registro SPF para no ser detectado como SPAM

Cuando configuras un servidor hay un tema que suele dar bastante quebraderos de cabeza y es el de como configurarlo para que los mensajes enviados desde él no sean configurados como SPAM.

En mi caso, utilizo Google Apps como servidor de correo y además, el formulario de contacto de esta web también envía mails desde el dominio manelperez.com, por ejemplo, contact@manelperez.com

Tras las primeras pruebas detecté que los mensajes enviados desde el formulario de contacto eran marcados como SPAM y tras buscar un poco de información, encontré la solución en los registros SPF configurables en tu zona DNS.

Un registro SPF (Sender Policy Framework) informa a un servidor de correo que recibe un mail cuales son las direcciones IP autorizadas para enviar correos desde el dominio recibido, de este modo, cuando llega un mail desde contact@manelperez.com a una dirección de correo de yahoo, el servidor de yahoo consultará las DNS para el dominio manelperez.com, comprobará si la IP desde la que se envió el correo está recogida dentro de las IPs permitidas identificadas en el registro SPF y si lo está, lo marcará como seguro.

Como configurar un registro SPF?

Configurar un registro SPF es tan sencillo como añadir un registro del tipo TXT en tu zona DNS con una sintaxis específica.

Si quieres permitir que tanto los servidores de google (recuerda que en mi caso utilizo Google Apps) como la IP 125.125.125.1 sean marcados como servidores seguros para enviar mails, deberás añadir un registro TXT con el siguiente valor:

v=spf1 include:_spf.google.com ip4:125.125.125.1 ~all

De este modo, ayudaremos a los servidores de correo a detectar los correos enviados desde Google y desde la IP 125.125.125.1 como válidos.

Error con setlocale()… devuelve false

i18nLos usuarios de Ubuntu, pueden encontrarse con un problema al hacer una llamada a la función setlocale() encargada de asignar el idioma correcto para, por ejemplo, llamar a la función getText() y que recoja las traducciones en el idioma correcto.

El problema está en que únicamente podemos cargar los idiomas que están presentes en el sistema operativo y si intentamos cargar uno diferente, setlocale() nos devolverá siempre false.

Podemos saber los idiomas cargados en el sistema operativo mediante el comando:

locale -a

Esto nos devolverá un listado similar a este:

C
en_GB.utf8
en_IN
en_NG
en_US.utf8
POSIX

Si estámos intentando cargar el idioma es_ES (como era mi caso), le resultará imposible… la solución, instalar los idiomas que necesitamos lanzando el comando:

apt-get install language-pack-es-base

Posteriormente, reiniciaremos Apache:

/etc/init.d/apache2 reload

Y le indicaremos a nuestro programa que cargue el idioma con el mismo nombre que lo encontramos en nuestro sistema, es decir, en mi caso:

setlocale( LC_MESSAGES, “es_ES.UTF8” );

Y con esto conseguiremos que nuestro programa quede internacionalizado de manera correcta.

Error SVN Working Copy locked y cleanup

En alguna ocasión me he encontrado con que no puedo hacer update de un proyecto porque SVN indica el error:

Working copy xxxxxxxx locked Please execute “Cleanup” command

Pero cuando lanzao el comando cleanup también devuelve un error:

Cleanup failed to process the following paths: xxxxxx

Con lo que aparentemente, la única solución que queda es hacer un checkout nuevo e intentar no perder los cambios, sin embargo, existe otra solución:

  1. Copia los archivos editados en otra carpeta para evitar perder los cambios
  2. Borra la carpeta que esté causando el problema
  3. Ahora podrás hacer update
  4. Copia los archivos editados en la carpeta (no copies las carpetas enteras porque contienen directorios .svn que volverán a darte problemas)
  5. Por último, haz commit

Espero os sea de utilidad.

Smarty3 y autoload

Smarty Logo

Uno de los errores comunes al implementar Smarty3 es:

Fatal error: Class ‘Smarty_Internal_Wrapper’ not found

Fatal error: Class ‘Smarty_Internal_Register’ not found

Fatal error: Class ‘Smarty_Internal_Template’ not found

Estos se deban, probablemente, a que en tu aplicación estás utilizando la función __autoload también necesaria por Smarty3. La solución a este problema pasa por utilizar la función que PHP nos brinda spl_autoload_register.

En una aplicación, sólo puede existir una llamada a la función __autload, sin embargo, con spl_autoload_register podemos añadir tantos manejadores como queramos y estos se irán ejecutando en el orden en el que los hayamos registrado.

Un ejemplo sencillo de su uso sería:


class AutoloadHandler
{
static public function launch( $classname )
{
print '[['. $name .']]';
}
}

spl_autoload_register( 'AutoloadHandler::launch' );

new ThisClassNotExists();

El resultado de ejecutar este script sería algo así:

[[ThisClassNotExists]]

Fatal error: Class ‘ThisClassNotExists’ not found in …

El cual nos indica que está llamando de manera correcta al autoload, pero al no estar implementado de manera correcta y no existir la clase ‘ThisClassNotExists’ nos devuelve un error.

En definitiva, para solventar el problema, no será necesario que modifiques el código Smarty, pues este ya está utilizando de manera correcta spl_autoload_register, lo que debes hacer es sustituir tu __autoload por una clase con una función ‘launch’ (llámala como quieras) y registrarla mediante:

spl_autoload_register( 'MyAutoloadHandler::launch' );

Smarty3 y gettext

Si estás utilizando Smarty2 y te has decidido a dar el salto a Smarty3 para aprovecharte de sus nuevas funcionalidades (como por ejemplo la nada despreciable opción de herencia en templates), verás que existen algunas incompatibilidades, por ejemplo, se han decidido por seguir el estandar camelCase en el nombre de las funciones, utilizan getters y setters para los atributos o han cambiado la manera de registrar bloques.

En el caso del popular plugin smarty-gettext, si tenemos personalizada la llamada al traductor con, por ejemplo ‘{t}’ como es mi caso, nos encontraremos con un bonito error:

function call ‘register_block’ is unknown or deprecated

Esto es debido a que la forma correcta de registrar bloques en Smarty3 es:


$this->register->block('t', 'translate');

en lugar de:


$this->register_block( 't', 'translate' );

Una vez hecho esto, el siguiente error que nos deja Smarty es:

Plugin “t” not callable

En lugar del antiguo ‘translate’, el segundo parámetro deberá ser el nombre correcto de la función, es decir ‘smarty_translate’:


$this->register->block('t', 'smarty_translate');

de este modo solventaremos el problema y podremos seguir disfrutando de nuestro plugin de traducción.

Symfony: Upgrade de 1.2.x a 1.4 con PEAR

Antes de empezar a hacer el upgrade de symfony debemos asegurarnos que los plugins utilizados actualmente en el proyecto son compatibles con la versión 1.4, en caso de no ser compatibles, tenemos tres opciones:

  1. Buscar un plugin similar que sí sea compatible.
  2. Modificar nuestra aplicación para que no utilice dicho plugin.
  3. Si no podemos prescindir de él, habrá que esperar a que saquen la compatibilidad o hackearlo nosotros mismos (lo qual podría ser muy fácil o muy difícil en función del tipo de problema).

Pasos a seguir para subir de versión:

1) Update de los canales de pear

sudo pear update-channels

2) Upgrade de symfony a la versión 1.3

sudo pear upgrade -f symfony/symfony-1.3.0

3) Validamos que no estamos usando métodos deprecated (estós están eliminados en la versión 1.4)

symfony project:validate

En caso de obtener errores del validador, los solventaremos antes de hacer el upgrade siguiendo instrucciónes en la página Deprecations and removals in 1.3

4) Upgrade del projecto a la versión 1.3

symfony project:upgrade1.3

5) Upgrade de los plugins a la última versión

symfony plugin:upgrade [plugin]

6) Upgrade de symfony a la última versión

sudo pear upgrade symfony/symfony

7) Limpiamos la caché antes de probar

symfony cc

Ahora deberíamos tener nuestro proyecto updateado a la última versión estable de symfony 😀

Symfony i18n con gettext

Symfony permite varios métodos para internazionalizar nuestra aplicación. Por defecto, utilizan el formato XLIFF sin embargo, personalmente me gusta más gettext.

¿Cómo configurar symfony para usar gettext?

Para configurar symfony para que utilice gettext seguiremos los siguientes pasos:

1) Activamos el módulo I18N modificando el archivo settings.yml:

#apps/<appName>/config/settings.yml
all:
  .settings:
    charset:                utf-8
    i18n:                   on
    standard_helpers:       [ [TUS_HELPERS_ACTIVADOS]..., I18N]

2) Abrimos el archivo factories.yml y añadimos la entrada i18n:

#apps/<appName>/config/factories.yml
all:
  i18n:
    class: sfI18N
    param:
      default_culture:  en_US
      source:           gettext</pre>

3) Crearemos una carpeta i18n dentro de apps//:

apps/<appName>/i18n/<lang>

Donde <lang> será el idioma en dos letras (en, es, fr…) y dentro tendremos los ficheros messages.po y messages.mo.

Ahora podemos utilizar la función __( ‘texto_a_traducir’ ) con doble underscore [ _ ] en lugar del simple utilizado normalmente.

¿Cómo generar automáticamente nuestros ficheros po y mo?

Symfony trae una serie de herramientas que nos permiten generar los archivos po y mo de manera automática. Invocando el comando:

symfony i18n:extract frontend en --auto-save

Se recorrerá todos los archivos php de nuestra aplicación (código y templates) y sacará los textos que encuentre en las funciones __().

También se puede utilizar el mismo comando de la siguiente manera:

symfony i18n:extract frontend en --auto-delete

para eliminar las cadenas de texto que ya no existen.

Pasar segundos a horas:minutos:segundos

Una sencilla función que dado un número de segundos, nos devuelve el tiempo en formato hh:mm:ss


protected function makeTimeFromSeconds( $total_seconds )
{
    $horas              = floor ( $total_seconds / 3600 );
    $minutes            = ( ( $total_seconds / 60 ) % 60 );
    $seconds            = ( $total_seconds % 60 );

    $time['horas']      = str_pad( $horas, 2, "0", STR_PAD_LEFT );
    $time['minutes']    = str_pad( $minutes, 2, "0", STR_PAD_LEFT );
    $time['seconds']    = str_pad( $seconds, 2, "0", STR_PAD_LEFT );

    $time               = implode( ':', $time );

    return $time;
}

Espero os sea de utilidad.