Un poco de programación en PHP. ¿Cómo hacer un mecanismo de menciones en WordPress?

Mención en eseeusee.com

WordPress es una herramienta fascinante. Puedes hacer desde un blog corriente como Telira.net, otro más sofisticado como este, hasta cosas que no parecen un blog –o que lo parecen menos- como eseeusee.com. Para casi cualquier cosa que quieras hacer, hay un plugin ya empaquetado que lo hace por ti, la mayoría de ellos gratis. Y si no, puedes encontrar procedimientos en los foros de WordPress o en Stack Overflow, principalmente, pero también en otros millones de ubicaciones en la web.

Lo que yo quería hacer para Eseeusee era muy simple: un mecanismo de menciones como el de Twitter o Instagramque funcione en

Mención en eseeusee.com

Mención en eseeusee.com

blogs que tengan varios autores o multiuser con permiso de escritura. Cuando un usuario comenta un post o un comentario de otro, automáticamente se le manda un aviso a este último de que fue comentado (un mail). Pero quería que se hiciera otro tanto cuando en un comentario se pusiera el nombre de uno o varios usuarios precedidos por una arroba.

Y no he visto ni plugin ni respuesta en los foros. Seguro que lo que ha pasado es que he buscado poco, pero por si acaso, aquí dejo lo que he hecho. Es la primera versión, así que necesita refinamiento para cada circunstancia –incluso para la mía- pero creo que sirve bien de inspiración y punto de partida. Cuando lo tenga acabado –y un poco de tiempo- haré un plugin y lo subiré al repositorio de WordPress… 😉  Mientras tanto, puedes ver cómo funciona en eseeusee.com (http://eseeusee.com/2014/micropoema3022) o (http://eseeusee.com/2013/micropoema931 )…

Ahí va. Necesitarás saber un poco de php… o fé ciega para incluir estos fragmentos de código en tu instalación de wordpress 🙂

UNA PEQUEÑA FUNCION AUXILIAR

El tema es que el nombre del usuario no necesariamente coincide con el displayname. Y de todos modos, para operar con usuarios en WordPress lo que se necesita es el userID, un número autogenerado que identifica unívocamente a cada usuario. La función siguiente devuelve el ID a partir del nombre de usuario. La encontré en  Stack Exchange

[learn_more caption=”get_user_id_by_display_name”][box type=”info”]

function get_user_id_by_display_name( $display_name ) {

global $wpdb;

if ( ! $user = $wpdb->get_row( $wpdb->prepare(

“SELECT `ID` FROM $wpdb->users WHERE `display_name` = %s”, $display_name

) ) )

return false;

return $user->ID;

}

[/box][/learn_more]

OJO: Una de las cosas que me quedan pendientes es ver qué ocurre si dos usuarios tienen el mismo displayname (¿Es esto posible en WordPress?) Por lo demás funciona níquel como correspodne a una SELECT de SQL muy sencillota que interroga la tabla de usuarios.

LA CHICHA: EXAMINAR CADA COMENTARIO Y ENVIAR EMAIL A LOS MENCIONADOS

La siguiente función lee cada comentario, buscando menciones (patrones @nombre_de_usuario) y, para cada una envía un email con el contenido del comentario a quien fue mencionado.

[learn_more caption=”Función para enviar un email a los citados”][box type=”info”]

function delanton_citados_sendmail($comment_id, $approval_status=” “){

$comment = get_comment( $comment_id );

$commenter = get_userdata($comment->user_id)->display_name;

$commenter_link = “http://www.eseeusee.com/author/”.get_userdata($comment->user_id)->user_login;

$the_subject = sprintf( __(‘%1$s te citó en eseeusee.com’), $commenter );

// divide la frase mediante cualquier número de comas o caracteres de espacio,

// lo que incluye ” “, r, t, n y f

// OJO  SI METES DOS NOMBRES DE USUARI UNO CON MAYUSCULAS Y OTRO CON MINUSCULAS (EL MISMO)

// SE MANDARÁ EL MSG A AMBOS DOS (EL MISMO; CLARO)

$people_cited_d = preg_split(“/[s,]+/”, $comment->comment_content);

$people_cited = array_unique((preg_grep(“/^@.*/”, $people_cited_d)));

$the_message = sprintf( __(‘%1$s dijo en eseeusee.com : “%2$s” ‘),$commenter, $comment->comment_content );

$the_message .= “rnrnrn” . “Si quieres responder pincha aquí: “;

$the_message .= sprintf( __(‘%s’), get_permalink( $comment->comment_post_ID ) . ‘#comment-‘ . $comment_id ) . “rn”;

$the_message .= “rn” . “Y si quieres conocer más de quien comentó, aquí: “.$commenter_link;

foreach($people_cited as $citado)

{

$email= get_userdata(get_user_id_by_display_name(substr($citado, 1)))->user_email;

if ($email != “”)

{

wp_mail( $email, $the_subject, $the_message  );

}

}

}

[/box][/learn_more]

OJO: Esta función tiene varias cosas que completar, pero a falta de tiempo me parecía interesante compartirlo ya. Por ejemplo, (1) no distingue entre mayúsculas y minúsculas, así que si pongo varios nombres de usuario que son el mismo, pero de distinta forma, por ejemplo, @raul @Raúl @RAUL, se enviarán 3 emails al mismo. (2) Otra cosa es que todos mis display name están libres de espacios (cambian espacios en blanco por ‘_’) y este código está pensado para esta eventualidad, con lo que si no es tu caso, podría no funcionar –seguro que no lo hace- para los nombres que tengan algo más que números, letras y subrayados. En ese caso, o modificas el código para poder poner el nombre entre comillas, por ejemplo, o bien –mi opción-, haces que los displayname nunca tengan espacios.

Si solucionas algún error o completas el código para que funcione en tu site… un detalle sería dejar un comentario a este post 😉

Por último… ¿Cómo hago que esta función se ejecute cada vez que alguien escribe un comentario? Pues añadiendo el siguiente código en el archivo PHP que estés modificando.

add_action(‘comment_post’, ‘delanton_citados_sendmail’);

 

LA LIMONÁ: QUE APAREZCAN EN NEGRITA Y COMO UN LINK LOS NOMBRES DE USUARIO EN LOS COMENTARIOS

 

¿Qué menos? Eso se hace modificando en tu theme el código en que se muestran un post único y, por ende, sus comentarios. Puede llamarse algo como SinglePost.php… y se trata de sustituir el fragmento de código en que se escribe el comentario –algo así como echo $get_comment_text() o similar- por este otro.

Lo que hace este código es poner en negrita cada mención (@nombre_de_usuario) y hacer de él un link a la página de los posts de ese autor en el site.

[learn_more caption=”Modificación para poner menciones en negrita en los comentarios”][box type=”info”]

<?php $comentario= preg_replace_callback ('/(@[w-]*)/',

function ($coincidencias) {

$cadena = '‘;

if (get_user_id_by_display_name(substr($coincidencias[0], 1))!=0) /*por si el username ya no existe o nunca existió*/

{$cadena .= ‘‘.$coincidencias[0].’‘ ;}

else

{$cadena .= $coincidencias[0];}

$cadena .=  ‘‘;

return $cadena;

},

get_comment_text());

echo $comentario; ?>

[/box][/learn_more]

Mención en eseeusee.com

Mención en eseeusee.com

OJO: ¿Problemas que podemos tener además del mencionado dependiendo de la forma que tengan tus displayname? Pues yo veo uno. ¿Qué pasa con las menciones antiguas si el displayname de alguien cambia? Pues que este código, a partir del cambio, no encontraría el link al contenido del autor. ¿Cómo solucionarlo? Lo primero que se me ocurrió fue migrar adaptado este código al mecanismo de registro de comentarios, de modo que el link se calculara al escribir el comentario y quedara grabado en la base de datos. El problema entonces –en el escenario de cambio de displayname- sería que tendría comentarios con el link OK pero para displaynames que ya no corresponden con lo real y que, incluso podrían corresponder a otro usuario. En fin. Que no lo toqué. Si cambias tu username, pierdes tus links.

Lo mismo que dije antes: si se te ocurre como solucionarlo, cualquier comment es bienvenido.

Raúl Antón Cuadrado

3 comentarios sobre “Un poco de programación en PHP. ¿Cómo hacer un mecanismo de menciones en WordPress?

  1. Pingback: Bitacoras.com

  2. WiFi Hack

    My brother recommended I might like this blog.

    He was once totally right. This publish actually made my day.
    You cann’t consider just how so much time I had spent for
    this information! Thank you!

Leave a Reply

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.