Alex Moreno


A Drupal Developer in London

Bases de datos en Symfony2: Doctrine2

Me encanta aprender lenguajes nuevos y tecnologías nuevas a pesar de lo desesperante de algunos momentos en los que te encuentras atascado. Es el caso.

Trabajar con Bases de datos en Symfony2 es sencillo, casi divertido. Si ya tenemos creado el Bundle es tan fácil como lo siguiente (si no lo tenemos creado os recomiendo leer el primer post de este tutorial sobre symfony2, Hola Mundo en Symfony2, una pista: php app/console generate:bundle --namespace=Acme/StoreBundle)

Lo siguiente es asegurarnos de que los datos de configuración de nuestra base de datos son correctos (tipo de base de datos, password, puerto, ...). Si hemos seguido los pasos de instalación correctamente, lo más normal es que ya esté configurada, y el fichero app/config/parameters.ini contiene esos datos.

(i) Normalmente lo primero es crear una base de datos sobre la que podamos trabajar. En Symfony2 no es necesario, el propio framework puede hacerlo por nosotros:

php app/console doctrine:database:create

Ojo con los permisos, en ubuntu probablemente deberemos usar el comando "sudo" antes del comando anterior para poder ejecutarlo con permisos de superusuario.

(ii) Lo siguiente es crear una estructura para nuestra base de datos. Antes de ponernos a picar código es importante diseñar bien la aplicación, independientemente del lenguaje, framework o "bicho" que estemos usando para plasmar nuestros sueños sobre la pantalla.

En Symfony vamos a pensar en Entidades. Una entidad es básicamente una representación de un objeto de nuestra base de datos. Por ejemplo, si tenemos una tienda o un ecommerce, una entidad sería un producto, o un crucero por ejemplo si nos dedicamos al turismo. Así, la entidad sería Producto.php y Crucero.php respectivamente.

Una vez tengamos clara la estructura vamos a crear un directorio nuevo dentro del directorio de nuestra app src/NombredenuestraApp/NombredelBundle/Entity/Objeto.php

Por ejemplo: src/CruiseHunter/CrucerosBundle/Entity/Cruceros.php

El fichero seguirá este formato:

----------------------------------------------

 

<?php

// src/Acme/StoreBundle/Entity/Product.php

namespace CruiseHunter\CrucerosBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**

 * @ORM\Table(name="cruceros")

 * @ORM\Entity

 */

class Crucero

{

    /**

     * @ORM\Id

     * @ORM\Column(type="integer")

     * @ORM\GeneratedValue(strategy="AUTO")

     */

    protected $id;

    /**

     * @ORM\Column(type="string", length=100)

     */

    protected $nombre;

    /**

     * @ORM\Column(type="integer")

     */

    protected $precio;

    /**

     * @ORM\Column(type="string", length=100)

     */

    protected $descripcion;

}

----------------------------------------------

 

Una vez en este punto, quedaría plasmar esta estructura en nuestra base de datos. Pero, un momento, hasta ahora no hemos tenido que tirar del comando mysql ni tan siquiera abrir phpmyadmin... no será esta una excepción:

sudo php app/console doctrine:generate:entities CruiseHunter/CrucerosBundle/Entity/Crucero

Con esto acabamos de crear las Entidades, que se usarán, entre otras cosas, para crear las tablas que vamos a necesitar en la base de datos.

Cuidado con repetir este último comando porque nos dará un error de redeclaración de la clase Crucero (o la que sea en tu caso) y tendremos un problema ( soy un poco manazas, lo se :-( ).

(iii) Bueno, allá vamos:

sudo php app/console doctrine:schema:update --force

y tendremos una respuesta parecida a esto:

 

Updating database schema...

Database schema updated successfully! "1" queries were executed

 

Si todo ha ido bien, ahora tenemos unas bonitas tablas nuevas en nuestra base de datos reflejando esta estructura. Fácil, verdad? :-)

 

Veamos, error clásico, olvidar el <?php del inicio del documento. Resultado? Este:

 

  [RuntimeException]                                                                            

  Namespace "CruiseHunter\CrucerosBundle\Entity\Crucero" does not contain any mapped entities.  

 

