Introducción
Como vimos en la parte anterior, este script permite generar varios foros, en donde cada foro tiene sus temas de discusión y cada tema tiene varias respuestas.
Con esto la primera función que veremos es la de listar los distintos foros que tenemos en nuestro sistema y luego veremos la que lista los temas de los foros.
Listado de los distintos foros
Como verán en el código, las instrucciones que usamos no son para nada complicadas y están a la mano de cualquier programador principiante de perl. De esta manera podrán modificar el código a gusto y entenderán bien ya que tiene comentarios en cada bloque lógico de la función.
sub foros_listar {
print "Listado de Foros<br />\n";
####### Función para listar los foros #######
# Lista los distintos foros con la cantidad de temas y mensajes que tenga.
# El último mensaje y el último usuario que escribió ese mensaje
#############################################
#Abrir el directorio msdb en donde están todas las carpetas de los distintos foros
opendir (DATABASEDIR, "$msdb_foros_url") || &error('abrir','directorio');
my @foros = readdir (DATABASEDIR);
closedir(DATABASEDIR) || &error('cerrar','directorio');
shift(@foros);
shift(@foros);
print qq *<table width="90%" border="2">
<tr>
<td>Foro</td>
<td>Último mensaje:</td>
<td>Temas</td>
<td>Mensajes</td>
</tr>*;
#Por cada directorio, abrir su archivo de contador, para saber la cantidad de temas y mensajes que tiene
#Abrir el archivo ultimo.txt para tener los datos del último mensaje enviado
foreach my $foro (@foros){
my %contador;
open (DATABASE, "<$contador_url/$foro/contador.txt") || &error('abrir','archivo');
flock (DATABASE,1)||&error('lock','file');
($contador{'temas'},$contador{'mensajes'}) = split(/\|\|/,<DATABASE>);
close (DATABASE) || &error('cerrar','archivo');
my %last_post;
open (DATABASE, "<$contador_url/$foro/ultimo.txt") || &error('abrir','archivo');
flock (DATABASE,1)||&error('lock','file');
($last_post{'autor'},$last_post{'titulo'},$last_post{'fecha'},$last_post{'file'}) = split(/\|\|/,<DATABASE>);
close (DATABASE) || &error('cerrar','archivo');
### H A C E R #comparar la fecha de la ultima visita con la del mensaje, para saber si el nuevo o viejo
print qq *
<tr>
<td><a href="index.pl?action=temas_listar&foro=$foro"> $foro </a></td>
<td>Último mensaje: $last_post{'titulo'} <br />\n
Autor: $last_post{'autor'} <br />\n
Fecha: $last_post{'fecha'} <br />\n
</td>
<td>$contador{'temas'} <br />\n</td>
<td>$contador{'mensajes'} <br />\n</td>
</tr>
<br />*;
}
print qq *</table>*;
#############################################
}
Estructura de los archivos
Para almacenar toda la información de los foros vamos a necesitar dos carpetas situadas en nuestro directorio del foro.
Dichas carpetas son msdb y contador. En la primera almacenamos todos los mensajes y en la segunda vamos llevando la cuenta de los posts, las respuestas y el último mensaje que fue posteado en cada uno de los foros.
A la vez de cada post, llevamos la cuenta de las visitas, las respuestas, el primer y último mensaje y contabilizamos todos los usuarios que participaron en ese post, así cuando un usuario lo visita, el sistema le indica que ya ha participado en esa discusión
Archivo contabilizador de un post:
1||5
Elpiedra||hola||2004-09-03 11:12:20
monoswim||re: hola||2004-09-03 11:12:20
kidd ||monoswim
(Mensajes || Visitas -- 1º post -- último post -- usuarios que participaron)
Archivo contabilizador de un foro:
3||8
(cantidad de temas||cantidad de mensajes)
Archivo almacenando el último post:
monoswim||zx||2004-09-03 11:12:20||2||basura
Como verán la estructura es sumamente sencilla y no presenta mayores dificultades. Cabe destacar que esta misma estructura se puede migrar a cualquier motor de base de datos para hacerla más robusta
Listado de los temas de un foro
sub temas_listar {
print "Listado de Temas del foro: $input_data{'foro'}<br /><br />";
####### Función que lista los temas de un foro
# Lista los 25 temas más actuales del foro, teniendo en cuenta si hay temas nuevos o no
# comparando la fecha del último mensaje y la de la última visita del usuario
print qq *<table width="90%" border="2">
<tr>
<td>Tema / Autor</td>
<td>Último mensaje</td>
<td>Respuestas</td>
<td>Visitas</td>
</tr>*;
# Abrimos la carpeta del foro y vemos todos los temas que tiene
opendir (DATABASEDIR, "$msdb_foros_url/$input_data{'foro'}") || &error('abrir','directorio');
my @temas = readdir (DATABASEDIR);
closedir(DATABASEDIR) || &error('cerrar','directorio');
shift(@temas);
shift(@temas);
#print @temas;
#exit;
# Dejamos solamente los primeros 25 mensajes más actuales
my %temas_time;
foreach my $tema (@temas) {
my $file = "$msdb_foros_url/$input_data{'foro'}/$tema";
$temas_time{-M $file} = $tema || &error('verificar','fechas');
}
# Imprimimos todos los mensajes en orden
foreach my $key (sort (keys %temas_time)){
my (%contador,%msg,%last_msg);
open (DATABASE, "<$contador_url/$input_data{'foro'}/$temas_time{$key}") || &error('abrir','archivo');
flock (DATABASE,1)||&error('lock','file');
($contador{'mensajes'},$contador{'visitas'}) = split(/\|\|/,<DATABASE>);
($msg{'autor'},$msg{'titulo'},$msg{'fecha'}) = split(/\|\|/,<DATABASE>);
($last_msg{'autor'},$last_msg{'titulo'},$last_msg{'fecha'}) = split(/\|\|/,<DATABASE>);
my @users_posted = split(/\|\|/,<DATABASE>);
close (DATABASE) || &error('cerrar','archivo');
#si participó en este tema lo ponemos en negrita
foreach my $user_poster (@users_posted){
if ($user_poster eq $logger_data{'user_name'}){
$msg{'titulo'} = "<b>$msg{'titulo'}</b>";
last;
}
}
#separamos el nombre del resto
my ($tema_id,$basura) = split(/\./, $temas_time{$key});
print qq*
<tr>
<td><a href="index.pl?action=mensajes_listar&foro=$input_data{'foro'}&tema=$tema_id"> $msg{'titulo'} </a><br /> Enviado por: $msg{'autor'} el $msg{'fecha'}</td>
<td>$last_msg{'autor'} el día $last_msg{'fecha'}</td>
<td> $contador{'mensajes'} </td>
<td> $contador{'visitas'} </td>
</tr>*;
}
print qq*
</table><br />Nuevo Tema: <a href="index.pl?action=form_new_tema&foro=$input_data{'foro'}">clickeame</a>
*;
}
Esta función tampoco trae ningún código raro difícil de entender. Simplemente lista los 25 mensajes más actuales de cada uno de los foros.
Ahí les dejo la pelota picando del lado de ustedes para que modifiquen esa parte y hagan que pueda listar de a 25 en 25, por si hay más temas en ese foro.
Igualmente si no lo pueden hacer en el script final que colocaremos estará todo completo, pero es un muy buen ejercicio para agilizar la lógica.
Notas Finales
Espero que les sea útil este tutorial (ya sea en el ámbito teórico o práctico) y me comprometo a publicar el siguiente capítulo la semana que viene.