Blogs

Cambiar de usuario en Drupal

Cuando estás programando una aplicación surgen fallos, errores y un montón de warnings e incidencias que en ocasiones los usuarios, o no son capaces de darnos toda la información, o simplemente necesitamos acceder con su usuario para recopilar más información.

Muy sencillo, sin tener que cambiar su password ni "violar" su cuenta, podemos usar el siguiente truco via "coding":

http://drupal.org/node/218104

o bien, más sencillo aún quizá, usar uno de estos módulos:

Crear una web social

Hay un montón de herramientas tipo CMS (gestores de contenido) que te permiten crear una red social con unos simples pasos. Sin embargo, cualquier solución que busques siempre va a tener unas u otras limitaciones, ya sea por licencias, aspecto, posibilidades de ampliación, etc...

La opción que más flexibilidad y posibilidades de ampliación a futuro nos asegura son, o bien usar un framework tipo Symfony, CakePHP o Ruby on Rails, por poner unos ejemplos. Si el presupuesto es reducido (siempre lo es) no vamos a poder partir de cero, con lo que la opción recomendada sería usar Drupal. No vamos a perder nada de flexibilidad, tendremos una web social lista en a penas unas jornadas de trabajo y con suficientes conocimientos de programación no tendremos ningún problema a la hora de añadir y/o ampliar casi cualquier característica que se nos ocurra.

Aquí tenemos un listado de módulos que podemos usar para partir de una base:

http://drupal.org/node/206724

y aquí una comparativa entre dos módulos imprescindibles para toda red social, User Relationships y Friendlist:

http://groups.drupal.org/node/14625

Ahora bien, como con cualquier CMS, simplemente instalando unos cuantos módulos no va a ser suficiente para tener un proyecto medianamente complejo que satisfaga el 100% de nuestras necesidades y/o requerimientos.

Aquí es donde entra en juego nuestra pequeña navaja suiza que es la programación en Drupal.

Durante las próximas semanas entraremos en detalle en cómo podemos elevar al 200% la potencia de Drupal aplicada al desarrollo y programación de redes sociales, incluso aplicaremos algunos ejemplos reales, sacados de casos concretos de clientes para los que hemos desarrollado redes sociales o incluso para proyectos propios de redes sociales.

Estás interesado en crear una red social? Tenemos experiencia en la creación de redes y webs sociales en Drupal, en sectores tan distintos como las bodas (mundo nupcial), los viajes o el deporte. Si estás interesado no dudes en contactar con nosotros, seguro que podemos encontrar la solución social que buscas al coste óptimo que estás buscando.

Reordenar un array con indices desordenados en php (drupal)

En Drupal es muy muy normal obtener algunas consultas de arrays de este tipo:

Array ( [1320] => stdClass Object ( [tid] => 1320 [vid] => 14 [name] => que ver [description] => [weight] => 0 [language] => [trid] => 0 ) [109] => stdClass Object ( [tid] => 109 [vid] => 5 [name] => Corfu [description] => [weight] => 0 [language] => [trid] => 0 ) ) corfu/que-ver-en-corfu/museo-arqueologicos-de-corfu

Fijaos el problema. La consulta con print_r de php ha devuelto un array de dos dimensiones o más... pero sus indices están desordenados. El primer elemento es el 1320, el segundo el 109, y así sucesivamente... En otra consulta a otro elemento los índices no tendrían necesariamente estos indices, con lo que no nos vale usar siempre el mismo número como seguro que ya estábais pensando ;-).

Este tipo de arrays se ven mucho en las taxonomias de drupal, donde el indice ha heredado el indice que la taxonomia tiene en su vocabulario correspondiente.

Bueno, el caso es que la solución es muy sencilla usando array_slice, fijaos:

$output = array_slice($nodocrucero->taxonomy, 0, 2);

$tid = $output[0]->tid;

donde tid, o mas bien print_r($tid); nos devolvería lo siguiente:

