Random code: Comic Calendar
I wrote this the other night in response to a question on the OCAU forums, and though that perhaps someone else might benefit from it (though please take note of the below disclaimer). The script is a really basic image archive (in this case comics), showing (and linking) the when images were created (based upon the filename). I’m not very happy with the code, but it took just over an hour and was meant as a POC more than anything.
<?php
/*
Note: Code was quickly hacked up, there are spelling mistakes, logic errors
and performance issues. Be careful :-)
- Matt_D <buzzard@project-2501.net>
*/
?>
<html>
<head>
<title>Comic Archive Test</title>
<style>
.calendarTable
{
border-collapse: collapse;
border: 1px solid gray;
margin: 2em;
float: left;
/* To help the floats, float correctly :-/ */
height: 240px;
}
.calendarTable .spacer
{
background-color: lightgray;
}
.calendarTable .hit
{
background-color: #efdfdf;
}
.calendarTable .hit a
{
text-decoration: none;
font-weight: bold;
}
h2
{
text-align: center;
}
</style>
</head>
<body>
<h1>Comic Archive Test</h1>
<?php
error_reporting(E_ALL | E_STRICT);
date_default_timezone_set("Australia/Melbourne");
// We find all the images matching a filemask, and turn them in a array
// of image deatils (i.e. extract the day/month/year)
$imageList = getImageListDetails(glob("./images/*.*"));
if(count($imageList) == 0)
{
die("No images found");
}
// Display an entire years calender if there was one image made
foreach(getYearsWithComics($imageList) as $year)
{
echo "<h2>Comics for $year</h2>";
printCalenderForYear($year, $imageList);
echo "<div style='clear: both'></div>";
}
// Takes a list of filenames, and uses getDateFromImage() to get the
// year/month/day for each one. Returns the a new list.
function getImageListDetails($filenameList)
{
$newDetails = array();
foreach($filenameList as $imageName)
{
try
{
$newDetails[] = getDateFromImage($imageName);
}
catch(Exception $e)
{
echo "\n<!-- Ignoring $imageName - " . $e->getMessage() . " -->\n";
}
}
return $newDetails;
}
// Loop through every image and return an array of years where atleast one
// image is present
function getYearsWithComics($imageList)
{
$yearList = array();
foreach($imageList as $imageDetails)
{
$yearList[] = $imageDetails['year'];
}
return array_unique($yearList);
}
// Extract the ymd from a single image filename, returning an array with
// the keys: year, month, day, filename
// Throws an exception is the filename doesn't match the regex.
function getDateFromImage($imageName)
{
if(preg_match("#img_(\d\d\d\d)(\d\d)(\d\d)\.#", $imageName, $matches) !== 1)
{
throw new Exception("$imageName doesn't not match expected format img_yyymmddd.");
}
return array('filename' => $imageName, 'year' => $matches[1], 'month' => $matches[2], 'day' => $matches[3]);
}
// Given a year, and a list of image details. Display some nice calender
// tables.
function printCalenderForYear($year, $imageList)
{
$skipLookup = array
(
"Sun" => 0,
"Mon" => 1,
"Tue" => 2,
"Wed" => 3,
"Thu" => 4,
"Fri" => 5,
"Sat" => 6,
);
for($month = 1; $month <= 12; $month++)
{
$firstDay = mktime(0, 0, 0, $month, 1, $year);
$monthName = date('F', $firstDay);
$firstDayName = date('D', $firstDay);
$amountToSkip = $skipLookup[$firstDayName];
$daysInMonth = cal_days_in_month(0, $month, $year);
echo "<table class='calendarTable' border='1' cellpadding='4' cellspacing='0'>";
echo "<tr><th colspan='7'>$monthName $year</th></tr>";
echo "<tr><td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td></tr>";
echo "<tr>";
$dayOfWeek = 1;
for($i = 0; $i < $amountToSkip; $i++)
{
echo "<td class='spacer'> </td>";
}
$dayOfWeek += $amountToSkip;
$currentDay = 1;
while($currentDay <= $daysInMonth)
{
// Check to see if there if there was an image made of this date
$foundMatch = false;
foreach($imageList as $imageDetails)
{
if(($imageDetails['year'] == $year) && ($imageDetails['month'] == $month) && ($imageDetails['day'] == $currentDay))
{
$foundMatch = true;
echo "<td class='hit'><a href='{$imageDetails['filename']}'>$currentDay</a></td>";
}
}
// If no image was found, then just display the day
if(!$foundMatch)
{
echo "<td>$currentDay</td>";
}
$currentDay++;
$dayOfWeek++;
if($dayOfWeek > 7)
{
echo "</tr><tr>";
$dayOfWeek = 1;
}
}
if($dayOfWeek != 1)
{
for($i = $dayOfWeek; $i <= 7; $i++)
{
echo "<td class='spacer'> </td>";
}
}
echo "</table>";
echo "\n\n";
}
}
?>
</body>
</html>