[TikiWiki-commits] [Git][tikiwiki/tiki][30.x] [BP][NEW] Calendar: add ICS calendar import support

"Adrien Mbuya Maloba \(@adrienmaloba\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <6a2c462862f2a_381961945611@gitlab-sidekiq-low-urgency-cpu-bound-v2-5b88f8847b-9qs6s.mail>

Adrien Mbuya Maloba pushed to branch 30.x at Tiki Wiki CMS Groupware / Tiki


Commits:
cde0ccc3 by Adrien Mbuya Maloba at 2026-06-12T20:40:52+03:00
[BP][NEW] Calendar: add ICS calendar import support
---
* [NEW] Calendar: add ICS calendar import support
---
* [NEW] Calendar: add ICS calendar import support

See merge request tikiwiki/tiki!10449

See merge request tikiwiki/tiki!10504

- - - - -


3 changed files:

- lib/calendar/calendarlib.php
- templates/tiki-calendar_import.tpl
- tiki-calendar_import.php


Changes:

=====================================
lib/calendar/calendarlib.php
=====================================
@@ -1287,6 +1287,52 @@ class CalendarLib extends TikiLib
         return $nb;
     }
 
+    /**
+     * @param $fname
+     * @param $calendarId
+     * @return int
+     */
+    public function importICS($fname, $calendarId)
+    {
+        global $prefs, $user;
+
+        $calendarData = file_get_contents($fname);
+        if (empty($calendarData) || strpos($calendarData, 'BEGIN:VCALENDAR') === false) {
+            throw new Services_Exception(tr("The ICS file is empty or invalid"));
+        }
+
+        $vObject = \Sabre\VObject\Reader::read($calendarData);
+        $nb = 0;
+
+        foreach ($vObject->getComponents() as $component) {
+            if ($component->name !== 'VEVENT') {
+                continue;
+            }
+
+            // Ignore recurrence exceptions
+            if (isset($component->{'RECURRENCE-ID'})) {
+                continue;
+            }
+            $client = new \Tiki\SabreDav\CaldavClient();
+            $data = \Tiki\SabreDav\Utilities::getDenormalizedDataFromComponent($component);
+            $data['calendarId'] = $calendarId;
+            // If the event is recurrent
+            if (! empty($data['rec'])) {
+                $rec = $data['rec'];
+                $rec->updateDetails($data);
+                // Lang is required in CalRecurrence::isValid(), so set it here
+                $rec->setLang($data['lang'] ?? $prefs['language'] ?? 'en');
+                $rec->setUser($user); // Set the user
+                $client->saveRecurringCalendarObject($rec);
+            } else {
+                // Save no recurrent event
+                $client->saveCalendarObject($data);
+            }
+            $nb++;
+        }
+        return $nb;
+    }
+
     /**
      * Returns an array of a maximum of $maxrows upcoming (but possibly past) events in the given $order.
      * If $calendarId is set, events not in the specified calendars are filtered. $calendarId


=====================================
templates/tiki-calendar_import.tpl
=====================================
@@ -9,6 +9,10 @@
     {tr}Calendar has been updated{/tr}
 {/if}
 
+{if isset($error) and $error eq 'y'}
+    {tr}Invalid file format. Only CSV and ICS files are accepted.{/tr}
+{/if}
+
 <form method="post" action="tiki-calendar_import.php" enctype="multipart/form-data">
     <br>
     <div class="tiki-form-group row">
@@ -22,12 +26,21 @@
         </div>
     </div>
     <div class="tiki-form-group row">
-        <label class="col-sm-3 col-form-label">{tr}CSV File{/tr}
-            {capture name=help}{tr}Column names on the first line:{/tr}<br>name,description,start&nbsp;date,start&nbsp;time,end&nbsp;date,end&nbsp;time,status,lang,categoryId,locationId,priority,url,categoryId<br><i>{tr _0=subject _1=name}%0 column name can be used instead of %1{/tr}</i><br>{tr}Date format:{/tr} {tr}See:{/tr} http://php.net/strtotime{/capture}
-            <a title="{tr}Help{/tr}" {popup text=$smarty.capture.help|escape}>{icon name='help'}</a>
+        <label class="col-sm-3 col-form-label">{tr}CSV or ICS File{/tr}
+            {capture name=help}
+                <strong>{tr}CSV format{/tr}</strong><br>
+                {tr}Column names on the first line:{/tr}<br>
+                name,description,start&nbsp;date,start&nbsp;time,end&nbsp;date,end&nbsp;time,status,lang,categoryId,locationId,priority,url,categoryId<br>
+                <i>{tr _0=subject _1=name}%0 column name can be used instead of %1{/tr}</i><br>
+                {tr}Date format:{/tr} {tr}See:{/tr} http://php.net/strtotime
+                <br><br>
+                <strong>{tr}ICS format{/tr}</strong><br>
+                {tr}Standard iCalendar (.ics) files are supported, including recurring events.{/tr}
+            {/capture}
+            <a title="{tr}Help{/tr}" {popup text=$smarty.capture.help}>{icon name='help'}</a>
         </label>
         <div class="col-sm-7">
-            <input type="file" accept=".csv" name="fileCSV" size="50" class="form-control">
+            <input type="file" accept=".csv,.ics" name="fileImport" size="50" class="form-control">
         </div>
     </div>
     <div class="tiki-form-group row">


=====================================
tiki-calendar_import.php
=====================================
@@ -25,11 +25,23 @@ $calendarlib = TikiLib::lib('calendar');
 $access->check_feature('feature_calendar');
 $access->check_permission('tiki_p_admin_calendar');
 
-if (isset($_REQUEST["import"]) && isset($_REQUEST["calendarId"]) && isset($_FILES["fileCSV"])) {
-    if ($calendarlib->importCSV($_FILES["fileCSV"]["tmp_name"], $_REQUEST["calendarId"])) {
-        $smarty->assign('updated', "y");
+
+if (isset($_REQUEST["import"]) && isset($_REQUEST["calendarId"]) && isset($_FILES["fileImport"])) {
+    $fileExtension = strtolower(pathinfo($_FILES["fileImport"]["name"], PATHINFO_EXTENSION));
+    if (in_array($fileExtension, ['csv', 'ics'])) {
+        if ($fileExtension === 'csv') {
+            $result = $calendarlib->importCSV($_FILES["fileImport"]["tmp_name"], $_REQUEST["calendarId"]);
+        } else {
+            $result = $calendarlib->importICS($_FILES["fileImport"]["tmp_name"], $_REQUEST["calendarId"]);
+        }
+        if ($result) {
+            $smarty->assign('updated', 'y');
+        }
+    } else {
+        $smarty->assign('error', 'y');
     }
 }
+
 $calendars = $calendarlib->list_calendars(); // no check perm as p_admin only
 $smarty->assign_by_ref('calendars', $calendars['data']);
 



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/cde0ccc3258b9386ec373bafbc8bb260f0911ba2

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/cde0ccc3258b9386ec373bafbc8bb260f0911ba2
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.