summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeldakatze <coffee@zeldakatze.de>2025-08-17 23:21:48 +0200
committerzeldakatze <coffee@zeldakatze.de>2025-08-17 23:21:48 +0200
commit50a67a31aaa18ec96019379a489ec65d2d641162 (patch)
treebe5b005a5343660a609d1693451cdc41ff650ade
parente828b9c7dd11410d995aa88dcc2b22210f099cf4 (diff)
downloadinfoCalendar-50a67a31aaa18ec96019379a489ec65d2d641162.tar.gz
infoCalendar-50a67a31aaa18ec96019379a489ec65d2d641162.zip
add ical exports, fix event listing
-rwxr-xr-xEvent.php36
-rw-r--r--adminCalendars.php85
-rwxr-xr-xadminPanel.php5
-rwxr-xr-xcalenderRenderer.php6
-rw-r--r--icalExport.php140
-rw-r--r--infoCalendar.css15
-rwxr-xr-xinfoCalendar.php15
7 files changed, 298 insertions, 4 deletions
diff --git a/Event.php b/Event.php
new file mode 100755
index 0000000..5c89974
--- /dev/null
+++ b/Event.php
@@ -0,0 +1,36 @@
+<?php
+
+class Event {
+ public $id;
+ public $title;
+ public $visibleInCalendar;
+ public $postID;
+ public $creator;
+ public $creationDate;
+ public $location;
+ public $duration;
+ public $timestamp;
+
+
+ public function __construct() {
+
+ }
+
+ public function renderCalEntry() {
+
+ }
+}
+
+class RepeatingEvent extends Event {
+ public $repetitionType;
+ public $repetitionArgs;
+ public $startTime;
+ public $endTime;
+
+ /* Returns a list of single events
+ * that can then be easily displayed in the calendar
+ * */
+ public function toSingleEvents($start, $end) {
+
+ }
+}
diff --git a/adminCalendars.php b/adminCalendars.php
new file mode 100644
index 0000000..9baf259
--- /dev/null
+++ b/adminCalendars.php
@@ -0,0 +1,85 @@
+<?php
+
+function infocalendar_get_admin_calendar_html() {
+ global $wpdb;
+
+ if(isset($_POST['pwViewSet']) || isset($_POST['pwViewDel'])) {
+ if(!isset($_POST['pwViewID'])) {
+ print('<font color="red">Du musst Eine Ansicht angeben</font><br>');
+ } else if(isset($_POST['pwViewSet']) &&
+ (!isset($_POST['pwViewPw']) || $_POST['pwViewPw'] == '')) {
+ print('<font color="red">Du musst ein Passwort angeben</font><br>');
+ } else {
+ $viewID = (int) $_POST['pwViewID'];
+ $pw = null;
+ if(isset($_POST['pwViewSet'])) {
+ $pw = password_hash($_POST['pwViewPw'], PASSWORD_BCRYPT);
+ }
+
+ $wpdb->query(
+ $wpdb->prepare('UPDATE `wp_infocalendar_calendar` '.
+ 'SET `password` = %s WHERE id = %d', $pw, $viewID));
+
+ ?><p><font color='green'>Passwort geändert!</font></p><?php
+ }
+ }
+ ?>
+
+ <h1>Kalenderansichten</h1>
+ <table border='1' cellspacing='0' cellpadding='5' id='infocal_views'>
+ <tr>
+ <th>ID</th>
+ <th>Name</th>
+ <th>Passwort gesetzt</th>
+ <th>iCal</th>
+ </tr>
+
+ <?php
+ $viewList = $wpdb->get_results("SELECT * FROM
+ {$wpdb->prefix}infocalendar_calendar", 'ARRAY_A');
+
+ foreach($viewList AS $view) {
+ $pwSet = 'Nicht gesetzt';
+ if($view['password'] != NULL)
+ $pwSet = 'Gesetzt';
+
+ $icalUrl = get_site_url().'?rest_route=/infocalendar/calendar/'.
+ $view['name'];
+
+ ?>
+ <tr>
+ <td><?php echo $view['id']; ?></td>
+ <td><?php echo $view['name']; ?></td>
+ <td><?php echo $pwSet; ?></td>
+ <td>
+ <?php echo '<a href="'.$icalUrl.'">'.$icalUrl.'</a>'; ?>
+ </td>
+ </tr>
+ <?php
+ }
+ ?>
+ </table>
+ <h2>Passwort ändern/Löschen</h2>
+
+ <form method='POST'>
+ <label for='pwViewID'>ID:</label>
+ <input type='number' name='pwViewID' id='pwViewID'><br>
+ <label for='pwViewPw'>Passwort:</label>
+ <input type='text' name='pwViewPw' id='pwViewPw'><br><br>
+ <input type='submit' name='pwViewSet' value='Passwort setzen' bgcolor='green'>
+ <br><br>
+ <input type='submit' name='pwViewDel' value='Passwort löschen' bgcolor='red'>
+ <?php
+
+}
+
+function infocalendar_add_view_admin_panel() {
+ add_submenu_page(
+ 'infoCalendar',
+ 'Kaelenderansichten',
+ 'Ansichten',
+ 'publish_posts',
+ 'infoCalendarViews',
+ 'infocalendar_get_admin_calendar_html'
+ );
+}
diff --git a/adminPanel.php b/adminPanel.php
index 0c48886..a45b75c 100755
--- a/adminPanel.php
+++ b/adminPanel.php
@@ -23,6 +23,8 @@ function infocalendar_options_page() {
'infoCalendar',
'infocalendar_options_page_html'
);
+
+ infocalendar_add_view_admin_panel();
}
function get_username_from_id($id) {
@@ -345,7 +347,8 @@ function infocalendar_options_page_html() {
WHERE event.id = eventCalendarMap.eventID AND
calendar.id = eventCalendarMap.calendarID AND
repeatingEvent=0 AND icalImported=0 AND
- (startDate > NOW() OR endDate > NOW())", 'ARRAY_A');
+ (startDate > NOW() OR endDate > NOW()) GROUP BY event.id",
+ 'ARRAY_A');
foreach($result as $row) {
/* get the creator's name */
diff --git a/calenderRenderer.php b/calenderRenderer.php
index 5cd4bee..54fc237 100755
--- a/calenderRenderer.php
+++ b/calenderRenderer.php
@@ -255,7 +255,11 @@ function infoCalendar_printEvent($event, $curDt) {
?>
<span class='infocal_event'>
<h2><?php echo $event->title; ?></h2>
- <small style='float: right;'># <?php echo $event->id; ?></small>
+
+ <?php
+ /*<small style='float: right;'># <?php echo $event->id;?></small>*/
+ ?>
+
<span class='infocal_showmore'>
<p><?php echo $event->timeToString($curDt); ?></p>
<p><?php echo $event->location ?></p>
diff --git a/icalExport.php b/icalExport.php
new file mode 100644
index 0000000..1e90c19
--- /dev/null
+++ b/icalExport.php
@@ -0,0 +1,140 @@
+<?php
+
+define("ICAL_DATE_FORMAT", "Ymd\THis");
+
+class infocalendar_CalendarView {
+ public $id;
+ public $name;
+ public $password;
+
+ public function __construct($id, $name, $password) {
+ $this->id = $id;
+ $this->name = $name;
+ $this->password = $password;
+ }
+}
+
+/** creates a calendarView object for the entry with $name. Returns
+ * null if not found */
+function infocalendar_getViewByName($name) {
+ global $wpdb;
+ $result = $wpdb->get_results(
+ $wpdb->prepare("SELECT * FROM {$wpdb->prefix}infocalendar_calendar
+ WHERE name = %s", $name),
+ 'ARRAY_A');
+
+ /* if nothing has been found, return */
+ if(count($result) != 1)
+ return 0;
+
+ return new infocalendar_CalendarView($result[0]['id'], $result[0]['name'],
+ $result[0]['password']);
+}
+
+function infocalendar_sendAuthHeaderAndExit() {
+ header('WWW-Authenticate: Basic realm="My Realm"');
+ header('HTTP/1.0 401 Unauthorized');
+ echo 'Invalid credentials';
+ exit;
+}
+
+function infocalendar_beAuthorizedOrBust($view) {
+ if($view->password != null) {
+ if (!isset($_SERVER['PHP_AUTH_USER'])) {
+ infocalendar_sendAuthHeaderAndExit();
+ } else if(password_verify($_SERVER['PHP_AUTH_PW'], $view->password)) {
+ return;
+ } else {
+ infocalendar_sendAuthHeaderAndExit();
+ die("Should not be here!");
+ }
+ }
+}
+
+function infocalendar_printICalTextFromView($view) {
+ global $wpdb;
+
+ /* print the calendar */
+?>
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//zeldakatze.de//InfoCalendar 1.1//DD
+<?php
+
+ /* print singular events */
+ $result = $wpdb->get_results($wpdb->prepare("SELECT
+ event.id, title, location, startDate, endDate, creator, creationDate,
+ repetitionOption, repeatEndTime,
+ postID, uid, repeatingEvent, icalImported
+ FROM {$wpdb->prefix}infocalendar_event AS event
+
+ LEFT JOIN {$wpdb->prefix}infocalendar_eventCalendarMap AS eventCalendarMap
+ ON event.id = eventCalendarMap.eventID
+
+ LEFT JOIN {$wpdb->prefix}infocalendar_calendar AS calendar
+ ON calendar.id = eventCalendarMap.calendarID
+
+ LEFT JOIN {$wpdb->prefix}infocalendar_repeatingEvent AS repeatingEvent
+ ON repeatingEvent.id = event.id
+
+ WHERE
+ calendar.name = %s
+ ",
+ $view->name), 'ARRAY_A');
+ foreach($result as $row) {
+ print("BEGIN:VEVENT\n");
+ print("SUMMARY:".$row['title']."\n");
+ print("UID:".sha1($row['id'].$row['title'].$row['startDate'])."\n");
+ print("DTSTART:".
+ date_format(date_create($row['startDate']), ICAL_DATE_FORMAT)."\n");
+ print("DTEND:".
+ date_format(date_create($row['endDate']), ICAL_DATE_FORMAT)."\n");
+ print("DTSTAMP:".
+ date_format(date_create($row['creationDate']), ICAL_DATE_FORMAT)
+ ."\n");
+ print("LOCATION:".$row['location']."\n");
+ if($row['postID'] != 0) {
+ print("URL:".get_permalink($row['postID'])."\n");
+ }
+
+ /* print the repeat information */
+ if($row['repeatingEvent']) {
+ $frequency = 'DAILY';
+ print("RRULE:FREQ=".$frequency.
+ ";INTERVAL=".$row['repetitionOption'].
+ ";UNTIL=".
+ date_format(date_create($row['repeatEndTime']),ICAL_DATE_FORMAT).
+ "\n");
+ }
+
+ print("END:VEVENT\n");
+ }
+
+ /* close the calendar */
+ ?>
+END:VCALENDAR
+ <?php
+}
+
+function doICalExport(WP_REST_Request $request) {
+ global $wpdb;
+
+ /* get the view information */
+ // TODO sanitization!?
+ $calendarView = infocalendar_getViewByName($request['slug']);
+ if($calendarView == null)
+ die("unknown view");
+
+ /* check authentication */
+ infocalendar_beAuthorizedOrBust($calendarView);
+
+ /* print the plaintext header */
+ header("Content-type: text/plain");
+
+ infocalendar_printICalTextFromView($calendarView);
+
+ /* */
+
+}
+
+?>
diff --git a/infoCalendar.css b/infoCalendar.css
index 33ff39a..e2177c3 100644
--- a/infoCalendar.css
+++ b/infoCalendar.css
@@ -69,10 +69,25 @@
}
+#infocal_views {
+ background: red;
+}
+
#infocal_list .infocal_event {
margin: 5px;
}
+#infocal_views tr th {
+ background: gray;
+ color: light-gray;
+}
+
+#infocal_views a {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: scroll;
+}
+
@media screen and (max-width: 512px) {
}
diff --git a/infoCalendar.php b/infoCalendar.php
index b53d6af..9709d38 100755
--- a/infoCalendar.php
+++ b/infoCalendar.php
@@ -1,9 +1,9 @@
<?php
/**
* Plugin Name: infoCalendar
-* Plugin URI: https://zeldakatze.de
+* Plugin URI: https://cgit.zeldakatze.de/infoCalendar/
* Description: the infoCalendar Plugin
-* Version: 0.1
+* Version: 0.2.2
* Author: zeldakatze
* Author URI: http://zeldakatze.de
**/
@@ -11,6 +11,8 @@
include 'common.php';
include 'calenderRenderer.php';
include 'adminPanel.php';
+include 'adminCalendars.php';
+include 'icalExport.php';
define('INFOCALENDAR_REPEAT_DAILY', 0);
define('INFOCALENDAR_REPEAT_MONTLY', 1);
@@ -90,3 +92,12 @@ function infocalendar_enqueue() {
add_action( 'init', 'infocalendar_init' );
add_action( 'wp_enqueue_scripts', 'infocalendar_enqueue');
+
+add_action( 'rest_api_init', function () {
+ register_rest_route( 'infocalendar', '/calendar/(?P<slug>\w+)', array(
+ 'methods' => 'GET',
+ 'callback' => 'doICalExport',
+ 'permission_callback' => '__return_true',
+ ) );
+} );
+