wp-shortstat-publicgraph: Plugin de Wordpress para publicar un gráfico de visitas
12 de Julio de 2007 en Programación, WordPress, PHP
Lecturas: 4,506

wp-shortstat-publicgraphQué usuario de Wordpress no usa / ha usado el plugin de Wordpress para estadísticas de tráfico wp-shortstat? Alguna vez has querido mostrar públicamente el contador de visitas?

Pues bién, hace unas semanas encontré a un compañero bloguero, Emilio, que tiene un gráfico en su web con las visitas de los últimos siete días... y pensé... mmmm... qué plugin será ése? No lo conozco...

Contacté con él y me contó que había encontrado el código por ahí (en el código no ponía la fuente) y que lo había adaptado a sus necesidades. Muy amablemente me cedió su código y yo lo he convertido en un plugin de Wordpress que se nutre de los datos del wp-shortstat, así que en éste artículo presento justamente el proceso de creación de un plugin de plugin ;-)

Al recibir el código de Emilio, se me hizo muy cuesta arriba realizar un plugin, y el código se me antojaba un poco barroco (bueno, ahí cada uno con su forma de programar). Así que lo primero que hice fué plantearme cómo lo haría. Pensé que lo mejor sería montar una clase que recogiera los datos que captura el wp-shortstat y que usara la generación del gráfico con ésos datos. mmmmm... y funcionó a la primera ;-)

Pero vamos por pasos:

Cabecera de plugin Wordpress

Ésta es la parte sencilla. Con ella Wordpress identificará nuestro archivo como plugin, y lo dejará activar desde el panel de Plugins.

PHP:
  1. /*
  2. Plugin Name: WP-ShortStat-PublicGraph
  3. Plugin URI: http://www.syntaxerror.es/wp-shortstat-publicgraph
  4. Description: Using <a href="http://blog.happyarts.de/wp-shortstat/">WP-ShortStat Plugin</a> shows a graph with the number of visits of the last week.
  5. Version: 0.01
  6. Author: Xavier Arnaus
  7. Author URI: http://www.syntaxerror.es
  8. */

Vale, ahora nuestro script vacío ya es un plugin ;-)

Definición de la clase y atributos

Lo siguiente inmediatamente es declarar la clase y los atributos que vamos a necesitar:

PHP:
  1. class publicgraph
  2. {
  3. var $table_stats;
  4.  
  5. var $week_hits;
  6.  
  7. var $color_background;
  8. var $color_days;
  9. var $color_hits;
  10. var $color_percents;
  11. var $color_bars;
  12. var $color_bars_fill;
  13. var $color_dashedline;
  14. var $color_titles;
  15. var $color_footnote;
  16.  
  17. var $daychar = array(0 => 'D', 1 => 'L', 2 => 'M', 3 => 'X', 4 => 'J', 5 => 'V', 6 => 'S');
  18.  
  19. }

Así, la clase publicgraph tendrá tres atributos y los de los colores:

  • table_stats: Aquí guardaremos el nombre de la tabla que debemos consultar. Ésto es una reminiscencia de la adaptación del plugin wp-shortstat, que lo usa de ésta manera.
  • week_hits: Aquí guardaremos las estadísticas que hemos recogido, para que lo usen los métodos de la clase. Sé que muchos no os va a gustar así, pero es la mejor solución rápida que se me ocurrió.
  • daychar: Éste es un simple array para traducir el número de día que devuelve la función date formateada con w a la letra del día de la semana en castellano.
  • color_*: Todos estos atributos contendrán el color definido para cada pieza del gráfico.

El constructor

El constructor simplemente hace el setado de datos. Primero define el nombre de la tabla según el prefijo con que tenemos montadas las tablas de Wordpress. Luego seta los colores por defecto (aquí estan definidos los de SyntaxError) y lanza el método para recuperar los datos y guardarlos en un lugar común para el resto de métodos.