Si nos encontramos con este dichoso error no os paséis horas y horas como yo buscando la solución. Lo más obvio, lo que nadie te dice al principio, olvida los config, routing, kernel, etc, etc... Fíjate si has olvidado el puñe***o <?php de declaración de inicio de un fichero php. Ale, de nada :-).

En el siguiente capítulo veremos como acceder a los datos almacenados en la base de datos.

Tutorial de Symfony2: Hola mundo en Symfony

Una vez tenemos instalado Symfony2 en nuestro servidor (algo sencillo como vimos en el capítulo anterior) vamos a comenzar a trabajar.

(i) En primer lugar tenemos que crear un bundle, que básicamente es la semilla de nuestra aplicación, el germen de lo que vamos a construir.

php app/console generate:bundle --namespace=Acme/HelloBundle --format=yml

Básicamente le estamos indicando a Symfony2, crea un Bundle, cuyo formato es yml y al que le vamos a dar el nombre de Hello (HelloBundle en terminología Symfony2) dentro del entorno Acme.

(ii) Vamos a crear el clásico "Hola Mundo" que todo hijo de vecino crea cuando está aprendiendo un nuevo lenguaje de programación. Para ello iremos al fichero /app/config/routing.yml dentro de nuestra aplicación:

 

  • hola:  
  • pattern:  /hola/{name}
  • defaults: { _controller: AcmeHelloBundle:Hello:index }

 

 

Aquí hay que llevar especial cuidado en no meter tabuladores en lugar de espacios, ya que Symfony lo detectará como un error y podemos volvernos locos buscando qué es lo que hemos hecho mal.

Un pequeño truco es usar un default, un valor por defecto para {name}. De esta forma estamos creando también una página para el "root" o directorio raíz:

  • hola:  
  • pattern:  /hola/
  • defaults: { _controller: AcmeHelloBundle:Hello:index , name:Mundo}

 

 

El default es "name:Mundo", separado por una coma.

Si intentamos ahora mismo acceder a nuestro servidor recibiremos un error muy específico y claro: nos falta un controlador.

localhost/DIRECTORIO-SYMFONY2/web/app_dev.php/hola/mundo

 

(iii) Nada más sencillo de solucionar. Creamos un fichero que se llamará, teniendo en cuenta cómo hemos llamado el Bundle, de la siguiente forma:

// src/Acme/HelloBundle/Controller/HelloController.php

namespace Acme\HelloBundle\Controller;

use Symfony\Component\HttpFoundation\Response;

class HelloController{

    public function indexAction($name)    {

       return new Response('<html><body>Hello '.$name.'!</body></html>');  

 }

}

 

