Ulzurrun de Asanza i Sàez

Contar artículos, comentarios y calcular algunas medias en WordPress

Parte del código de la función
Parte del código de la función

Nunca está de más mostrar algún que otro recuento de contenidos de nuestros blogs. Por ejemplo, el día del aniversario de Sumolari.com publiqué algunos números del blog, como el recuento de artículos, la media de artículos por dia, comentarios por artículo, etc. Cuando calculé estos números lo hice “a mano”, es decir, calculé yo mismo las medias y conté los días pasados, que aunque no lo hice de forma manual (para algo tenemos la calculadora), me llevó más tiempo del que habría necesitado el servidor para hacer unas simples operaciones matemáticas. Sin embargo no es necesario hacerlo manualmente, ya que podemos hacer que el servidor lo calcule, y es realmente fácil realizar el recuento de artículos, comentarios, días pasados desde el inicio del blog y medias artiméticas con estos datos.

Preparando la función básica

Antes de comenzar a contar artículos, comentarios y demás, crearemos una función básica, que acepte un parámetro y que con un switch le asigne el valor de lo que buscamos a la variable $value, que devolveremos más adelante. Como valores para el parámetro de la función, usaremos:

También deberemos cargar la variable $wpdb, que nos dará acceso a los nombres de las tablas de la Base de Datos de WordPress. Esta función la añadiremos al archivo functions.php de nuestro theme, aunque también podemos añadirla en un plugin. Después de este paso, tendremos un código similar a:

[php]
function datos($date) {
global $wpdb;

switch ($date) {
case ‘TOTPOST’:
break;
case ‘TOTDAYS’:
break;
case ‘POSTPERDAY’:
break;
case ‘TOTCOM’:
break;
case ‘COMPERPOST’:
break;
default:
$value = ”;
break;
}
return $value;
}
[/php]

Contar artículos y comentarios

Contar los artículos y los comentarios es bastante sencillo. Primero nos situaremos entre las líneas 5 y 6, y añadiremos:

[php]
$query = $wpdb->get_results(“SELECT * FROM $wpdb->posts WHERE post_status = ‘publish’ AND post_type = ‘post'”);
$value = count($query);
[/php]

Creamos la variable $query, que recibe los resultados de la consulta a la Base de Datos. Esta consulta busca en la tabla de artículos todos las filas que tengan por estado publish y por tipo post. Filtrando por la columna de estado logramos contar sólo el contenido público (fuera borradores y autoguardados). Filtrando por la columna de tipo eliminamos las páginas del resultado.

A continuación le asignamos a $value el recuento de los resultados de la consulta.

El caso de los comentarios es muy similar. Nos situamos entre las líneas 11 y 12 y añadimos:

[php]
$query = $wpdb->get_results(“SELECT * FROM $wpdb->comments WHERE comment_approved = ‘1’”);
$value = count($query);
[/php]

De nuevo, la variable $query almacena el resultado de la consulta, sólo que esta vez la consulta busca en la tabla de comentarios y filtra por la columna de comentarios aprovados, de modo que sólo devuelve los comentarios aprovados (fuera spam). La variable $value almacena el resultado del recuento.

Para sacar la media de comentarios por artículos, crearemos dos variables, una para el recuento de cada uno, les asignaremos el valor llamando a esta misma función y luego dividiremos, calcularemos el valor absoluto y redondearemos a 3 decimales. El código que debemos añadir entre las líneas 13 y 14 es:

[php]
$articulos = datos(‘TOTPOST’);
$comentarios = datos(‘TOTCOM’);
$division = $comentarios / $articulos;
$division = abs($division);
$value = round($division, 3);
[/php]

El código realmente se explica sólo: creamos la variable $artículos (que almacena el recuento de artículos), creamos la variable $comentarios (recuento de comentarios), creamos la variable $division (resultado de la división del total de comentarios entre el total de artículos), calculamos el valor absoluto (con la función abs) y le asignamos a la variable $value el redondeo de la división con 3 decimales de precisión (podéis cambiar el 3 por el número que queráis).

Calculando los días pasados desde la apertura del blog y la fecha actual

Quizá este sea el punto más complejo del tutorial, ya que requiere que usemos funciones que no solemos usar a menudo. La lógica del código siguiente, que deberemos situar entre las líneas 7 y 8), es simple: calculamos el UNIX timestamp (los segundos pasados desde el 00:00:00 UTC del 1 de enero de 1970) de la fecha de inicio del blog, calculamos el de hoy, calculamos la diferencia entre el último y el primero, calculamos el valor absoluto de la diferencia (aunque en realidad, si todo está bien, el resultado sería el mismo que sin calcular el valor absoluto), pasamos esos segundos a días (60 segundos en un minuto, 60 minutos en una hora, 24 horas en un día: 86400 segundos en un día) y truncamos (eliminamos los decimales) el resultado (calculamos sólo días, no fracciones de días).

[php]
$timestamp1 = mktime(0,0,0,9,13,2008);
$timestamp2 = mktime(0,0,0,date(‘n’),date(‘j’),date(‘Y’));
$segundos_diferencia = $timestamp1 – $timestamp2;
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);
$dias_diferencia = abs($dias_diferencia);
$value = floor($dias_diferencia);
[/php]

La función mktime acepta unos cuantos parámetros, pero nosotros nos centraremos en los 6 primeros, que corresponden, de izquierda a derecha, a las horas, los minutos, los segundos, el mes, el día y el año de la fecha en cuestión. En mi caso, dejo las horas, minutos y segundos a 0 (no creo que se gane mucho especificándolos) y establezco el mes en 9 (septiembre) el día en 13 y el año en 2008. Vosotros tendréis que cambiar estos números por los de la fecha del inicio de vuestro blog.

Ahora calcular la media de artículos por día es muy sencillo: recurrimos al mismo método que usamos para calcular la media de comentarios por artículo y listo:

[php]
$articulos = datos(‘TOTPOST’);
$dias = datos(‘TOTDAYS’);
$division = $articulos / $dias;
$division = abs($division);
$value = round($division, 3);
[/php]

Reemplazando etiquetas por valores

Ahora tenemos una función que nos devuelve el valor del dato que buscamos, sin embargo nos interesaría más poder escribir en un artículo una etiqueta del estilo de [TOTPOST] y que WordPress la reemplazase por el valor que le corresponde. Para hacerlo tenemos que crear una nueva función, la cual tendrá dos matrices: la primera conendrá las etiquetas y la segunda los valores. A continuación la función reemplazará las etiquetas por los valores. Por último añadiremos esta función como un filtro de WordPress y ya lo tendremos listo. La función quedaría así:

[php]
add_filter(‘the_content’, ‘reemplaza_etiquetas_con_los_datos’);
function reemplaza_etiquetas_con_los_datos($text) {
$etiquetas = array(‘[TOTPOST]’, ‘[TOTDAYS]’, ‘[POSTPERDAY]’, ‘[TOTCOM]’, ‘[COMPERPOST]’);
$valores = array(datos(‘TOTPOST’), datos(‘TOTDAYS’), datos(‘POSTPERDAY’), datos(‘TOTCOM’), datos(‘COMPERPOST’));
$text = str_replace($etiquetas, $valores, $text);
return $text;
}
[/php]

Con todo esto hecho, el código que tendremos será el siguiente:

[php]
function datos($date) {
global $wpdb;

switch ($date) {
case ‘TOTPOST’:
$query = $wpdb->get_results(“SELECT * FROM $wpdb->posts WHERE post_status = ‘publish’ AND post_type = ‘post'”);
$value = count($query);
break;
case ‘TOTDAYS’:
$timestamp1 = mktime(0,0,0,9,13,2008);
$timestamp2 = mktime(0,0,0,date(‘n’),date(‘j’),date(‘Y’));
$segundos_diferencia = $timestamp1 – $timestamp2;
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);
$dias_diferencia = abs($dias_diferencia);
$value = floor($dias_diferencia);
break;
case ‘POSTPERDAY’:
$articulos = datos(‘TOTPOST’);
$dias = datos(‘TOTDAYS’);
$division = $articulos / $dias;
$division = abs($division);
$value = round($division, 3);
break;
case ‘TOTCOM’:
$query = $wpdb->get_results(“SELECT * FROM $wpdb->comments WHERE comment_approved = ‘1’”);
$value = count($query);
break;
case ‘COMPERPOST’:
$articulos = datos(‘TOTPOST’);
$comentarios = datos(‘TOTCOM’);
$division = $comentarios / $articulos;
$division = abs($division);
$value = round($division, 3);
break;
default:
$value = ”;
break;
}
return $value;
}
add_filter(‘the_content’, ‘reemplaza_etiquetas_con_los_datos’);
function reemplaza_etiquetas_con_los_datos($text) {
$etiquetas = array(‘[TOTPOST]’, ‘[TOTDAYS]’, ‘[POSTPERDAY]’, ‘[TOTCOM]’, ‘[COMPERPOST]’);
$valores = array(datos(‘TOTPOST’), datos(‘TOTDAYS’), datos(‘POSTPERDAY’), datos(‘TOTCOM’), datos(‘COMPERPOST’));
$text = str_replace($etiquetas, $valores, $text);
return $text;
}
[/php]

Cualquier duda, no dudéis en preguntarla en los comentarios.


3 replies on “Contar artículos, comentarios y calcular algunas medias en WordPress

  1. ¿Y esto funciona también en cualquier parte del blog? ¿O sólo en los artículos? Porque estaría bien que en zonas como el pie de página o el menú se pudiera incluir algo como: Número de posts: XXX; Número de comentarios: XXX, etc.

  2. Es una función PHP, la puedes usar donde quieras, en el theme, en un plugin… incluso puedes usarla fuera de WordPress (eso sí, haciendo un include a los archivos necesarios).

    Lo que no podrás usar fuera de los artículos son las etiquetas [TOTCOM] y demás, pero puedes llamar a la función datos desde donde quieras.

  3. Ummm… he estado revisando el código y he detectado algún que otro problema de rendimiento. Se puede mejorar mucho (realmente mucho) el tiempo necesario para procesar la función si se crea un nuevo caso en el switch (por ejemplo, el caso "array") y en ese caso se carga una única vez el recuento de días, artículos y comentarios, y a partir de estos, se calculan los demás datos. Después, en ese mismo caso, se crea $value como una array y se le ponen como valores los diferentes resultados. A continuación, fuera de la función, se crea una nueva variable y se le asigna el resultado de la función datos con el parámetro array. Por último, en la función de reemplazar las etiquetas por los valores de los artículos, se carga (mediante global) la variable que hemos creado antes y se le asigna a $valores el valor de esta variable.

    Con esto habremos reducido la cantidad de consultas a la Base de Datos de unas 50 (en el caso de cargar el inicio del blog) a 2 (en cualquier página), lo cual no está nada mal :) .

Leave a Reply

Your email address will not be published.

Required fields are marked *

Your avatar