12 de febrero de 2025

Luchar

No hay mayor lucha que la lucha contra uno mismo. 

Si pierdes no hay segunda oportunidad.

Y ganar parece tan complicado que en 3 párrafos ya he perdido.



13

13 meses y dos enfermedades. Todo eso te ha costado, y sólo has empezado. ¿Y ahora?

Búscate. No va a ser fácil, pero si no te encuentras tú, ¿quién te va a buscar?

¿Y acaso no es eso lo que buscas?

Ánimo. Sólo has empezado.

27 de marzo de 2024

Madurar

 ¿Cómo podías ser más valiente con 25 que con 38? ¿qué has hecho todo este tiempo? Y lo más importante, ¿cuándo piensas aprender a compartir tus emociones?

He vuelto. Quizás debería volver más a menudo. Es curioso que haya sido un santo el que me ha vuelto a traer a ti. O una santa, no sabría decirlo. Quizás un día vuelva a leer esto y no recuerde nada de ese santo. Y espero poder leer esto un día y haber olvidado lo mucho que necesitaba la calma. 

Porque el primer paso para conseguir (la calma), es olvidarla.

Porque ya va siendo hora de aprender que la vida es un juego... de una sola vida.



14 de agosto de 2016

Loguear consultas de Doctrine

Tan sencillo como:


$this->em->getConnection()
                  ->getConfiguration()
                  ->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());



23 de octubre de 2013

Configurar git para usar https:// en vez de git://

Muy útil para cuando estamos detrás de un proxy o firewall:

git config --global url."https://".insteadOf git://

Visto en: http://stackoverflow.com/questions/16298986/unable-to-connect-to-github-com-for-cloning

11 de febrero de 2013

Symfony: Limitaciones de tipo de campo entity y prefetch de las entidades asociadas

Cualquiera que haya trabajado con Symfony y se haya visto en la necesidad de añadir un campo en un formulario que haga referencia a una entidad se habrá visto en la situación de que la única opción posible es usar el tipo 'entity'. Este tipo tienes dos grandes problemas:

  • Solo permite mostrar el campo mediante checkboxes, radiobuttons o selects, donde todas las opciones posibles se muestran para que el usuario escoja alguna en concreto. Esto dificulta mucho la interacción en casos como el de recuperar una entidad vía AJAX y vincularla al formulario.
  • La eficiencia de lo anterior es nula, porque obliga a recuperar todos los valores posibles de la entidad a la hora de mostrar el campo. Imagina que necesitas un campo usuario y tienes más de 5000 en tu base de datos. Sería inviable usar el tipo entity.
Este es un tema que lleva dando vueltas por los repositorios de Symfony desde hace 2 años. Una solución es la propuesta por el usuario Gregwar en este PR https://github.com/symfony/symfony/pull/1951/, que añade el tipo 'entity_id'. Del ejemplo de la misma página:
$builder->add('city', 'entity_id', array(
            'query_builder' => function($repository, $id) {
                return $repository->createQueryBuilder('c')
                    ->where('c.id = :id AND c.available = 1')
                    ->setParameter('id', $id);
            },  
            'class' => 'Gregwar\TestBundle\Entity\City',
            'required' => false,
            'hidden' => true
        )); 
Con este tipo es posible tener un campo de texto o un campo oculto en el que poder insertar automáticamente el ID de una entidad, olvidándonos de selects, radiobuttons o checkboxes, y sin hacer prefetchs de las entidades. Yo llevo usándolo desde hace 8 meses y me ha resuelto bastantes problemas.

Aunque hay bastantes solicitudes para hacer oficial este PR, parece que finalmente la solución oficial va a ser la de añadir un atributo widget al tipo entity, como se detalla aquí https://github.com/symfony/symfony/issues/6602 :

I think that we should add two new options widget and delimiter to ChoiceType.
  • widget can be one of the values selectcheckboxradio and text
  • delimiter can be any single character
Behavior:
  • widget = 'select': This is equivalent to expanded = false right now.
  • widget = 'checkbox'multiple must not be set to false. Otherwise equivalent to expanded = true.
  • widget = 'radio'multiple must not be set to true. Otherwise equivalent to expanded = true.
  • widget = 'text': A text input is shown.
    • if multiple is false, the input must equal one of the predefined choices.
    • if multiple is true, the input is split by the character defined in delimiter (a comma by default), then each value is trimmed (unless trim is false). Each resulting input must equal one of the predefined choices.

Solución bastante más genérica y limpia, y que incluye el tipo de widget text, que combinado con el atributo multiple soluciona el problema de poder referenciar entidades "manualmente". Lo que no aclara esta solución es si seguirá haciendo prefetch o no de todas las entidades posibles. A día de hoy este debate sigue abierto en Github.

9 de febrero de 2013

