diff options
author | zeldakatze <coffee@zeldakatze.de> | 2025-08-17 23:21:48 +0200 |
---|---|---|
committer | zeldakatze <coffee@zeldakatze.de> | 2025-08-17 23:21:48 +0200 |
commit | 50a67a31aaa18ec96019379a489ec65d2d641162 (patch) | |
tree | be5b005a5343660a609d1693451cdc41ff650ade | |
parent | e828b9c7dd11410d995aa88dcc2b22210f099cf4 (diff) | |
download | infoCalendar-50a67a31aaa18ec96019379a489ec65d2d641162.tar.gz infoCalendar-50a67a31aaa18ec96019379a489ec65d2d641162.zip |
add ical exports, fix event listing
-rwxr-xr-x | Event.php | 36 | ||||
-rw-r--r-- | adminCalendars.php | 85 | ||||
-rwxr-xr-x | adminPanel.php | 5 | ||||
-rwxr-xr-x | calenderRenderer.php | 6 | ||||
-rw-r--r-- | icalExport.php | 140 | ||||
-rw-r--r-- | infoCalendar.css | 15 | ||||
-rwxr-xr-x | infoCalendar.php | 15 |
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', + ) ); +} ); + |