Array ( [0] => stdClass Object ( [tid] => 1320 [vid] => 14 [name] => que ver [description] => [weight] => 0 [language] => [trid] => 0 ) [1] => stdClass Object ( [tid] => 109 [vid] => 5 [name] => Corfu [description] => [weight] => 0 [language] => [trid] => 0 ) )

Fijaos, es el mismo array, pero ahora vemos claramente como el indice empieza en 0 y lista el resto de elementos sin ningún problema.

En la orden array_slice hemos pasado 0,2 como argumentos porque sabíamos que tenía únicamente dos elementos y queríamos que comenzara a contarlo en 0, pero podríamos usar indices distintos, mayor que 2 por ejemplo si tenemos arrays de mayor tamaño (el que sea, sin problemas).

 

Prueba tu diseño en varios navegadores

Para futuras referencias:

http://browsershots.org/

En general es un infierno tener una web lista y tener que ir uno a uno visualizando en todos los navegadores posibles que se vea todo bien.

No deja de ser una lata, pero al menos con esta herramienta tenemos de un plumazo todas las páginas en pantalla y en el mismo ordenador.

categorias: 

Comparar y buscar perfiles de usuarios en Drupal

Drupal tiene varios módulos bastante buenos que permiten crear perfiles de usuarios a base de crear nodos (o contenidos) y asociarlos a tu perfil.

El módulo que se suele usar para esto en Drupal 6 en Content Profile, aunque en Drupal 7 ha cambiado un poco la cosa, es algo más compleja a primera vista, pero en general los cambios son a mejor mediante el uso de "Entities" y el módulo Profile2.

Puedes montarte, por poner un ejemplo inocente, una red social en la que los usuarios tienen su propio muro, información de su perfil, gustos, viajes hechos, el vino que les gusta, fecha de nacimento, ... lo que se os ocurra.

Genial, verdad? Ahora imaginaros que en esa red social "imaginaria" vamos a querer cruzar datos para, "por ejemplo", buscar amigos. Muy útil en una red social, verdad? Verdad que sería interesante no sólo mostrar usuarios sin más, sino mostrar únicamente aquellos usuarios que tengan coincidencias con tu perfil?

Con Drupal y el módulo views pueden hacerse maravillas sin tener que tocar una sólo linea de mysql y/o php... ahora bien, si queremos hacer algo más complejo, como lo es precisamente el cruzar datos de un perfil y encontrar coincidencias en otro... Drupal es fantástico pero no hace magia... todavía ;-).

Bien, solución? Muy "simple", expresiones regulares + mysql + tipos de contenido. Las expresiones regulares son algo así como la navaja suiza del programador, no entiendes su potencia hasta que realmente no te pones a trabajar con ellas.

La opción de usar un tipo de contenido es porque podemos crear un nodo específico para cada usuario en el que metamos un código php específico para ese tipo de nodos, y con rules, por ejemplo, hagamos que cuando un usuario se registra en la red ese nodo se crea automáticamente.

El contenido de dicho nodo como decía lo dirigiremos desde el node-TIPODECONTENIDO.tpl.php. La magia está simplemente en cargar desde la plantilla los datos del usuario "owner" usando el campo $node->uid). Con esos datos haremos ahora consultas sobre sobre los campos "nodeprofile" que pertenecen a dicho usuario, almacenamos los datos que nos interesen en un campo de texto, y lanzamos una consulta contra todos los usuarios obteniendo los mismos datos, pero de cada usuario.

Con esos datos en variables distintas "sólo" queda jugar con expresiones regulares, e ir almacenando, por ejemplo en un Array, los usuarios cuya coincidencia sea la que estamos buscando.

La coincidencia de la que os hablo puede ser exacta, lo que en la mayoría de los casos no tiene sentido, o "parcial". Ahora queda jugar con expresiones regulares en php para encontrar esa "coincidencia parcial" en los perfiles de usuario.