Recuperar datos de formularios al volver atrás en el navegador

Dado que cada navegador es un mundo a la hora de enviar un formulario y volver atrás a la página del formulario, que unos conservan los datos del formulario y otros no, que algunos tipos de campos mantienen el estado y otros no, que unos tiran de caché y otros vuelven a solicitar la página... La solución más fiable y más crossbrowser es guardar una cookie en el momento en que se envía el formulario, y hacer una petición AJAX en la página del formulario siempre que dicha cookie esté definida, cookie que recupere los datos del formulario y los vuelque en el formulario.

Ojo, para datos sensibles esta solución puede no ser la más adecuada.

Explicación por extender.

Parámetros de Symfony en variables de entorno

A veces nos interesa que ciertos parámetros de nuestra configuración estén definidos fuera del código de esta. Por ejemplo, los parámetros de conexión de la base de datos. Para estos casos podemos usar variables de entorno. En Apache lo haríamos así:

    DocumentRoot "c:/xampp/htdocs/dev/public_html/web"
    ServerName symfony.localhost
    SetEnv SYMFONY__DATABASE__USER     "usuario"
    SetEnv SYMFONY__DATABASE__PASSWORD "password"
    SetEnv SYMFONY__DATABASE__NAME "name"

En el caso de que usemos Nginx con PHP-CGI sería algo así:

     location ~ .php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  app_dev.php;
        include        fastcgi_params;
        fastcgi_param  SYMFONY__DATABASE__USER usuario;
        fastcgi_param  SYMFONY__DATABASE__NAME name;
        fastcgi_param  SYMFONY__DATABASE__PASSWORD password;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
     }

Y luego los recuperamos en el config.yml:

doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database.name%
        user:     %database.user%
        password: %database.password%

Ojo al uso de . y _ . En este caso database_driver, database_host y database_port siguen definidos en el fichero parameteres.ini.

Hay que tener en cuenta que si lanzamos algún script desde consola, tipo php app/console, no tendrá acceso  a las variables de entorno, generando un error:


[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]

You have requested a non-existent parameter "database.user".


Para que funcione correctamente, hay que definir las variables de entorno, usando SET en Windows, o EXPORT en Linux:

SET SYMFONY__DATABASE__USER=usuarioSET SYMFONY__DATABASE__PASSWORD=password
SET SYMFONY__DATABASE__NAME=name

En Windows también podemos hacerlo en la ventana de variables de entorno, Panel de control -> Sistema -> Configuración avanzada del sistema -> Variables de entorno:



Más info en: http://symfony.com/doc/current/cookbook/configuration/external_parameters.html

8 de febrero de 2013

Ojo a los orders by en MySQL

Aunque MySQL suele ser inteligente, a veces no viene mal ayudarle con los orders. Ejemplo, tabla con muchos municipios, donde queremos obtener unos cuantos haciendo búsqueda por nombre, y luego ordenarlos por capitales y códigos postales ascendentes. La consulta típica sería así:

SELECT m1.id, m1.nombre, m1.codigo_postal, m1.capital
FROM Municipio m1
WHERE m1.nombre LIKE "%Girona%"
ORDER BY m1.capital DESC , m1.codigo_postal ASC

12 total, La consulta tardó 0.5366 seg

Si le echamos una mano a MySQL:

SELECT m2.id AS id, m2.nombre AS nombre, m2.codigo_postal AS codigoPostal, m2.capital
FROM (

SELECT m1.id, m1.nombre, m1.codigo_postal, m1.capital
FROM Municipio m1
WHERE m1.nombre LIKE "%Girona%"
) m2
ORDER BY m2.capital DESC , m2.codigo_postal ASC

12 total, La consulta tardó 0.0886 seg

Parece ser que en algunos casos, como en éste, MySQL tiene a ordenar la tabla antes de realizar la búsqueda, con lo que el resultado es bastante peor.

pd: La prueba está hecha con varios municipios y tras varios reinicios de MySQL. No parece un tema de caché.

7 de febrero de 2013

¿Qué aplicación utiliza un puerto en Windows?

1. En consola:

netstat -noa



2. En el administrador de tareas buscamos el PID: (si el PID no aparece marcarlo en Ver/Seleccionar columnas...)



Actualización: Otra forma más cómoda y rápida como administrador (gracias al comentario anónimo). En consola:

netstat -nba



Mercurial y SSH bajo Windows

Tal que así:

1. Bajar putty, plink, puttygen. Generar clave SSH, guardarla y añadirla al authorized_keys del servidor.

2. Bajar e instalar Mercurial.

3. Configurar %USERPROFILE%/Mercurial.ini:

[ui]
ssh="C:\Putty\Plink.exe" -P XXXX -ssh -i "C:\Putty\key.ppk" 
username=usuario

4. En consola probar:

