first commit

This commit is contained in:
2023-10-21 04:55:29 +02:00
commit 74e1f0054a
59 changed files with 11176 additions and 0 deletions

217
php/calendar-month.php Normal file
View File

@@ -0,0 +1,217 @@
<?php
require_once ('ics.php');
$ical = null;
if (isset ($_GET["ics_url"])) {
$ical = getCalendar($_GET["ics_url"]);
}
/**
* Sets and returns the global $requested_month variable
* to either the GET requested month, or the current month
*
* @return int Month number
*/
function getRequestedMonth () {
global $_GET, $requested_month;
if (isset ($requested_month)) return $requested_month;
if (
! isset ($_GET["month"]) ||
! ($requested_month = intval ($_GET["month"])) ||
$requested_month > 12 ||
$requested_month < 1
) {
$requested_month = idate("m");
}
return $requested_month;
}
/**
* Echoes the requested months' name
*/
function echoMonthName () {
echo getLocalizedMonthName (getRequestedMonth ());
}
/**
* Returns HTML for a days' events list (CSS class day-events-scrollbox)
*
* @param ICal $ical ICal object
* @param int $day Day of month
* @param int $month Month (defaults to current month)
* @param int $year Year (defaults to current year)
*
* @return string HTML containing DIV of class day-events-scrollbox
* @return false False on failure
*/
function generateDayEventsList ($ical, $day, $month = null, $year = null) {
if (! $ical) return false;
$html = '
<div class="day-events-scrollbox">
<div class="day-events autoscroll">
%s
</div>
<div class="day-events-shadow"></div>
</div>
';
foreach (getEventsForDay ($ical, $day, $month, $year) as $event) {
$dtstart = $ical -> iCalDateToDateTime($event -> dtstart_array[3]);
$dtend = $ical -> iCalDateToDateTime($event -> dtend_array[3]);
$today_start = new DateTime(
date('Y-m-d H:i:s', mktime(0, 0, 0, $month, $day, $year)),
$dtstart -> getTimezone()
);
$today_end = clone $today_start; $today_end -> modify("+1 day");
$time_separator = "-";
$time_prefix = "";
$time_start = $dtstart -> format('H:i');
$time_end = $dtend -> format('H:i');
// When start date is in past, don't display start time
if ($dtstart < $today_start) {
$time_start = "";
$time_separator = "Bis ";
}
// When end date is in future, don't display end time
if ($dtend > $today_end) {
$time_end = "";
$time_separator = "";
$time_prefix = "Ab ";
}
// Assemble time display string
$time_str = "{$time_prefix}{$time_start}{$time_separator}{$time_end}";
// Check if event is all day
if ($time_start == "00:00" && $time_end == "00:00") {
//$time_str = "Ganztägig";
$time_str = "";
}
// Check if event is multi day
if ($time_start == "" && $time_end == "") {
$time_str = "Mehrtägig";
}
// Check if multi day event without start times
if ($time_start . $time_end == "00:00") {
$time_str = "Mehrtägig";
}
$html = sprintf (
$html,
sprintf(
'<span class="day-event-entry">
<span class="time">%s</span>
<span class="description">%s</span>
</span>
%%s',
$time_str,
$event -> summary
),
);
}
$html = sprintf ($html, "<!-- {$day} -->");
return $html;
}
/**
* Returns HTML with all elements going in the DIV with CSS class calendar-body
*
* @param ICal $Ical ICal object
* @param int $month Month
*
* @return string HTML containing elements for calendar body
* @return false False on failure
*/
function generateCalendarBodyItems ($ical, $month) {
if ($month > 12 || $month < 1) return false;
$html = '%s';
$odd_row = false;
// Number of days in month
$month_max_days = idate ("t", mktime (0, 0, 0, $month));
// First of month unix timestamp
$first_of_month = new DateTime (
date('Y-m-d H:i:s', mktime (0, 0, 0, $month, 1))
);
// Days needed to pad the calendar at the start
$pad_days = idate ("N", $first_of_month -> getTimestamp()) - 1;
// First of the month, minus the pad days
$day = $first_of_month -> modify ("-{$pad_days} days");
// Number of total entries in calendar
$num_rows = ceil (($pad_days + $month_max_days) / 7);
$num_entries = ($num_rows * 8);
// Loop over all entry slots and generate entries
for ($item_index = 0; $item_index < $num_entries; $item_index ++) {
// If item_index is beginning of row, add week number entry
if ($item_index % 8 == 0) {
$week = $day -> format ("W");
$html = sprintf (
$html,
"<div class=\"calendar-header-value\">Woche {$week}</div>
%s",
);
// Swap odd and even rows
$odd_row = ! $odd_row;
continue;
}
$calendar_entry_html = '
<div class="calendar-entry %s %s %s">
<div class="day-header %s"><span>%d.</span></div>
%s
</div>
%s
';
$html = sprintf (
$html,
sprintf(
$calendar_entry_html,
$odd_row? "odd-row" : "even-row",
(isDateTimeWithinMonth ($day, $month)) ? "" : "other-month",
(isDateTimeDuringWeekend ($day)) ? "weekend" : "",
(isDateTimeToday ($day))? "today" : "",
$day -> format ("d"),
generateDayEventsList(
$ical,
intval ($day -> format ("d")),
intval ($day -> format ("m")),
),
"%s"
)
);
$day -> modify ("+1 day");
}
return sprintf($html, "");
}
/**
* Echoes HTML to insert all calendar day entries
*/
function echoCalendarEntries() {
global $ical;
echo generateCalendarBodyItems($ical, getRequestedMonth());
}