Usar de esta forma los tipos de contenido y los templates .tpl.php de Drupal es probablemente una aberración, pero es una solución rápida sin necesidad de tener que programar un módulo, cosa que por otra parte es muy sencillo.

Mucha teoría, verdad? Los próximos días pondré algún ejemplo en forma de código... y si habéis sido buenos probablemente en forma de módulo :-).

 

migrar contenido de drupal a drupal con mysql y phpmyadmin

Atención: lo siguiente es una administración de Drupal de guerrilla. No os recomiendo llevarla a cabo a menos que realmente sepáis que lo necesitáis y sabéis lo que estáis haciendo. Igualmente, un backup antes de poneros en harina es altamente aconsejable. Si pierdes datos o la base de datos entera no me hago responsable de las consecuencias, lo que vas a leer a continuación es sólo apto para no cardíacos, y por tanto si sigues alguna de mis indicaciones lo haces por tu cuenta y riesgo :-).

Caso expuesto: migrar contenido de un drupal a otro, siendo el segundo un Drupal en marcha (más de 6.000 nodos y unos 1.000 usuarios) y el primero con unos 600 nodos y otros 500 usuarios aprox.

Primer paso, backup:

  • mysqldump --opt -uUSER -pPASS BBDDaMigrar  > BBDDaMigrar-BACKUP.sql
  • mysqldump --opt -uUSER -pPASS BBDDaMigrar  > BBDDaRecibirMigracion-BACKUP.sql

 

Segundo paso, migrar los nodos (del Drupal a migrar, se entiende):

  • CREATE TABLE node2 LIKE  node; #creamos una tabla sobre la que jugar
  • INSERT node2 SELECT * FROM node;

 

Repetimos con node_revisions:

  • CREATE TABLE node_revisions2 LIKE node_revisions;
  • INSERT node_revisions2 SELECT * FROM node_revisions;
  •  

Y con los tipos de contenido que tengamos a medida:


    • CREATE TABLE content_type_empresa2 LIKE content_type_empresa;
    • INSERT content_type_empresa2 SELECT * FROM content_type_empresa;

 

La tabla node_type no contiene nid ni datos de este tipo que tengamos que adaptar, solo una descripción por nombre del tipo de contenidos. Por lo tanto, no hace falta migrarla, simplemente nos aseguramos de que existe el tipo de contenido en la base de datos o el Drupal que va a recibir los nodos (page, blog, ... los estándar y cualquier tipo nuevo que hayamos creado nosotros o el admin del sitio).

Ahora volcamos estas tablas en el Drupal que vaya a recibir los datos:

primero, backup de las tablas:

  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen node_revisions2 > node_revisions2.sql
  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen node2 > node2.sql
  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen node_revisions2 > node_revisions2.sql

 

segundo, volcamos el backup en el Drupal receptor.

  • mysql -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDDestino < node_revisions2.sql
  • mysql -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDDestino < node2.sql

Ahora tenemos los nodos en la base de datos final. Sin embargo los datos nuevos tienen ids que coincidirán con los que ya existan en Drupal (en el receptor, se entiende). Solución? Contar los nodos que ya existen y sumar ese número al nid de los nodos que hemos traido a la base de datos. Por ejemplo, en mi caso teníamos unos 6000 y pico nodos. El nid nuevo será 7.000 + nid.

No nos preocupamos por nada más ya que Drupal se encargará de asignar a los nuevos nodos los ids correctos, teniendo en cuenta los nuevos nodos que han aparecido en la base de datos.

Vamos allá:

  • UPDATE  `node2` SET  `nid` = `nid` + '7000';
  • UPDATE  `node_revisions2` SET  `vid` = `vid` + '7000';
    UPDATE  `node2` SET  `uid` = `uid` + '500'  ;

    • UPDATE  `node_revisions2` SET  `nid` = `nid` + '7000'  ;

      