plink -ssh -i c:\putty\key.ppk usuario@X.X.X.X -P XXXX

5. Si ha ido bien, perfect, si no tenemos algún fallo previamente. Revisar IPs, puerto, key, etc. Aceptar añadir clave a cache.

6. Clonar repositorio:

hg -v clone ssh://usuario@X.X.X.X:XXXX/ruta/al/repo /ruta/local

¡Listo!

2 de enero de 2013

Termina el año de la valoración

Un año después, termina el año de la valoración. 2 entrevistas de trabajo, contratado durante 9 meses y ahora vuelta a empezar. Siempre será mejor que trabajar gratis.

Este año... aun en duda.

27 de noviembre de 2012

Con que poco...

... me haces feliz antes de dormir.

Hace ya tiempo que dejaste huella.






19 de septiembre de 2012

Separar nombre y apellidos en MySQL

No es 100% efectivo dado la cantidad de nombres compuestos, apellidos e historias que hay, pero una solución rápida para dejar la primera palabra como nombre y el resto como apellidos sería:

UPDATE usuario SET nombre = (SELECT LEFT(nombre_apellidos,InStr( nombre_apellidos ,' '))), apellidos = (SELECT RIGHT(nombre_apellidos,(Length( nombre_apellidos ) - InStr( nombre_apellidos ,' '))));

Visto originalmente aquí: http://compgroups.net/comp.databases.mysql/split-full-name-in-to-first-middle-and-l/104981

31 de julio de 2012

remember_me en security.yml (Symfony 2.0)

Después de muchas peleas con el security.yml de Symfony 2.0 para habilitar la función remember_me, esta es la versión definitiva:

frontend: 
    ... 
    remember_me: 
         key: "una_key_cualquiera" 
         lifetime: 604800 
         remember_me_parameter: _remember_me 
         path: / 
         domain: 

Muy importante dejar el dominio en blanco para no tener problemas si estamos haciendo pruebas en varios servidores, no poner rutas con símbolos comodín o similar en el path, y no poner comentarios o usar ~ a continuación de los valores. Al menos a mi estos factores me causaban problemas porque no se parsea de ningún modo los valores antes de introducirlos en la cookie que se envía el usuario, por lo cual el navegador puede recibir la cookie y no tragársela.

pd: esto es un inciso solo.

2 de enero de 2012

Bienvenido 2012

Termina el año de la congruencia. Comienza el año de la valoración.

pd: El balance, más adelante.

17 de diciembre de 2011

Casual-idades

Él.
Sin una llamada no habría venido a verme.
Sin verme, no la habría acompañado a casa.
Sin acompañarla, no habría buscado un autobús para volver.
Sin ser su acompañante por teléfono, no habría acabado ahí.

Ella.
(...)
Si no hubiera acompañado a su amiga, no habría acabado ahí.

Ellos.
Sin una causa conjunta, no habrían entablado una conversación. Si el autobús hubiera seguido su rumbo no se habrían conocido. Sin conocerse, habría sido una noche más.

Denada por una conversación agradable. Ahora te toca rellenar tu parte.

El ya sabía escribir su nombre. Casualidades.

24 de octubre de 2011

Pequeño apunte sobre Grecia

Hace cerca de año y medio saltaba a la red un vídeo de un europarlamentario francés por el partido de Los Verdes, llamado Daniel Cohn-Bendit, donde criticaba con mucha dureza las reformas que se le estaban exigiendo a Grecia. También criticaba la hipocresía de la venta de armamento militar (minuto 4:50) por parte de Francia y Alemania. La reflexión, en sus propias palabras, era la siguiente: "Les estamos prestando dinero para que nos compren armamento". En su comparecencia también pone en entredicho el tamaño del ejercito de Grecia. Según GlobalFirePower, Grecia tiene 177600 militares activos con una población de 11 millones de personas, mientras que, p.ej., España, tiene 177000 con una población de 47 millones. Si comparamos nuestro arsenal militar con el de ellos, también quedamos por detrás en muchos aspectos.

Daniel Cohn-Bendit, eurodiputado francés, hablando sobre Grecia

¿Y a que viene todo esto? Fácil, un año y medio después de este vídeo, y tal como esta la situación en Grecia, surge la noticia de la compra de 400 tanques a Estados Unidos por valor de 1280 millones de euros según La Razón.

Cuanto menos es para hacerse preguntas. Tanto oír hablar de rescates, de recortes, de manifestaciones... ¿para luego leer que compran 400 tanques? Definitivamente, el mundo está loco.

9 de octubre de 2011

Volando en círculos

- Aun no podemos volar juntos.
- ¿Por qué?
- Debes aprender a volar en linea recta.

No existen lineas rectas. Incluso el horizonte es un círculo.

