"community",
"css" => ['calendar.css'],
"layout_span" => 12,
];
/*
This script serves three different forms of the calendar data:
a monthly view ($cm, $cy)
a daily view ($cm, $cd, $cy)
an individual item view ($id)
For the last two, the month view is also displayed beneath the
specifically requested data. If we encounter an error, we have
a fallback to display the actual month/year.
*/
$begun = false; $errors = [];
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$cy = isset($_GET['cy']) ? (int) $_GET['cy'] : 0;
$cm = isset($_GET['cm']) ? (int) $_GET['cm'] : 0;
$cd = isset($_GET['cd']) ? (int) $_GET['cd'] : 0;
// If the year is not valid, set it to the current year
// This excludes all the "too old", or "too far in the future"
// calendar displays (so search engines can handle this page too)
if ($cy != 0 && !valid_year($cy)) {
$cy = date("Y");
}
// We need to look up an event with an ID
if ($id) {
// Try to load event by ID and display header and info for that event
if ($event = load_event($id)) {
site_header("Event: " . stripslashes(htmlentities($event['sdesc'], ENT_QUOTES | ENT_IGNORE, 'UTF-8')), $site_header_config);
display_event($event, 0);
$begun = true;
}
// Unable to find event, put this to the error messages' list
else {
$errors[] = "There is no event for specified id ('" . htmlentities($id, ENT_QUOTES | ENT_IGNORE, 'UTF-8') . "')";
}
}
// Year, month and day specified, display a daily view
elseif ($cy && $cm && $cd) {
// Check if date is valid
if (checkdate($cm,$cd,$cy)) {
// Date integer for that day
$date = mktime(0, 0, 1, $cm, $cd, $cy);
// Try to load events for that day, and display them all
if ($events = load_events($date)) {
$site_header_config = ['classes' => 'calendar calendar-day'] + $site_header_config;
site_header("Events: " . date("F j, Y", $date), $site_header_config);
echo "
for each of the events that are on a given day
function display_events_for_day($day, $events): void
{
// For preservation of state in the links
global $cm, $cy, $COUNTRY;
// For all events, try to find the events for this day
foreach ($events as $event) {
// Multiday event, which still lasts, or the event starts today
if (($event['type'] == 2 && $event['start'] <= $day && $event['end'] >= $day)
|| ($event['start'] == $day)) {
echo '
';
}
}
}
// Find a single event in the events file by ID
function load_event($id)
{
// Open events CSV file, return on error
$fp = @fopen("backend/events.csv",'r');
if (!$fp) { return false; }
// Read as we can, event by event
while (!feof($fp)) {
$event = read_event($fp);
// Return with the event, if it's ID is the one
// we search for (also close the file)
if ($event !== false && $event['id'] == $id) {
fclose($fp);
return $event;
}
}
// Close file, and return sign of failure
fclose($fp);
return false;
}
// Load a list of events. Either for a particular day ($from) or a whole
// month (if second parameter specified with TRUE)
function load_events($from, $whole_month = false)
{
// Take advantage of the equality behavior of this date format
$from_date = date("Y-m-d", $from);
$bom = mktime(0, 0, 1, date("m",$from), 1, date("Y",$from));
$eom = mktime(0, 0, 1, date("m",$from) + 1, 0, date("Y",$from));
$to_date = date("Y-m-d", $whole_month ? $eom : $from);
// Set arrays to their default
$events = $seen = [];
// Try to open the events file for reading, return if unable to
$fp = @fopen("backend/events.csv",'r');
if (!$fp) { return false; }
// For all events, read in the event and check it if fits our scope
while (!feof($fp)) {
// Read the event data into $event, or continue with next
// line, if there was an error with this line
if (($event = read_event($fp)) === false) {
continue;
}
// Keep event's seen list up to date
// (for repeating events with the same ID)
if (!isset($seen[$event['id']])) { $seen[$event['id']] = 1; }
else { continue; }
// Check if event is in our scope, depending on type
switch ($event['type']) {
// Recurring event
case 3:
$date = date_for_recur($event['recur'], $event['recur_day'], $bom, $eom);
$event['start'] = date("Y-m-d", $date);
// Fall through. Now it is just like a single-day event
// Single-day event
case 1:
if ($event['start'] >= $from_date && $event['start'] <= $to_date) {
$events[] = $event;
}
break;
// Multi-day event
case 2:
if (($event['start'] >= $from_date && $event['start'] <= $to_date)
|| ($event['end'] >= $from_date && $event['end'] <= $to_date)
|| ($event['start'] <= $from_date && $event['end'] >= $to_date)) {
$events[] = $event;
}
break;
}
}
// Close file and return with results
fclose($fp);
return $events;
}
// Reads an event from the event listing
// Parameter: opened event listing file
function read_event($fp)
{
// We were unable to read a line from the file, return
if (($linearr = fgetcsv($fp, 8192)) === false) {
return false;
}
// Corrupt line in CSV file
if (count($linearr) < 13) { return false; }
// Get components
[
$day, $month, $year, $country,
$sdesc, $id, $ldesc, $url, $recur, $tipo, $sdato, $edato, $category
] = $linearr;
// Get info on recurring event
@[$recur, $recur_day] = explode(":", $recur, 2);
// Return with SQL-resultset like array
return [
'id' => $id,
'type' => $tipo,
'start' => $sdato,
'end' => $edato,
'recur' => $recur,
'recur_day' => $recur_day,
'sdesc' => $sdesc,
'url' => $url,
'ldesc' => base64_decode($ldesc, false),
'country' => $country,
'category' => $category,
];
}
// We would not like to allow any year to be viewed, because
// it would fool some [not clever enough] search engines
function valid_year($year)
{
// Get current year and compare to one sent in
$current_year = date("Y");
// We only allow this and the next year for displays
if ($year != $current_year && $year != $current_year + 1) {
return false;
}
// The year is all right
return true;
}
?>