idem con content_..._empresa, o los tipos de contenido que tengamos "a medida":

  • UPDATE  `content_type_empresa` SET  `nid` = `nid` + '7000';
  • UPDATE  `content_type_empresa` SET  `vid` = `vid` + '7000';
  • UPDATE  `content_type_empresa` SET  `uid` = `uid` + '500'  ;

 

cuidado con esto último. El nodo pertenece a un usuario de la BBDD anterior, con lo que también hay que, tanto en node, noderevisions y content, modificar el nuevo usuario.

Bien, en este punto ya estamos listos para volcar estas tablas en su sitio definitivo...o más bien para concatenar las tablas que ya tenemos con estas nuevas.

Primero, una vez más, backup de lo que tengamos:

 

  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen node_revisions > node_revisions.sql
  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen node > node.sql

 

Segundo, pasamos concatenamos los nuevos nodos, que es justamente el proceso inverso con el que empezamos todo este "lio":

 

    • INSERT node SELECT * FROM node2;
    • INSERT node_revisions SELECT * FROM node_revisions2;
    • INSERT content_type_X SELECT * FROM content_type_X2;

 

 

Y, si no ha habido ninguna incidencia, tenemos una bonita base de datos con el número de nodos total justamente igual a la suma de los nodos de ambas webs en Drupal, ni más ni menos, y con id's que son:

para la base de datos "receptora", los nid son los mismo,

para la base de datos que "aluniza" en esta base de datos, el nid que tuviera antes más la constante que hayamos elegido como precaución (en nuestro caso 7.000).

En otro post tocaremos el tema de las taxonomías, y cómo podemos migrarlas sin que se produzcan colisiones a la vez que los posts no pierdan sus respectivas clasificaciones.

Importar / Exportar de Drupal a Drupal usando SQL

En drupal hay un montón de módulos para realizar migraciones, como migrate, user_import, node_import... o incluso el fantástico Feeds, que te permite partir de casi cualquier fuente, como xml, cvs,... y fuentes tan difersas urls, ficheros, ...

Ahora bien, a veces es más sencillo, sabiendo un poco de sql y organizandose uno mismo la migración, hacerlo directamente a mano. Es el caso de una migración, una importación más bien de usuarios de un Drupal a otro. No me preguntéis como me he metido en tal lio, pero a veces pasa... "shit happens" decía un amigo.

Y, como decía otro amigo... que demonios, los hombres de verdad programan en C a "pelo" y con vi sin plugins ni mari*** de esas :-).

Vamos allá:

i) Pasar tablas:

  • CREATE TABLE users2 LIKE users;
  • INSERT users2 SELECT * FROM users;

 

Actualizamos el uid para que no "choque" con el de la base de datos en la que vamos a volcarlo:

  • UPDATE  `users2` SET  `uid` = `uid` + '500'  ;

 

Esto suma 500 a todos los uid que existan (no hay where ni limit, con lo que la consulta se hace para todas las tablas y no se pone limitación.

En mi caso el número de usuarios era de 400 y pico, casi 500. En vuestra tabla tendréis que comprobar el último uid y cambiar la cifra. Da igual cuál usemos puesto que Drupal usa autoincrement, con lo que mientras no solapemos uids, drupal "cazará" la última que exista (1000 y pico en mi caso) y continuará trabajando desde ahí.

Ahora hacemos backup SOLO de la tabla: 

  • mysqldump -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDOrigen users2 > users2.sql

 

y nos la llevamos a la otra base de datos

 

  • mysql -uUSUARIOMYSQL -pPASSMYSQL nombreBBDDDestino < users2.sql

 

Excelente. Ya tenemos la base de datos con las dos tablas juntas (origen y destino) y con los uids incrementados de forma que no se solapen entre ellos. No habría problema si no lo hemos hecho bien porque al hacer el import mysql se "quejaría" de que ya existe un dato con ese uid (que debe ser único).

Ahora hacemos justo lo contrario de lo que habíamos hecho al inicio:

 

  • INSERT users SELECT * FROM users2;

 

con lo que la nueva tabla pasará a la tabla users... y drupal ni se habrá dado cuenta :-).

 