Dentro de HelloController.php hay dos declaraciones fundamentales, la clase HelloController, en la linea 4: class HelloController{

y la función indexAction, una línea más abajo. A esta función hemos hecho referencia desde el routing.yml, justamente en la linea que habla del controller:


  • defaults: { _controller: AcmeHelloBundle:Hello:index , name:Mundo}

En realidad le estamos dando la ruta al Bundle, AcmeHello, y al Action que vamos a ejecutar: index. Ambos, Bundle y Action llevarán el postfijo después de su nombre, es decir, AcmeHelloBundle e indexAction. Si por ejemplo el action se llamara NuevoCliente, la función en el controller se llamaría NuevoClienteAction, y haríamos referencia a ella desde el fichero yml (pronunciado "YAMEL") de esta forma:


 

  • defaults: { _controller: AcmeHelloBundle:Hello:NuevoCliente}

 

 

Tutorial de Symfony2: instalacion

1. Descargamos symfony2: http://symfony.com/download

2. Descomprimimos y dejamos en un directorio dentro de nuestro apache, por ejemplo:

/var/www/symfonylabs/

3. Si entramos en /var/www/symfonylabs/web nos dará error. Tenemos que entrar a configurarlo primero: http://localhost/symlabs/web/config.php

Y seguimos los pasos para configurarlo

4. Seguramente no podamos escribir sobre el fichero parameters.ini, con lo que lo abrimos y pegamos el codigo que nos indicará el propio "wizard" o configurador que estamos siguiendo: http://localhost/symlabs/web/app_dev.php/

Listo, ya podemos acceder a nuestra nueva app:

http://localhost/symlabs/cruisehunter/web/app_dev.php/

Fácil, verdad? En el siguiente punto aprenderemos a crear la primera aplicación o librería (llamada Bundle en Symfony2) y a "picar" algo de código.

Recuperar o resetear una contraseña en Drupal 7

Le llaman la navaja suiza del Drupal. Y es verdad que una vez te acostumbras a usarlo no puedes dejar de hacerlo.

Lo mejor de todo es que te puede sacar de un apuro. Os pongo en situación. Drupal7 instalado en local, sendmail no funciona bien, y la password de administrador la he perdido. Mal momento para ponerme a buscar que le pasa al sendmail... solución? En drupal 6 es fácil, vamos a mysql o a phpmyadmin y ejecutamos:

UPDATE users SET pass = MD5('mynewpassword') WHERE uid = 1;

ahora bien, en Drupal7 la cosa no es tan sencilla.

Vamos a instalar Drushhttp://drupal.org/project/drush

muy sencillo, ejecutamos en consola:

  • pear channel-discover pear.drush.org
  • pear install drush/drush

 

Si no tenemos instalado pear, hacemos lo propio:

apt-get install pear-php

y, una vez todo en su sitio, sólo nos queda cambiar la password al usuario que queramos:

drush user-password USUARIO --password="NUEVAPASSWORD"

Obviamente cambiamos USUARIO por el nombre de usuario, y NUEVAPASSWORD por la password que queramos. A partir de aquí podemos volver a loguearnos en nuestra web con las password que acabamos de definir.

Otra opción, más rápida, sería especificar una password con mysql concreta para entrar con el usuario y cambiarla. Por ejemplo "password":

UPDATE users SET pass='$S$Cd059Vsxc8berFeg6hspaa7ejx2bSxyUisvCbT4h9o8XIgSUtPKz' WHERE uid=1;

Visto en: http://chillburn.com.au/blog/changing-resetting-the-admin-password-in-drupal-7/

Programadores vs Usuarios

Un poquito de humor para aguantar lo que queda de semana con una sonrisa ;-).

Visto en http://rafuru.blogspot.com

categorias: 

Actualizar comentarios en drupal desde mysql

Un pequeño truco. En un determinado momento me vi con el problema de varios cientos de nodos en Drupal publicados con los comentarios cerrados.

Solución? Muy sencilla:

 

UPDATE node SET comment = '2' WHERE type = 'tipo_contenido';

