**/
function show_channels(PDO $db) {
// Begin the HTML page:
template_header('Channels');
echo "\nChannels:\n
\n";
// Loop through the database reading in each channel, and echoing out a - for it.
// only grab actual channels that start with # ... also pre-lowercase everything.
// this allows us to 'deal' with variable caps in how the channels were logged.
$channels = $db->query("
select distinct lower(chan) as c
from logs
where chan like '#%'
");
foreach ($channels as $row) {
$html = utf8specialchars($row['c']);
$url = urlencode($row['c']);
echo "
- {$html}
\n";
}
// Finish off the page:
echo "\n
\n";
template_footer();
}
/**
* show_days
*
* Create a calendar view of all days available for this particular channel
*
* NOTE: May get unwieldy if large log files. Perhaps consider in the future
* making a paginated version of this? by year? Or a separate 'which year' page
* before this? Not to worry about now.
*
* @param PDO A PDO object referring to the database
* @return void
* @author Eli White
**/
function show_days(PDO $db) {
$channel = $_GET['w'];
$url = urlencode($channel);
// Begin the HTML page:
template_header('Daily Logs for Channel: ' . utf8specialchars($channel));
echo "\n\n";
// Query the database to discover all days that are available for this channel:
$data = array();
$prepared = $db->prepare("
select distinct date(tstamp) as day
from logs
where lower(chan) = :chan
");
$prepared->execute(array(':chan' => $channel));
foreach ($prepared as $row) {
list($y, $m, $d) = explode('-', $row['day']);
$data[$y][$m][$d] = "{$y}-{$m}-{$d}";
}
// For now, just loop over them all and provide a list:
ksort($data);
foreach ($data as $year => $months) {
ksort($months);
foreach ($months as $month => $days) {
// Figure out a few facts about this month:
$stamp = mktime(0, 0, 0, $month, 1, $year);
$first_weekday = idate('w', $stamp);
$days_in_month = idate('t', $stamp);
$name = date('F', $stamp);
// We have a month ... start a new table:
echo <<
{$name} {$year}
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
EOTABLE;
// Now we need to start looping through the days in this month:
echo '';
$rowmod = 0;
// Loop through all day entries, no matter how many blanks we need:
for ($d = (-$first_weekday + 1); $d < $days_in_month + 1; $d++) {
if (!($rowmod++ % 7)) {
// Stop/start a new row:
echo '
';
}
echo '';
// If this day is pre or post actual month days, make it blank:
if (($d < 1) || ($d > $days_in_month)) {
echo ' ';
} elseif (isset($days[$d])) {
// Make a link to the day's log:
echo "{$d}";
} else {
// Just a dead number:
echo $d;
}
echo ' | ';
}
// Finish off any blanks needed for a complete table row:
while ($rowmod++ % 7) {
echo ' | ';
}
echo "
\n";
}
}
// Finish off the page:
echo "\n
\n";
template_footer();
}
/**
* show_log
*
* Actually show the log for this specific day
*
* @param PDO A PDO object referring to the database
* @return void
* @author Eli White
**/
function show_log(PDO $db) {
$channel = $_GET['w'];
$day = $_GET['d'];
$parts = explode('-', $day);
$formatted_date = "{$parts[0]}-{$parts[1]}-{$parts[2]}";
// Begin the HTML page:
template_header('Date: ' . utf8specialchars($formatted_date) .
' - Channel: ' . utf8specialchars($channel));
// Query the database to get all log lines for this date:
$prepared = $db->prepare("
select time(tstamp) as t, type, nick, message
from logs
where lower(chan) = :chan and date(tstamp) = :day
order by tstamp asc
");
$prepared->execute(array(
':chan' => $channel,
':day' => $day,
));
// Loop through each line,
foreach ($prepared as $row) {
// Prepare some basic details for output:
$color = nick_color($row['nick']);
$time = utf8specialchars($row['t']);
$msg = utf8specialchars($row['message']);
$nick = utf8specialchars($row['nick']);
$type = false;
// Now change the format of the line based upon the type:
switch ($row['type']) {
case 4: // PRIVMSG (A Regular Message)
echo "[$time] <{$nick}> {$msg}
\n";
break;
case 5: // ACTION (emote)
echo "[$time] *{$nick} {$msg}
\n";
break;
case 1: // JOIN
echo "[$time] -> {$nick} joined the room.
\n";
break;
case 2: // PART (leaves channel)
echo "[$time] -> {$nick} left the room: {$msg}
\n";
break;
case 3: // QUIT (quits the server)
echo "[$time] -> {$nick} left the server: {$msg}
\n";
break;
case 6: // NICK (changes their nickname)
echo "[$time] -> {$nick} is now known as: {$msg}
\n";
break;
case 7: // KICK (booted)
echo "[$time] -> {$nick} boots {$msg} from the room.
\n";
break;
case 8: // MODE (changed their mode)
$type = 'MODE';
case 9: // TOPIC (changed the topic)
$type = $type ? $type : 'TOPIC';
echo "[$time] -> {$nick}: :{$type}: {$msg}
\n";
}
}
// Finish up the page:
template_footer();
}
/**
* nick_color
*
* Uses a silly little algorithm to pick a consistent but unique(ish) color for
* any given username. NOTE: Augment this in the future to make it not generate
* 'close to white' ones, also maybe to ensure uniqueness? (Not allow two to have
* colors that are close to each other?)
*
* @return string A CSS valid hex color string
* @author Eli White
**/
function nick_color($user) {
static $colors = array();
if (!isset($colors[$user])) {
$colors[$user] = substr(md5($user), 0, 6);
}
return $colors[$user];
}
/**
* utf8specialchars
*
* Just a quick wrapper around htmlspecialchars
*
* @param string The UTF8 string to escape
* @return string An escaped and ready for HTML use string
* @author Eli White
**/
function utf8specialchars($string) {
return htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
}
/********** TEMPLATES **********/
/**
* template_header
*
* Echo out the header for each HTML page
*
* @param $title string The title to be used for this page.
* @return void
* @author Eli White
**/
function template_header($title) {
$css = template_css();
echo <<
Phergie LogViewer - {$title}
Phergie LogViewer - {$title}
EOHTML;
}
/**
* template_footer
*
* Echo out the bottom of each HTML page
*
* @return void
* @author Eli White
**/
function template_footer() {
echo <<
EOHTML;
}
/**
* template_css
*
* Generate the CSS used by these HTML pages & return it.
*
* @return string The CSS in question:
* @author Eli White
**/
function template_css() {
return <<