Huelga decir que este procedimiento puede aplicarse a cualquier tabla, por ejemplo a la tabla node, donde residen los nodos, la tabla content_TIPOCONTENIDO, donde residen los contenidos de CCK, ...

Notas:

Hay otra forma de crear la tabla users2 más rápida, que es la siguiente:

create table users2 select * from users;

De esta forma genera la tabla users2 e importa de una todos los datos de users.

categorias: 

eliminar una base de datos en Symfony2 / Doctrine2

eliminamos el php que contiene la definición de la tabla actual, por ejemplo:

rm src/CruiseHunter/CrucerosBundle/Entity/Crucero.php

Ejecutamos el comando:

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

Mas información:

http://www.doctrine-project.org/docs/orm/2.0/en/reference/tools.html sobre todo la sección 23.1.4. Command Overview

 

Y ya estamos en condiciones de volver a ejecutar:

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

sin que nos de un error porque exista ya la clase, lo que suele indicar que hay un .php en Entities que no debería...

Drupal: Publicar un banner o mensaje despues del primer (o segudo) post

Seguro que te ha ocurrido alguna vez. Tienes un banner o un determinado mensaje que quieres colocar en el teaser, después del primer o segundo post, pero no más. No quieres que se repita de forma indefinida, sobre todo porque queda muy intrusivo.

La solución? Mas fácil de lo que en principio había estado tratando de hacer. Si usamos una variable global, su contenido se va a mantener a lo largo de todo el ciclo de vida de carga de la web (mientras un usuario abre la página). Por ejemplo:

<?php

global $nodenumber;

if($teaser){

//if(drupal_is_front_page()){

 

Fijaos que lo pongo al principio del fichero, justo antes de la declaración de inicio del $teaser de Drupal. De esta forma la varible ya está inicializada y evitamos que cada vez que vaya a mostrarse un post en la misma página se reinicie de nuevo la varible.

Ahora vamos al final de la plantilla del tipo de contenido, y hacemos lo siguiente:

<?php //print_r ($node); 

echo 'page:: ' . $page;

$nodenumber = $nodenumber + 1;

echo $nodenumber;

if($nodenumber == 1 || $nodenumber == 3) {

?>

<a href="http://bit.ly/sBPXWg"><img src="<?php echo base_path() . path_to_theme()?>/imagenes/BANNER.jpg" alt="" ></a>

<?php

}

?>

 

Facil, verdad? En nuestro caso estamos mostrando la imagen después del post número 1 y del tercero.

El código tendremos que insertarla en la plantilla del tipo de contenido que estamos usando, por ejemplo en node-blog.tpl.php, o en node-TIPOCONTENIDO.tpl.php

Programadores Drupal

Somos una pequeña empresa / freelance especializados en la programacion web, y en especial somos entusiastas del mundo Open Source, especialistas programadores en Drupal y recientemente podemos ponernos la etiqueta de programadores Symfony2, un grandísimo framework php con muchísimo futuro.

En realidad cualquier proyecto en php está dentro de nuestras capacidades, como lo sería cualquier programador o ingeniero sería capaz de adaptarse en poco más de una semana a cualquier lenguaje de programación nuevo (no es ninguna brabuconada, todos los lenguajes comparten estructuras y grandísimas similitudes, sólo se diferencian en "pequeñas" cosas).

Nos gusta pensar que ayudamos a empresas y emprendedores a plasmar sus sueños sobre la pantalla, y nosotros mismos lanzamos y mantenemos nuestros propios sueños online. Nos encanta la programacion web, el desarrollo y la programación con herramientas "lógicas" como Drupal o lenguajes de programación elegantes como Symfony, Symfony2, Ruby on Rails y en general casi cualquier cosa con la que podamos transformar ideas en "sueños en movimiento".

Si necesita nuestra ayuda y puede encontrarnos, quizá pueda contratarnos...