fabricawebs
Blog donde podrás encontrar el árticulo o tutorial que estas buscando sobre PHP, JavaScript, XML, Flash, Ruby on Rails, o desarrollo web en general.

Apache enable rewritemap

By Carlos
Menudo quebradero de cabeza con la directiva RewiteMap de Apache. La estaba utilizando para unificar urls que respondían el mismo contenido tanto si la url estaba en mayúsculas como en minúsculas, estas urls habían comenzado a aparecer como páginas con el title duplicado en Webmasters tools y evidentemente yo solo deseo tener una url para cada contenido.

De este modo, por ejemplo la url /nombres-Africanos debe redirigir con un 301 a /nombres-africanos .

Para ello en el http.conf debemos crear una función que convierte texto a minúsculas, y esta función la podemos usar en directivas RewriteCond y RewriteRule.

RewriteMap lc int:tolower

Esta directiva debe incluirse a nivel de servidor en el httd.conf o en una sección Virtualhost, nunca en un .htaccess ni dentro de una sección Directory . Hasta aqui todo bien, pero a mi seguía sin funcionarme la declaración de la función "lc", después de muchas pruebas dí con el problema, había puesto la directiva RewriteMap en http.conf pero antes de la directiva RewriteEngine On , por lo que no tenía ningún efecto, así que ojo con esto.

Otro tema a tener en cuenta es que en la RewriteRule o RewriteCond tengas cuidado en esquivar los nombres de images o ficheros en general que pueden tener mayusculas en su url y que por tanto no queremos que sean redirigidos a la url en minusculas.
 

Agencia de protección de datos "El certificado SSL del servidor no es válido"

By Carlos
Para tener registradas legalmente tus bases de datos de clientes, usuarios o cualquiera que incluya datos personales, la agencia de protección de datos te permite inscribir el fichero por internet.

El gran problema es que como el certificado raiz de la FNMT no está en los listados de autoridades de confianza de ningún programa (Acrobat, Firefox, IE, ...) , a menudo hacer cualquier tramite se convierte en algo complicado.

Al enviar el formulario NOTA, si no tienes ya instalado el certificado de la FNMT te saldrá el mensaje de error "El certificado SSL del servidor no es válido."

Cuando rellenas el formulario NOTA directamente en el plugin Acrobat del navegador y te devuelve este error, la solución la encuentras en la propia FAQ de la agpd.es , se trata de configurar el navegador para que acepte la revocación del certificado del servidor, más información en este pdf

En cambio si has descargado el pdf, para rellenarlo y enviarlo directamente desde Acrobat, te devuelve el mismo error, pero nadie te cuenta como solucionarlo. Después de perder un buen rato he conseguido enviarlo con éxito, para ello solo hay que agregar el certificado raiz de la FNMT en Acrobat Reader, pero esto que suena tan fácil es algo que no es nada obvio de configurar, la guía paso a paso la podéis encontrar aquí.

 

Symfony 2.1 Expected argument of type "object, array or empty", "string" given

By Carlos
Ayer actualicé mi Symfony 2.1.x y algunos de los formularios empezaron a  fallar, al final dí con el problema: los custom types.

En la actualización de Julio de 2012 se han modificado unas cuantas cosas, puedes verlas todas aqui https://github.com/symfony/symfony/blob/master/UPGRADE-2.1.md , en mi caso solo tuve que actualizar lo siguiente:

ANTES:


namespace Fourcats\AdminBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ImageType extends AbstractType
{
    public function getDefaultOptions()
    {
        return array(
            // cannot have a required attribute
            'required'       => false,
            // Pass errors to the parent
            'error_bubbling' => true,
            'class'          => 'uploader'

        );
    }

    public function getParent()
    {
        return 'field';
    }

    public function getName()
    {
        return 'image';
    }
}



DESPÚES


namespace Fourcats\AdminBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ImageType extends AbstractType
{


    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'compound' => false,
            // cannot have a required attribute
            'required'       => false,
            // Pass errors to the parent
            'error_bubbling' => true,
            'class'          => 'uploader'

        )
        );
    }

    public function getParent()
    {
        return 'form';
    }

    public function getName()
    {
        return 'image';
    }
}


La clase FieldType fue deprecated ahora debe usarse siempre FormType, por eso debe cambiarse en el método GetParent, por otra parte el método getDefaultOptions también fue deprecated ahora hay que usar setDefaultOptions, y recuerda incluir con use la clase OptionsResolverInterface.
 

Codemotion 2012

By Carlos


Tenía algunas dudas sobre que iba a sacar de las charlas que había anunciadas en el Codemotion pero la verdad es que ha sido un dia muy productivo.



Me han gustado bastante las charlas de Diego Muñoz y Carlos Sanchez sobre el "Workflow Release de Tuenti" y  "Dev to DevOps",  del primero me quedo con ideas muy buenas que no conocía y en las que tengo que profundizar, como el "dark launch",  subir una funcionalidad a producción para ver su rendimiento pero sin que los usuarios las puedan ver, u otras como lanzar nuevas funcionalidades solo con un grupo reducido de usuarios para ver su reacción o enviar distintos formatos de newsletters a distintos usuarios para ver cual es más eficaz, también algún truco sencillo como hacer php -l en los pre-commit para evitar puntos y coma olvidados y otros errores de sintaxis. La charla sobre DevOps me ha dejado claro el funcionamiento de algunas herramientas como Puppet o Vagrant, de las que ya había escuchado algo pero no sabía exactamente como funcionaban.



Después del descanso he asistido a un par de charlas sobre aplicaciones móviles, la primera de nscode "Cliente twitter en 45 mins" por Fernando Tapia, que explicó por encima el uso del storyboard y el manejo de xCode, todo parecía bastante sencillo, al menos para empezar a trastear. Luego ha venido la que para mi ha sido la charla estrella de la conferencia "Monetización de aplicaciones móviles" de Curro Rueda, resumir todo lo que ha contado se me hace imposible pero para que os hagais una idea he rellenado unas 20 páginas de la agenda de notas con trucos, cifras y consejos que solo se aprenden con la experiencia, dándote muchos palos, y que Curro generosamente ha compartido con nosotros.

El dia fue soleado así que la gente se animó a comer en el jardín de la universidad, allí vi muchas caras conocidas de otras conferencias: Symfony Live París, PhpBarcelona, deSymfony y el grupo de Symfony Madrid.



A la hora de la siesta nada mejor que una charlita de WebRTC, de la mano de Javier Cerviño. WebRTC es un estándar para transmisión de datos en tiempo real entre clientes, sin necesidad de pasar por el servidor, Javier explicó como se podrá usar este estándar para videoconferencias pero es una pena porque está tecnología de momento solo esta implementada a medias en algunas betas de navegadores y tardará unos años en poder usarse en el mercado. Luego tocó Tomás Corral con "Automatización de Unit Testing en Javascript", la charla fue muy reveladora, muchas herramientas nuevas que investigar, aunque la verdad me costó bastante seguirla pues la programación Js que utilizó habitualmente es infinitamente más sencilla que todo el entorno que presento Tomás.


Coffe break y las dos últimas charlas: "Symfony2 y su ecosistema" por Javier Aceituno, que fue añadiendo los componentes de Symfony2 y compañía en el código de una aplicación php plain, mostrando como y porque usar cada uno, fue bastante curioso ver todas las piezas de Symfony2 desmontadas pues uno usualmente lo usa todo junto por costumbre. La conferencia la terminé con "Construyendo un ecosistema para programadores" de David Bonilla, la sala estaba abarrotada fue digno de ver, en cuanto a la charla nos habló de las diferencias entre una aplicación y una plataforma, que se podría resumir en plataforma= aplicación + permitir que terceros hagan plugins y ofrecerlos directamente dentro de la aplicación. Empezó bastante bien, aunque en algunos puntos se repetía bastante, y para mi gusto hubiera hecho mejor en hacer caso a los de marketing de Atlassian y no debería haber comparado tanto los propios productos de Atlassian con los de otras compañías, para decir siempre lo bien que lo hacen en su empresa y lo malos que son el resto. Aún así la charla en general estuvo bien.



 

Ideup SimplePaginator con urls friendly

By Carlos
Estaba utilizando este bundle tan útil para paginar los listados en un nuevo proyecto y me encontre con el problema de que añadía el parámetro de la página actual por GET, dejando mis urls friendlys así www.friendly.loc/amigos/europa?page=1 . Esto no me molaba nada porque las urls las quería en el formato  www.friendly.loc/amigos/europa/1 y este paginador es muy comodo así que quería seguir usandolo.

La solución fue rapidísima, resulta que ya está preparado para funcionar con urls friendly, solo hay que añadir un parametro opcional "page" en tus rutas:


DirectoryBundle_friends_continent:
    pattern:  /amigos/{continentSlug}/{page}
    defaults: { _controller: DirectoryBundle:Default:listContinent, page:1 }
    requirements:
        page:  \d+



Una pena que no lo ponga en sus instrucciones de uso, porque antes de dar con esto perdí un rato revisando el código del bundle para ver como tendría que modificarlo.
 

Sopa fácil y barata con Python

Category: By Carlos
Llevo unos días leyendo el manual de Python y mira por donde hoy me ha surgido la oportunidad de usarlo en un caso real. Necesitaba extraer los textos de unas plantillas html y guardarlos en un fichero para posteriores operaciones. La solución que he encontrado es realmente simple, utilizando la librería Beautiful Soup de parseo de HTML/XML :

from BeautifulSoup import BeautifulSoup

import sys
if len(sys.argv) >= 2:
f = open(sys.argv[1])
freturn = open("striptag_result", "w")
soup = BeautifulSoup(f.read())
freturn.write( ''.join([e for e in soup.recursiveChildGenerator() if isinstance(e,unicode)]).encode('utf-8')
)
freturn.close()
else:
print "Uso: striptags.py fichero"
 

Crear un source en Sphinx

Category: By Carlos
Cuando el source es de tipo sql hay un elemento muy importante, el "Document ID", este se nombra en muchas partes de la documentación, y queda bastante claro que es el identificador único que utilizará Sphinx para distinguir las tuplas de datos, a base de ensayo y error averigüe que Sphinx toma como Document ID el primer campo que devuelves en la consulta sql, pero el caso es que me costó un buen rato encontrar en la documentación un parrafo donde explicara esto y lo definiera, por fin lo encontré y por eso lo quiero dejar por aqui:

"There can be only one main query. This is the query which is used to retrieve documents from SQL server. You can specify up to 32 full-text fields (formally, upto SPH_MAX_FIELDS from sphinx.h), and an arbitrary amount of attributes. All of the columns that are neither document ID (the first one) nor attributes will be full-text indexed.

Document ID MUST be the very first field, and it MUST BE UNIQUE UNSIGNED POSITIVE (NON-ZERO, NON-NEGATIVE) INTEGER NUMBER. It can be either 32-bit or 64-bit, depending on how you built Sphinx; by default it builds with 32-bit IDs support but --enable-id64 option to configure allows to build with 64-bit document and word IDs support. "

http://www.sphinxsearch.com/docs/current.html#conf-sql-query