Todos queremos volar. Pero nadie vuela igual. Las variables son tantas como profundo sea el análisis. Y en cualquier caso, dos vuelos exactamente iguales tienen muchas posibilidades de acabar en accidente. Tampoco se vuela igual a lo largo de la vida. A día de hoy, si pudiera escoger, escogería volar a la misma velocidad, en círculos pequeños que entrecruzan sus caminos constantemente a diferente altura. Si me preguntas mañana, no sabría responder, aunque quizás ya haya escogido.

Tan importante es volar como respetar el vuelo de los demás. No puedes forzar a que alguien vuele como tu si no lleváis el mismo avión y la misma cantidad de combustible.

Suerte en tu vuelo. Quizás a tu regreso ya vuele en linea recta.

5 de octubre de 2011

El sistema electoral aplicado a Granada

Me he decidido a hacer este post porque creo que mucha gente no entiende aun cómo va el sistema electoral y como afecta en particular a Granada. Como creo que está más que explicado en Internet, el que aun no sepa como va debe entender que en España se aplica el sistema D'Hondt, que las circunscripciones son las provincias y el porcentaje de exclusión es del 3%.

Dicho esto, en el caso concreto de Granada tenemos que, de cara al congreso, al votar en Granada tu voto afectará solo a los 7 diputados que por población le corresponden a Granada. Para entender esto mejor, es bueno hacer un poco de historia.

En las 3 últimas elecciones generales al congreso (2008, 2004 y 2000), el resultado en Granada ha sido idéntico, 4 diputados para PSOE y 3 diputados para PP. Para obtener un resultado diferente hay que remontarse a 1996, cuando IU consiguió robarle un diputado al PSOE. La Tabla 1 refleja estos datos:

Tabla 1 - Resultados al congreso por Granada 1996-2004

Si nunca antes habías observado estos datos te preguntarás, ¿qué pasa, p.ej., con los 35000 votos de IU en el 2000? ¿A dónde van? La respuesta es muy sencilla: a la basura. Quizás te parezca lógico, pues el resto de partidos tienen bastante más porcentaje. Pero, ¿y si en Granada hubiera más de 7 diputados? Vamos a fijarnos ahora en la Tabla 2, que muestra la tabla D'Hondt de los resultados de 2008:

Tabla 2 - Tabla D'Hondt de elecciones al congreso de Granada en 2008, usando 7 diputados

En esta tabla se ve como el PSOE obtiene 4 diputados y el PP 3. Ahora bien, ¿qué pasaría si en Granada se escogieran 18 diputados? El resultado sería el de la Tabla 3:

Tabla 3 - Resultados al congreso por Granada suponiendo 18 diputados en vez de 7

Con 18 diputados, IU hubiera obtenido un diputado por Granada. Pero claro, no vamos a tener 18 diputados por provincia. La solución a este problema pasaría por hacer más grandes las circunscripciones. Si usáramos Andalucía como circunscripción, que en total suma 55 diputados, el resultado con estos mismos porcentajes sería de 29 diputados para PSOE, 24 para PP y 2 para IU. Y a medida que aumenta la circunscripción disminuye el bipartidismo, pero claro, esto no le interesa a los grandes partidos, que precisamente son los que tienen en su mano el poder cambiar la ley electoral.

Dicho todo esto, a modo de curiosidad, si el próximo 20N se repitieran en las elecciones al congreso de los diputados los mismos resultados que en las municipales del 22M, el resultado sería el que se muestra en la Tabla 4:

Tabla 4 - Resultados al congreso por Granada utilizando resultados de las municipales

No me he olvidado de UPyD, que obtuvo representación en el ayuntamiento. Simplemente sus 10000 votos en toda la provincia no le darían para superar el listón del 3% de votos totales. No obstante esta tabla es totalmente especulativa, pues UPyD no se presentaba en todos los municipios de la provincia y ni que decir tiene que los votos a partidos locales en las municipales acaban en los partidos grandes en las generales. En cualquier caso, con estos resultados IU volvería a tener un diputado por apenas 395 votos.

Como conclusión, y aunque el voto es libre, diré que no acabo de entender a la gente que vota a partidos cuyas opciones de obtener representación en el congreso son nulas. Hacen falta casi 50000 votos para obtener un representante de un partido en la provincia, y francamente no me imagino, p.ej., a 50000 votantes de PACMA (por muy loable que sea su programa). Si estás cansado de lo mismo explora que posibilidades tienen otros partidos en tu provincia, a veces el obtener o no representación depende de apenas unos votos. Y si lo que te frustra es simplemente este sistema electoral bipartidista sal a manifestarte con Democracia Real Ya, pues uno de sus principales puntos estaba relacionado con el bipartidismo.

Pd: Para hacer cálculos con el Sistema D'Hondt he usado la calculadora de http://www.portalelectoral.es/