207
php/flow.php Normal file
View File

@@ -0,0 +1,207 @@
<?php
require_once ('ics.php');
$ical = null;
if (isset ($_GET["ics_url"])) {
$ical = getCalendar($_GET["ics_url"]);
}
/**
* Fetches the user requested start date for the flow
*/
function getRequestedStartDate () {
global $_GET, $requested_start_date;
if (isset ($requested_start_date)) return $requested_start_date;
if (
! isset ($_GET["start_date"]) ||
! ($requested_start_date = new DateTime ($_GET["start_date"]))
) {
$requested_start_date = new DateTime ();
}
return $requested_start_date;
}
/**
* Fetches the user requested amount of days to display
*/
function getRequestedDisplayedDays () {
global $_GET, $requested_display_days;
if (isset ($requested_display_days)) return $requested_display_days;
if (
! isset ($_GET["days"]) ||
! ($requested_display_days = intval($_GET["days"]))
) {
$requested_display_days = 7;
}
return $requested_display_days;
}
/**
* Return HTML for a flow day entry
*
* @param ICal $ical ICal object
* @param DateTime $date DateTime object
*
* @return string Returns HTML with flow day entry
* @return false False on failure
*/
function generateFlowEntryForDay ($ical, $date) {
if ($ical == null || $date == null) return false;
$html = sprintf (
'
<div class="flow-element">
<div class="flow-day-name">
<div class="day">%s</div>
<div class="weekday">%s</div>
</div>
<div class="flow-day-entries">
%%s
</div>
</div>
',
$date -> format ("d"),
getLocalizedShortDayName (
intval ($date -> format ("N"))
)
);
// Fetch events for the specified date
$events = getEventsForDate ($ical, $date);
// Skip empty days
if (count ($events) == 0) return "";
// Iterate over each event and add an event entry to the HTML
foreach ($events as $event) {
$dtstart = $ical -> iCalDateToDateTime($event -> dtstart_array[3]);
$dtend = $ical -> iCalDateToDateTime($event -> dtend_array[3]);
$today_end = clone $date; $today_end -> modify("+1 day");
$time_separator = " - ";
$time_prefix = "";
$time_start = $dtstart -> format('H:i');
$time_end = $dtend -> format('H:i');
// When start date is in past, don't display start time
if ($dtstart < $date) {
$time_start = "";
$time_separator = "Bis ";
}
// When end date is in future, don't display end time
if ($dtend > $today_end) {
$time_end = "";
$time_separator = "";
$time_prefix = "Ab ";
}
// Assemble time display string
$time_str = "{$time_prefix}{$time_start}{$time_separator}{$time_end}";
// Check if event is all day
if ($time_start == "00:00" && $time_end == "00:00") {
$time_str = "Ganztägig";
}
// Check if event is multi day
if ($time_start == "" && $time_end == "") {
$time_str = "Mehrtägig";
}
// Check if multi day event without start times
if ($time_start . $time_end == "00:00") {
$time_str = "Mehrtägig";
}
$html = sprintf (
$html,
sprintf (
'<div class="flow-day-entry">
<span class="description">%s</span>
<span class="time">%s</span>
</div>
%%s',
$event -> summary,
$time_str
),
);
}
$html = sprintf ($html, '');
return $html;
}
/**
* Return HTML with flow header for specific date
*
* @param DateTime $date DateTime object
*
* @return string Returns HTML with flow header
* @return false False on failure
*/
function generateFlowHeader ($date) {
if ($date == null) return false;
return sprintf (
'<div class="flow-header">
<div class="flow-header-spacer"></div>
<div class="flow-header-value">%s</div>
</div>',
getLocalizedMonthName (intval ($date -> format ("m")))
);
}
/**
* Return HTML for the flow body
*
* @param ICal $ical ICal object
* @param DateTime $date DateTime object
* @param int $days Days to display
*
* @return string Returns HTML with the entire flow data
* @return false False on failure
*/
function generateFlowData ($ical, $date, $days) {
if ($ical == null || $date == null) return false;
$html = generateFlowHeader ($date) . "\n%s";
$end_date = clone $date; $end_date -> modify ("+{$days} days");
while ($date <= $end_date) {
if ($date -> format ("d") == "01") $html = sprintf (
$html,
generateFlowHeader ($date) . "\n%s"
);
$html = sprintf (
$html,
generateFlowEntryForDay($ical, $date) . "%s"
);
$date -> modify ("+1 day");
}
$html = sprintf ($html, "");
return $html;
}
/**
* Echoes the entire HTML for the flow body
*/
function echoFlowBody () {
global $ical;
echo generateFlowData (
$ical,
getRequestedStartDate(),
getRequestedDisplayedDays()
);
}

73
php/html-components.php Normal file
View File

@@ -0,0 +1,73 @@
<?php
$_ERRORS = [];
/**
* Adds an error to the $_ERROR array to be displayed at the end
* of a PHP script as HTML dialogs
*
* @param string $message Error message
*/
function showError ($message) {
if ($message == "") return;
$message = str_replace("\n", "<br>", $message);
$message = str_replace(" ", "&nbsp;", $message);
global $_ERRORS;
$_ERRORS[] = $message;
}
/**
* Write text into stderr
*
* @param string $text Text to log
*/
function debug ($text) {
error_log("\n> $text" . PHP_EOL);
}
/**
* Echoes HTML code to display all collected error messages
*/
function insertErrorsHtml() {
global $_ERRORS;
if (count ($_ERRORS) == 0) return;
// Dialog frame HTML
$base_html = '
<div class="dialog-parent">
<div class="dialog">
<div class="dialog-content">
<b>Fehler beim Laden der Seite:</b><br>
<br>
%s
</div>
<div class="dialog-buttons">
<button onclick="closeDialog(this)">OK</button>
</div>
</div>
</div>
';
$errors_html = "";
foreach ($_ERRORS as $error) {
$errors_html .= "{$error}<br>";
}
printf ($base_html, $errors_html);
}
/**
* Hides the dialog box asking for an ICS URL if one
* was already specified by the user
*/
function hideMissingIcsDialog () {
global $_GET;
if (isset ($_GET["ics_url"]) && $_GET["ics_url"] != "") {
echo "hidden";
}
}

206
php/ics.php Normal file
View File

@@ -0,0 +1,206 @@
<?php
require_once ('html-components.php');
require_once ('vendor/autoload.php');
use ICal\ICal;
date_default_timezone_set("Europe/Berlin");
/**
* Returns the name of a month
*
* @param int $month Month index, 1 to 12
*
* @return string Month name
* @return string Blank string if invalid month was given
*/
function getLocalizedMonthName ($month) {
if (! $month || $month > 12 || $month < 1) return "";
return [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember"
][$month - 1];
}
/**
* Returns the short name of a day of week
*
* @param int $day_of_week DoW index, 1 to 7
*
* @return string Day of week name
* @return string Blank string if invalid DoW was given
*/
function getLocalizedShortDayName ($day_of_week) {
if ($day_of_week < 1 || $day_of_week > 7) return "";
return [
"Mo.",
"Di.",
"Mi.",
"Do.",
"Fr.",
"Sa.",
"So."
][$day_of_week - 1];
}
/**
* Tests if a given date is today
*
* @param DateTime $date DateTime object to compare against
*
* @return true when the DateTime object is today
* @return false when the DateTime object is not today
*/
function isDateTimeToday ($date) {
return $date -> format ("Y-m-d") == date ("Y-m-d");
}
/**
* Tests if a given date is within the current month
*
* @param DateTime $date DateTime object to compare against
* @param int $month Month to check against (defaults to current month)
*
* @return true when the DateTime object is within the current month
* @return false when the DateTime object is not within the current month
*/
function isDateTimeWithinMonth ($date, $month = null) {
$compareDate = new DateTime ();
if ($month != null) $compareDate = new DateTime ("this year $month/01");
return $date -> format ("Y-m") == $compareDate -> format ("Y-m");
}
/**
* Tests if a given date is during the weekend
*
* @param DateTime $date DateTime object to test
*
* @return true when the DateTime object is a weekend day
* @return false when the DateTime object is a week day
*/
function isDateTimeDuringWeekend ($date) {
return intval ($date -> format ("N")) > 5;
}
/**
* Fetches an ICal object from an ICS URL
*
* @param string $url ICS URL to fetch from
*
* @return ICal ICal object
*/
function getCalendar ($url) {
try {
$ical = new ICal (false, array(
'defaultSpan' => 2, // Default value
'defaultTimeZone' => 'Europe/Berlin',
'defaultWeekStart' => 'MO', // Default value
'disableCharacterReplacement' => false, // Default value
'filterDaysAfter' => null, // Default value
'filterDaysBefore' => null
));
$ical -> initUrl(
$url,
$username = null,
$password = null,
$userAgent = null
);
} catch (Exception $e) {
showError( "ICal error: " . $e -> getMessage() );
return $ical;
}
return $ical;
}
/**
* Returns all events from an iCal object
*
* @param ICal $ical ICal object
*
* @return array Array of event objects
* @return false False on failure
*/
function getEvents ($ical) {
if (! $ical) return false;
return $ical -> sortEventsWithOrder (
$ical -> events ()
);
}
/**
* Returns all events from an ICal object for a specific day
*
* @param ICal $ical ICal object
* @param int $day Day
* @param int $month Month (defaults to current month)
* @param int $year Year (default to current year)
*
* @return array Array of event objects
* @return false False on failure
*/
function getEventsForDay ($ical, $day, $month = null, $year = null) {
if (! $ical) return false;
$date_format = "Y-m-d h:i:s";
return $ical -> sortEventsWithOrder (
$ical -> eventsFromRange (
date ($date_format, mktime (0, 0, 0, $month, $day, $year)),
date ($date_format, mktime (23, 59, 59, $month, $day, $year)),
)
);
}
/**
* Wrapper for getEventsForDay.
* Returns all events from an ICal object for a specific date
*
* @param ICal $ical ICal object
* @param DateTime $date DateTime object
*
* @return array Array of event objects
* @return false False on failure
*/
function getEventsForDate ($ical, $date) {
return getEventsForDay (
$ical,
intval($date -> format ("d")),
intval($date -> format ("m")),
intval($date -> format ("Y"))
);
}
/**
* Get events from ICal object limited by a start date
* and amount to days forward from the start date
*
* @param ICal $ical ICal object
* @param DateTime $startDate Date to start from
* @param int $days Amount of days to get
*/
function getEventsFromRange ($ical, $startDate, $days) {
if (! $ical) return false;
return $ical -> sortEventsWithOrder (
$ical -> getEventsFromRange (
$startDate -> format ("Y-m-d H:i:s"),
$startDate -> modify ("+ {$days} days") -> format ("Y-m-d H:i:s")
)
);
}