(cambiar tipo_contenido por el contenido correspondiente, que además suele coincidir tipo_contenido con el nombre del contenido que hayamos creado en Drupal.

 

categorias: 

Añadir una marca de agua a varias imagenes

El otro día hablábamos sobre redimensionar una o varias imágenes (tantas como tengamos en un directorio o localización, puesto que podemos automatizarlo), y cambiar su calidad para poder subirla a la web.

Hoy vamos a ver un truco para, además, añadir una marca de agua a las imágenes. Además, al tratarse de un proceso automatizado no vamos a perder más que unos segundos, incluso aunque tengamos varios cientos de imágenes por tratar. 

Veamos una primera aproximación:

convert IMG_3476.JPG IMG_3493.JPG -font Helvetica -pointsize 120 -draw "gravity center fill black text 20,12 'http://www.ViajarenCruceros.com' fill white text 11,11 'http://www.ViajarenCruceros.com'" nieuw-amsterdam.jpg

Lo que hacemos aquí es añadir la marca de agua "ViajarenCruceros.com" a la imagen nieuw-amsterdam.jpg.

Ahora vamos a desplazar un poco hacia abajo esa marca de agua:

convert IMG_3476.JPG -font Helvetica -pointsize 120 -draw "gravity center fill black text 120,400 'http://www.ViajarenCruceros.com' fill white text 130,410 'http://www.ViajarenCruceros.com' " nieuw-amsterdam.jpg

Y ahora la centraremos un poco:

convert IMG_3476.JPG  -font Helvetica -pointsize 120 -draw "gravity center rgba(255,0,0,0.80)  'http://www.ViajarenCruceros.com' fill white text 11,11 'http://www.ViajarenCruceros.com' " nieuw-amsterdam.jpg

Y, para terminar, la solución que uso yo:

convert  IMG_3561.JPG -font Helvetica -pointsize 80 -draw "gravity south fill black text 120,400 'www.ViajarenCruceros.com' fill white text 126,404 'www.ViajarenCruceros.com' " nieuw-amsterdam.jpg

Redimensionar varias imagenes con imagemagick

Has hecho un lote de fotos de tus vacaciones, o les has hecho un book a un cliente y quieres subirlo a la web. Si tienes que ir una a una redimensionando cada una de las imágenes te pueden dar las uvas, como se suele decir vulgarmente.

Un pequeño truco es usar imagemagick y mogrify, un pequeño software que puede instalarte en linux y que te permite:

redimensionar varias imágenes a, por ejemplo, un porcentaje concreto:

mogrify -resize 40% *.JPG

En mi caso pasaron de ocupuar unos 1,5MB, demasiado para subirlas a una web, a pesar unos 300kb. Lo bueno de mogrify es que, si intentamos redimensionar en base a un tamaño determinado, mogrify intentará mantener las proporciones originales de la imagen:

mogrify -resize 800x600 *.jpg

Si queremos forzar a que se cambien las dimesiones podemos usar el !:

mogrify -resize 320x240! *.jpg

También podemos modificar la calidad de la imagen, algo típico en jpg:

convert -resize 750×500 -quality 80% *.jpg

categorias: 

Cambiar la configuracion en un vps o servidor dedicado sin reiniciar apache

Este es un pequeño truco que uso a veces cuando hago cambios en alguna configuración de alguno de mis sitios con Drupal. Imaginemos que configuramos un nuevo dominio en drupal, usando multisite para que apunte a un único directorio raiz, por ejemplo:

/var/www/vhosts/dominio.com/directorio-fuente-drupal

El fichero vhost será algo así (en /var/www/vhosts/dominioorigen.com/conf/vhost.conf):

 

        ServerAlias  *.crucerista.org
        ServerAdmin  "[email protected]"
        DocumentRoot /var/www/vhosts/crucerista.net/httpdocs/crucerista/

        <Directory /var/www/vhosts/crucerista.net/httpdocs>
        <IfModule mod_php5.c>
                php_admin_flag engine on
                php_admin_flag safe_mode off
                php_admin_value open_basedir "/var/www/vhosts/crucerista.net/httpdocs:/tmp"
        </IfModule>
                Options +Includes -ExecCGI
        </Directory>
        <Directory /var/www/vhosts/crucerista.net/web_users>
        <IfModule sapi_apache2.c>
                php_admin_flag engine off
        </IfModule>
        <IfModule mod_php5.c>
                php_admin_flag engine off
        </IfModule>
        </Directory>

 

Y aquí viene el truco. Tras añadir el nuevo vhost no necesitamos ejecutar un apache restart, sino que valdrá con este comando:

/usr/local/psa/admin/bin/websrvmng --reconfigure-all

El truco está hecho sobre Drupal 6 y en un dedicado o un vps sobre Debian. Cualquier configuración alternativa de Drupal o distribución linux sería igualmente válida.

De nada ;-)

categorias: 

No puedo hacer login en Drupal después de cambiar de servidor

error tonto donde los haya, pero como todos, si es la primera vez que te ocurre puedes volverte loco hasta encontrarlo.

El problema, después de migrar un drupal funcionando a un servidor nuevo, el login parece no funcionar. Simplemente haces login y no da ningún mensaje adicional, error ni nada parecido, pero no estás "logueado".

Problema? Pues simplemente la variable cookies en settings.php:

$cookie_domain = '.dominio.com';

comentándola con una # al principio de la linea o bien simplemente cambiando el dominio al nuevo dominio debería ser suficiente para que volviera todo a funcinar correctamente :-).

categorias: