Script: Aggregate Rating en WordPress

Script en Ajax para incluir el esquema Aggregate Rating a WordPress y, adaptado, a otros gestores de contenidos.

archivado en: WordPress / 15 septiembre, 2012 / taller:

El otro día vimos la especificación de microdatos AggregateRating, que es un esquema transversal que sirve para la valoración colectiva de las cosas. Existen plugin para WordPress que incorporan metadatos de este tipo, como WP Customer Reviews de Bompus, pero como están basados en microformatos o extensiones RDFa, me interesaba preparar uno específico basado en microdatos para adaptarlo a mi gusto.

Como no tengo tiempo de apañar el código en un plugin y subirlo al repositorio de WordPress, explico cómo lo he programado en AJAX por si a alguien le resulta útil. Lo bueno de hacerlo así es que este código se puede adaptar a cualquier gestor de contenidos (Prestashop, Drupal...), incluso a cualquier web que funcione dinámicamente con PHP.

Bueno, vamos a ver cómo añadir este esquema a una web o un tema WP o dónde sea sin más preámbulos...

Quick Use ^^

  1. Te bajas este archivo zip llamado code_aggregate_rating.zip, que tiene todo lo que vamos a necesitar.
  2. En PHP-MyAdmin, en la base de datos que uses en WP, ejecutas la sentencia SQL que hay en el archivo tabla.sql
  3. Descomprimes todos los archivos que hay en code_aggregate_rating.zip
  4. En mi_conexion.php pones los datos de tu conexión a la base de datos en la que tengas el blog en WP
  5. En single.php o la página que uses para mostrar los post, donde quieras que aparezca el sistema de valoración, añades esta línea: <?php require_once('rating.php'); ?>
  6. Subes todos los archivos a la carpeta de tu tema y chispún... ya estaría 🙂 .

Explicación detallada

1. MySql

Lo primero es crear una tabla en la bbdd con los siguientes campos:

  • id_rating_post: un int autoincrement (este en realidad no sería necesario, pero tengo esa manía de crear índices autoincrements pá tó, jajajajjaaa 😆 .
  • numero_post: con un smallint debería bastar para cualquier blog normal, pero si tienes más de 32767 entradas, ponlo como int y te quitas de líos. Tampoco es que vaya a ir mucho más rápido de la otra forma.
  • ip_user: un varchar de 16. Aquí guardaremos la IP de cada usuario, para que solo se pueda votar una vez por ítem.
  • val_rating: aquí guardaremos la valoración, del 1 al 5, que es la escala normal para este esquema. Con un  tinyint de 4 bastaría.
  • timestamp_rating: por último, guardamos la fecha en que se ha votado, que siempre viene bien para tener controladas las cosas.

Así, esta sería la sentencia SQL a ejecutar en el PHP-Admin

  • CREATE TABLE IF NOT EXISTS `wordpress_rating_post` (
  • `id_rating_post` int(11) NOT NULL AUTO_INCREMENT,
  • `numero_post` smallint(6) NOT NULL,
  • `ip_user` varchar(16) NOT NULL,
  • `val_rating` tinyint(4) NOT NULL,
  • `timestamp_rating` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  • PRIMARY KEY (`id_rating_post`)
  • ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

2. Archivo de conexión

En un archivo que podemos llamar mi_conexion.php indicamos los datos de conexión a la bbdd.

  1. <?php
  2. $dbhost = 'localhost';
  3. $dbuser = 'Tu nombre de usuario';
  4. $dbpass = 'Tu contraseña';
  5. $dbname = 'Nombre de la base de datos';
  6. $link_id = new mysqli($dbhost,$dbuser,$dbpass,$dbname);
  7. if ($link_id ->connect_error) {
  8. echo "Error de Connexion ($link_id->connect_errno)
  9. $link_id->connect_error\n";
  10. exit;
  11. //header('Location: index.php');
  12. }
  13. ?>

3. XMLHttpRequest

Vale, con eso ya estaría hecho lo más complicado, el resto prácticamente es cortar y pegar.

En otro archivo, que podemos llamar funciones_ajax.inc, ponemos el objeto  XMLHttpRequest, que es el puente de enlace entre JavaScript y PHP.

Con este script vamos a pasarle a la página op_rating.php, la encargada de procesar la valoración de los usuarios, tres variables que luego pondremos en JavaScript:

  • val_rating: con la valoración del usuario
  • numero_post: el número de post al que se refiere la votación
  • ip: la ip del usuario
  1. <script type="text/javascript">
  2. function rating(val_rating, ip, numero_post) {
  3. var val_rating;
  4. var ip;
  5. var numero_post;
  6. var xmlhttp;
  7. if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
  8. xmlhttp=new XMLHttpRequest(); }
  9. else {
  10. // code for IE6, IE5
  11. xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
  12. xmlhttp.onreadystatechange=function() {
  13. if (xmlhttp.readyState==4 && xmlhttp.status==200) {
  14. document.getElementById("div_rating").innerHTML=xmlhttp.responseText; }
  15. }
  16. xmlhttp.open("GET","<?php echo get_template_directory_uri(); ?>/op_rating.php?val_rating="+val_rating+"&ip="+ip+"&numero_post="+numero_post,true);
  17. xmlhttp.send();
  18. }
  19. </script>

Importante, en la línea 16 he especificado la ruta del archivo op_rating.php siguiendo la sintaxis un tanto peculiar de WordPress, es decir, con la función get_template_directory_uri(); para indicar el path, pero si adaptas el código para otro gestor, como Drupal, tienes que cambiar eso por lo que se tercie.

4. op_rating.php

En este archivo vamos a procesar la valoración de los usuarios. El código, como diría mi amigo Santos, es más simple que un botijo.

  1. <?php require_once('mi_conexion.php'); // Incluimos la conexión
  2. // Recogemos las variables
  3. if (isset($_REQUEST['val_rating'])) {
  4. $val_rating = strip_tags(addslashes($_REQUEST['val_rating']));  }
  5. if (isset($_REQUEST['numero_post'])) {
  6. $numero_post = strip_tags(addslashes($_REQUEST['numero_post'])); }
  7. if (isset($_REQUEST['ip'])) {
  8. $ip_user = strip_tags(addslashes($_REQUEST['ip']));  } ?>
  9. <?php // Insertamos los datos en la base de datos
  10. if (isset($val_rating) && isset($numero_post) && isset($ip_user)) {
  11. $indexar_valoracion= $link_id->query("INSERT INTO wordpress_rating_post (ip_user, numero_post, val_rating,timestamp_rating )
  12. VALUES ('$ip_user','$numero_post','$val_rating',NOW())"); } ?>
  13. <!-- snippet estrellicas -->
  14. <?php // Sacamos el número de votos y la valoración hasta el momento
  15. $resultado_rating = $link_id->query("SELECT val_rating FROM wordpress_rating_post WHERE numero_post='$numero_post'");
  16. $row_rating = $resultado_rating->num_rows;
  17. $contador = 0;
  18. while($filas_resultado_rating=$resultado_rating->fetch_assoc()){
  19. $contador = $contador+$filas_resultado_rating['val_rating']; }
  20. $total = round(($contador/$row_rating),1);
  21. $total_redondeado = round($total);
  22. /* Añadimos tantas estrellas amarillas como hay en el total redondeado y grises como faltan para llegar a 5
  23. (se podrían añadir medias estrellas, pero eso lo dejo para otro día) */ ?>
  24. <p><b>valoraci&oacute;n de los lectores: </b></p>
  25. <ul style="list-style-type:none;padding:3px; overflow:hidden;">
  26. <?php for ($i=0; $i<$total_redondeado;$i++) { ?>
  27. <li style="float:left"><img src="<?php echo get_template_directory_uri(); ?>/images/sm_estrella.gif" width="18px" height="18px" alt="estrellica valoraci&oacute;n positiva" /></li>
  28. <?php } ?>
  29. <?php for ($i=0; $i<(5-$total_redondeado);$i++) { ?>
  30. <li style="float:left"><img src="<?php echo get_template_directory_uri(); ?>/images/estrellica_blanca.png"" width="18px" height="18px" alt="estrellica valoraci&oacute;n negativa" /></li>
  31. <?php } ?>
  32. <li style="float:left; margin-left:1em;">
  33. <div itemscope itemtype="http://schema.org/Article">
  34. <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
  35. <?php echo " <span itemprop='ratingValue'>".$total."</span> sobre <span itemprop='bestRating'>5</span> (<span itemprop='ratingCount'>".$row_rating."</span> votos)"; ?>
  36. </div> <!-- #itemprop-->
  37. </div> <!-- #itemscope-->
  38. </li>
  39. </ul>
  40. <!-- #snippet estrellicas -->
  41. <?php echo "Muchas gracias por aportar tu opini&oacute;n"; ?>

Importante, en las líneas 27 y 30 pon las imágenes que quieras usar como estrellicas (en la carpeta images hay las dos que uso en este blog).

5. rating.php

En el archivo rating.php mostramos todo el tinglado

  1. <?php require_once('funciones_ajax.inc');
  2. require_once('conexion.php'); // Incluimos la conexión ?>
  3. <script type="text/javascript">
  4. var recoge_ip;
  5. recoge_ip = "<?php echo $_SERVER['REMOTE_ADDR']; ?>";
  6. var recoge_numero_post;
  7. recoge_numero_post = <?php the_ID(); ?>;
  8. </script>
  9. <div>
  10. <!-- snippet estrellicas -->
  11. <?php $numero_post= get_the_ID(); ?>
  12. <?php // Sacamos el número de votos y la valoración hasta el momento
  13. $resultado_rating = $link_id->query("SELECT val_rating FROM wordpress_rating_post WHERE numero_post='$numero_post'");
  14. $row_rating = $resultado_rating->num_rows;
  15. // Si nadie ha votado aún, mostramos un mensaje explicándolo
  16. ?>
  17. <?php
  18. if ($row_rating == 0) { ?>
  19. <p>Este art&iacute;culo a&uacute;n no ha sido valorado.</p>
  20. <?php } else {
  21. // de lo contrario, mostramos las estrellas normales e incluimos microdatos
  22. $contador = 0;
  23. while($filas_resultado_rating=$resultado_rating->fetch_assoc()){
  24. $contador = $contador+$filas_resultado_rating['val_rating'];
  25. }
  26. $total = round(($contador/$row_rating),1);
  27. $total_redondeado = round($total);
  28. /* Añadimos tantas estrellas amarillas como hay en el total redondeado y grises como faltan para llegar a 5
  29. (se podrían añadir medias estrellas, pero eso lo dejo para otro día) */ ?>
  30. <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
  31. <p><b>valoraci&oacute;n de los lectores sobre <i><span itemprop="itemreviewed"><?php echo get_the_title(); ?></span></i> </b></p>
  32. <ul style="list-style-type:none;padding:3px; overflow:hidden;">
  33. <?php for ($i=0; $i<$total_redondeado;$i++) { ?>
  34. <li style="float:left"><img src="<?php echo get_template_directory_uri(); ?>/images/sm_estrella.gif" width="18px" height="18px" alt="estrellica valoraci&oacute;n positiva" /></li>
  35. <?php } ?>
  36. <?php for ($i=0; $i<(5-$total_redondeado);$i++) { ?>
  37. <li style="float:left"><img src="<?php echo get_template_directory_uri(); ?>/images/estrellica_blanca.png" width="18px" height="18px" alt="estrellica valoraci&oacute;n negativa" /></li>
  38. <?php } ?>
  39. <li style="float:left; margin-left:1em;">
  40. <?php echo " <span itemprop='ratingValue'>".$total."</span> sobre <span itemprop='bestRating'>5</span> (<span itemprop='reviewCount'>".$row_rating."</span> votos)"; ?>
  41. </li>
  42. </ul>
  43. </div><!-- #itemscope aggregateRating-->
  44. <?php } // #estrellas normales ?>
  45. <!-- #snippet estrellicas -->
  46. <?php /* Chequeamos que el usuario aún no ha valorado la entrada.
  47. Si no lo ha hecho, ofrecemos la posibilidad de que vote */
  48. $ip_user = $_SERVER['REMOTE_ADDR']; // Saca la IP del usuario
  49. $resultado_user = $link_id->query("SELECT ip_user FROM wordpress_rating_post WHERE ip_user='$ip_user' AND numero_post='$numero_post'");
  50. $row_cnt = $resultado_user->num_rows;
  51. if ($row_cnt==0) { ?>
  52. <p><b>&iquest;Te ha parecido &uacute;til o interesante? </b><br />
  53. <a onclick="javascript: rating(1, recoge_ip, recoge_numero_post)">nada</a> &#8212;
  54. <a onclick="javascript: rating(2, recoge_ip, recoge_numero_post)">un poco </a> &#8212;
  55. <a onclick="javascript: rating(3, recoge_ip, recoge_numero_post)">a medias </a> &#8212;
  56. <a onclick="javascript: rating(4, recoge_ip, recoge_numero_post)"> bastante </a> &#8212;
  57. <a onclick="javascript: rating(5, recoge_ip, recoge_numero_post)">mucho </a></p>
  58. T&uacute; opini&oacute;n es importante, gracias!
  59. <?php } else {
  60. // Si ya votó, le damos las gracias ?>
  61. Ya valoraste este art&iacute;culo, gracias!
  62. <?php } ?>
  63. </div> <!-- #div_rating -->

6. Incluir la valoración

Y ya donde quieras incluir la valoración, por ejemplo, antes de los comentarios, en single.php, incluyes el archivo rating.php

  1. <?php require_once ('rating.php'); ?>

Importante: como puedes ver, el esquema Aggregate está aplicado como propiedad del esquema Article, que es el que uso para formatear semánticamente los post de este blog, pero si vas a utilizar este código, qué sé yo, para libros o lo que sea, cambia la línea 35 por lo que necesites.

|| Tags: , , ,

valoración de los lectores sobre Script: Aggregate Rating en WordPress

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 3.7 sobre 5 (46 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

9 respuestas a “Script: Aggregate Rating en WordPress

  1. Hola chicos la verdad es que no es ningún spam el de directorio. Soy el propietario y me parece interesante. de hecho lo pienso implementar. Que lastima que lo tomen de esa manera.

    Saludos!.

  2. Mis disculpas, Arce, es que ya uno se emparanoia con el spam…

    Un abrazo.

    (Si usas WordPress, estoy a ver si saco dos segundos para implementar el código en un plugin).

  3. Hola! Parece que me las arreglé para conseguir que todo funcione correctamente, pero cuando alguúm usuario hace clic en una de las 5 opciones, as estrellas simplemente desaparecen y el usuario sólo puede ver que si votado a cargar la página. Puede comprobar isto aqui:http://fuvestibular.com.br/livro/orraa-ta-fogo/ y estaría muy agradecido si usted me podría ayudar. Sorry for my very bad spanish!