PHP:
  1. function publicgraph() // Constructor -- Set things up.
  2. {
  3. global $table_prefix;
  4.  
  5. $this->table_stats  = $table_prefix . "ss_stats";
  6.  
  7. $this->setBackgroundColor('666666');
  8. $this->setBarsColor('E58C00');
  9. $this->setBarsFillColor('E58C00');
  10. $this->setDashedLineColor('8E8E8E');
  11. $this->setDaysColor('FFFFFF');
  12. $this->setHitsColor('FFFFFF');
  13. $this->setPercentsColor('8E8E8E');
  14. $this->setTitlesColor('FFFFFF');
  15. $this->setFootNoteColor('8E8E8E');
  16.  
  17. $this->week_hits = $this->getWeekHits();
  18. }

Recogiendo los datos de la Base de Datos

Vamos ahora a por los datos. Si nos repasamos el wp-shortstat por dentro encontramos un método getWeekHits() que construye el primer cuadro que se presenta en la pantalla de estadísticas: las visitas en los últimos 7 días. Curiosamente lo que yo busco es poner éso en un gráfico público, con lo que no necesitamos nada más... Sólo unos pequeños retoques para que en vez de construir una tabla con los resultados, se construya un array bidimensional con los datos para que se usen en otro método.

PHP:
  1. function getWeekHits() {
  2. global $wpdb;
  3.  
  4. $offset=24*60*60;
  5. $of = get_settings('gmt_offset');
  6. $ct = mktime(gmdate("G")+$of, gmdate("i")+($of - ((int) $of)) * 60, gmdate("s"), gmdate("m"), gmdate("d"), gmdate("Y"));
  7.  
  8. $week_hits = array();
  9.  
  10. for ($i=0; $i<8; $i++) {
  11. // start with 00:00 on currente date
  12. $dt_start = mktime(0, 0, 0, date("m", $ct), date("d", $ct)-$i, date("Y", $ct));
  13.  
  14. $day = date('d/m/Y/w',$dt_start);
  15.  
  16. $query = "SELECT COUNT(*) AS 'total', COUNT(DISTINCT remote_ip) as 'unique'  FROM $this->table_stats WHERE dt>= $dt_start AND dt <($dt_start+$offset) AND resource LIKE '%/feed/%'";
  17. if ($results = $wpdb->get_results($query)) {
  18. foreach ($results as $result) {
  19. $feedhits = $result->unique;
  20. $feedtotal = $result->total;
  21. }
  22. }
  23. $query = "SELECT COUNT(*) AS 'total', COUNT(DISTINCT remote_ip) as 'unique' FROM $this->table_stats WHERE dt>= $dt_start AND dt <($dt_start+$offset) AND resource NOT LIKE '%/feed/%'";
  24. if ($results = $wpdb->get_results($query)) {
  25. foreach ($results as $result) {
  26. $total = $result->unique+$feedhits;
  27. $week_hits[] = array('when' => $day, 'unique' => $total, 'feed' => $feedhits);
  28. }
  29. }
  30. }
  31.  
  32. return $week_hits;
  33. }

Como vemos, el proceso es sencillo. Primero se construye el timestamp que usaremos como base, inicializamos el array de resultado y ejecutamos un bucle de 7 iteraciones, una por cada día (recordemos, los 7 últimos días). En el bucle, montamos el timestamp del día que queremos analizar y ya de paso setamos una variable con los datos del día, mes, año y día de la semana (lo usaremos para pintarlo en el gráfico). Luego lanzamos una query que nos de los datos referentes a las visitas en el feed y lo guardamos. Seguidamente lo mismo para los datos que no son feeds y también lo guardamos. Podríamos obviar los feeds, pero no me lo he cargado porque más adelante puede que lo mejore ;-) A medida que se van recorriendo los bucles vamos guardando los datos en el array resultado y al final lo devolvemos.

Obtener el máximo de visitas en el periodo

Como el gráfico se basa en porcentajes, necesitamos saber la cantidad de visitas del día que hubo más. Como tenemos los datos ya en un array no hace falta lanzar otra query, así que lo solucionamos de la siguiente forma:

PHP:
  1. function getMaxWeekHits()
  2. {
  3. $max_week_hits = array();
  4. $max_week_hits=0;
  5. foreach($this->week_hits as $day_hits)
  6. {
  7. if($day_hits['unique']> $max_week_hits) $max_week_hits=$day_hits['unique'];
  8. }
  9.  
  10. return $max_week_hits;
  11. }

Fácil, no?

Setado de los colores del gráfico

Una de las cosas que me pareció útil fué darle más facilidad en la elección de los colores con los que pintaremos el gráfico. Por éso los atributos declarados en la clase, y por éso los métodos siguientes:

PHP:
  1. function translateCode($hexcode)
  2. {
  3. $int = hexdec('0x'.$hexcode);
  4.  
  5. return array("red" => 0xFF & ($int>> 0x10),
  6. "green" => 0xFF & ($int>> 0x8),
  7. "blue" => 0xFF & $int);
  8. }
  9.  
  10. function setBackgroundColor($hexcode)
  11. {
  12. $this->color_background = $this->translateCode($hexcode);
  13. }
  14.  
  15. function setDaysColor($hexcode)
  16. {
  17. $this->color_days = $this->translateCode($hexcode);
  18. }
  19.  
  20. function setHitsColor($hexcode)
  21. {
  22. $this->color_hits = $this->translateCode($hexcode);
  23. }
  24.  
  25. function setPercentsColor($hexcode)
  26. {
  27. $this->color_percents = $this->translateCode($hexcode);
  28. }
  29.  
  30. function setBarsColor($hexcode)
  31. {
  32. $this->color_bars = $this->translateCode($hexcode);
  33. }
  34.  
  35. function setBarsFillColor($hexcode)
  36. {
  37. $this->color_bars_fill = $this->translateCode($hexcode);
  38. }
  39.  
  40. function setDashedLineColor($hexcode)
  41. {
  42. $this->color_dashedline = $this->translateCode($hexcode);
  43. }
  44.  
  45. function setTitlesColor($hexcode)
  46. {
  47. $this->color_titles = $this->translateCode($hexcode);
  48. }
  49.  
  50. function setFootNoteColor($hexcode)
  51. {
  52. $this->color_footnote = $this->translateCode($hexcode);
  53. }

El primer método sirve para transformar un código hexadecimal de color en el decimal rojo, verde y azul que necesitará la función imagecolorallocate que se usa para dibujar el gráfico. Como estamos acostumados a usar los códigos hexadecimales, lo he visto útil hacerlo así. El resto simplemente sirven para setar los colores haciendo uso del método de traducción.

Dibujar el Gráfico

Y aquí viene el método que dibuja el gráfico. Debo reconocer que me costó algunas neuronas entender cómo se dibuja el gráfico, pero una vez cogido el tranquillo es fácil variarlo.

PHP:
  1. function getGraph($tot_width = 90, $tot_height = 100, $path = 'extras/')
  2. {
  3. $x_offset = 25;
  4. $filename = $path.'stats_'.date('YmdH').'.png';
  5. if(!file_exists($filename))
  6. {
  7. $im = imagecreate($tot_width+$x_offset,$tot_height);
  8.  
  9. //Colores
  10. $color_bkg = imagecolorallocate($im,$this->color_background['red'],$this->color_background['green'], $this->color_background['blue']);
  11. $color_days = imagecolorallocate($im,$this->color_days['red'], $this->color_days['green'], $this->color_days['blue']);
  12. $color_hits = imagecolorallocate($im,$this->color_hits['red'], $this->color_hits['green'], $this->color_hits['blue']);
  13. $color_percent = imagecolorallocate($im,$this->color_percents['red'], $this->color_percents['green'], $this->color_percents['blue']);
  14. $color_bars = imagecolorallocate($im,$this->color_bars['red'], $this->color_bars['green'], $this->color_bars['blue']);
  15. $color_dashedline = imagecolorallocate($im,$this->color_dashedline['red'], $this->color_dashedline['green'], $this->color_dashedline['blue']);
  16. $color_titles = imagecolorallocate($im,$this->color_titles['red'], $this->color_titles['green'], $this->color_titles['blue']);
  17.  
  18. imagefill($im,0,0,$color_bkg); //El color de fondo del gráfico
  19. imagedashedline($im,10+$x_offset,10,10+$x_offset,$tot_height-8,$color_dashedline);
  20. imagestring($im,1,8+$x_offset,$tot_height-7,'0%',$color_percent); //Lo que aparece como: 0%
  21. imagedashedline($im,35+$x_offset,10,35+$x_offset,$tot_height-8,$color_dashedline);
  22. imagestring($im,1,32+$x_offset,$tot_height-7,'50%',$color_percent); //Lo que aparece como: 50%
  23. imagedashedline($im,60+$x_offset,10,60+$x_offset,$tot_height-8,$color_dashedline);
  24. imagestring($im,1,54+$x_offset,$tot_height-7,'100%',$color_percent); //Lo que aparece como: 100%
  25. imagestring($im,1,0+$x_offset,0,'Día',$color_titles); //Dibujamos el texto Día
  26. imagestring($im,1,50+$x_offset,0,'Visitas',$color_titles); //dibujamos el texto Visitas
  27. $y1 = $y1+10;
  28. $y2 = $y2+10;
  29.  
  30. //$total_week_hits = $this->getTotalWeekHits();
  31. //$anum = $total_week_hits['hits'];
  32. $max_week_hits = $this->getMaxWeekHits();
  33. $bnum = "0$max_week_hits";
  34.  
  35. //Ahora empezamos a dibujar las barras de los gráficos
  36. foreach($this->week_hits as $day_hits)
  37. {
  38. $var = $day_hits['unique']/$bnum*100;
  39. $width = $var/2;
  40. $y1 = $y1+10;
  41. $y2 = $y1+8;
  42.  
  43. $date = explode('/',$day_hits['when']);
  44.  
  45. if($y1<$tot_height-12)
  46. {
  47. imagestring($im,1,0,$y1,$this->daychar[$date[3]].' '.$date[0].'/'.$date[1],$color_days); //Día correspondiente a las visitas
  48. imagerectangle($im,10+$x_offset,$y1,$width+8+$x_offset,$y2,$color_bars);
  49. imagestring($im,1,65+$x_offset,$y1,$day_hits['unique'],$color_hits); //Numero de visitas
  50. imagefilledrectangle($im,11+$x_offset,$y1+1,$width+9+$x_offset,$y2-1,$color_bars);
  51. }
  52. }
  53.  
  54. //Guardamos la imagen donde queramos
  55. imagepng($im,$filename);
  56.  
  57. //eliminamos la anterior;
  58. $this->deleteLastImage($path);
  59. }
  60.  
  61. return 'http://'.$_SERVER['HTTP_HOST'].'/'.$filename;
  62. }

El funcionamiento es simple. Primero definimos un offset que desplace horizontalmente. Ésta es una modificación mía para dar espacio a los días, pues en la implementación original sólo había un par de dígitos (el día) y yo quería poner la letra del día, el día y el mes.

Como no quiero reescribir el gráfico para cada visita que entre, la idea es generarlo cada hora. Por éso, miramos si para la hora actual el archivo ya está creado. Si lo está devolvemos el nombre de ése archivo, y si no procedemos a crearlo.

Primero creamos la imagen y luego generamos los colores que vamos a usar. Luego empezamos a dibujar/pintar las partes fijas del gráfico usando desplazamientos. Y a continuación recogemos y recorremos el array con los datos. Para cada iteración calculamos la longitud de la barra y la posición y pintamos las partes variables del gráfico. Al acabar guardamos la imagen en un archivo que contendrá el año-mes-día-hora (para poder ver si existe o no en el if inicial) y seguidamente eliminamos el archivo correspondiente a la hora anterior.

Por último retornamos la URL de la imagen que se debe mostrar... porque llamaremos a éste método para que nos la dé desde el tema de Wordpress...

También fácil, no?

Eliminar el archivo de la hora anterior

Lo último que nos queda es un método que se encargue de eliminar el archivo de la hora anterior, más que nada para no ir acumulando archivos... El proceso es muy fácil:

PHP:
  1. function deleteLastImage($path = 'extras/')
  2. {
  3. //una hora
  4. $una_hora = 60*60;
  5.  
  6. $filename = $path.'stats_'.date('YmdH', time() - $una_hora).'.png';
  7.  
  8. return unlink($filename);
  9. }

Aquí es muy fácil. Construimos el nombre del archivo de la hora anterior y lo borramos. Retornamos el resultado, aunque realmente no lo usamos...

Ejecutarlo desde la barra lateral

Abrimos la plantilla de la barra lateral (o dónde queramos instalarlo) y pegamos el siguiente código:

Y se acabó! Si se quiere bajar el archivo para verlo con más calma, lo podéis bajar desde aquí: wp-shortstat-publicgraph.

Podéis ver la página del plugin aquí: wp-shortstat-publicgraph plugin

Saludos!

Tag:
 Enviar a Fresqui

Leer los Comentarios

[ # 2649 ] Comment desde Emirodgar [12 de Julio de 2007, 08:06]

Muy buen artículo :) te ha quedado genial.

[ # 2653 ] Pingback desde Plugin de Wordpress para publicar un gráfico de visitas - ZonaMasters - Recursos para webmasters [12 de Julio de 2007, 10:17]

[…] Leyendo Planeta Código nos comentan acerca del plugin de Wordpress para estadísticas de tráfico wp-shortstat. Pero nos hacen referencia  si tu lo que necesitas es mostrar  públicamente un contador de visitas? Tendrás que seguir algunos pasos. […]

[ # 2663 ] Comment desde Xavi [13 de Julio de 2007, 07:57]

Gracias Emilio, sobretodo por el código que me sirvió de base. ;-)

Saludos!

[ # 2760 ] Comment desde ALPHA [16 de Julio de 2007, 01:19]

Sí está muy bien lo de los contadores de visitas, siempre espefican algo mejor que la barrita del PAGERANK el tráfico de una web o weblog. Un saludo.

[ # 2763 ] Comment desde Xavi [16 de Julio de 2007, 02:15]

Si, es verdad. Además, de esta forma se lleva un pequeño seguimiento del número de visitas a lo largo de los días.

El siguiente paso podría ser recoger los datos de Google Analytics en vez del plugin wp-shortstat

[ # 21457 ] Comment desde Nueva x aqui [09 de Mayo de 2008, 03:39]

Hola!
Me he bajado el plugin e instalado, (también me he instalado el wp-shortstat) pero me dá error…
El código que hay que pegar dónde quiera visualizarlo es este, no?

$publicgraph = new publicgraph();
echo ‘getGraph().’” />’;

No sale bien, sale esto:
$publicgraph = new publicgraph(); echo ‘’; (y en echo un icono de imagen rota…) que estoy haciendo mal??

[ # 21493 ] Comment desde Xavi [10 de Mayo de 2008, 08:57]

Vale, veo que tenemos problemas para mostrar el codigo aqui, en los comentarios…

Para mostrar el grafico debes crear el objeto primero (como ya haces) y luego con un echo generas un tag IMG donde su atributo SRC sea $publicgraph->getGraph();

echo ‘<IMG SRC=’.$publicgraph->getGraph().’ />’;

El problema que tienes es la ruta que no le defines al grafico. Necesitas definirle donde va a guardar la imagen (recuerda que necesitas derechos de escritura). La funcion getGraph tiene los siguientes parmetros:

getGraph($tot_width = 90, $tot_height = 100, $path = ‘extras/’)

Salu10.

Escribe un Comentario





Estadísticas