From 302f50b16a6204fb261f305f071d69197c010d10 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Sat, 8 Dec 2012 00:53:21 +0000 Subject: [PATCH] CalendarexporterModule: - fixed ExtJS Problem in chrome - integrate servertimezone in ics file - ics exporter nearly finished - loading animation --- js/dialogs/ImportPanel.js | 47 ++++++++-- php/module.calendarexporter.php | 146 ++++++++++++++++++++++++++++++-- 2 files changed, 179 insertions(+), 14 deletions(-) diff --git a/js/dialogs/ImportPanel.js b/js/dialogs/ImportPanel.js index 0d6318a..1cc73aa 100644 --- a/js/dialogs/ImportPanel.js +++ b/js/dialogs/ImportPanel.js @@ -4,7 +4,7 @@ Ext.namespace("Zarafa.plugins.calendarimporter.dialogs"); * @class Zarafa.plugins.calendarimporter.dialogs.ImportPanel * @extends Ext.form.FormPanel */ -Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPanel, { +Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { /* store the imported timezone here... */ timezone: null, @@ -296,7 +296,6 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPa close: function () { this.addFormPanel.getForm().reset(); - this.getForm().reset(); this.dialog.close() }, @@ -373,8 +372,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPa icon : Ext.MessageBox.ERROR, buttons : Ext.MessageBox.OK }); - } else { - + } else { var calendarFolder = container.getHierarchyStore().getDefaultFolder('calendar'); if(calValue != "calendar") { var subFolders = calendarFolder.getChildren(); @@ -388,6 +386,36 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPa } } } + + Zarafa.common.dialogs.MessageBox.show({ + title: 'Please wait', + msg: 'Generating ical file...', + progressText: 'Exporting...', + width:300, + progress:true, + closable:false + }); + + // progress bar... ;) + var updateProgressBar = function(v){ + return function(){ + if(v == 100){ + if(Zarafa.common.dialogs.MessageBox.isVisible()) { + updateTimer(); + } + }else{ + Zarafa.common.dialogs.MessageBox.updateProgress(v/100, 'Exporting...'); + } + }; + }; + + var updateTimer = function() { + for(var i = 1; i < 101; i++){ + setTimeout(updateProgressBar(i), 20*i); + } + }; + + updateTimer(); // call export function here! var responseHandler = new Zarafa.plugins.calendarimporter.data.ResponseHandler({ @@ -437,9 +465,10 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPa }, responseHandler ); - container.getNotifier().notify('info', 'Exported', 'Exported ' + response.item.length + ' entries'); + container.getNotifier().notify('info', 'Exported', 'Found ' + response.item.length + ' entries to export.'); } else { container.getNotifier().notify('info', 'Export Failed', 'There were no items to export!'); + Zarafa.common.dialogs.MessageBox.hide(); } this.dialog.close(); }, @@ -451,11 +480,13 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.form.FormPa */ downLoadICS : function(response) { - if(response.status === true) { - document.location.href = 'plugins/calendarimporter/php/download.php?fileid='+response.fileid+'&basedir='+response.basedir+'&secid='+response.secid+'&realname='+response.realname; + Zarafa.common.dialogs.MessageBox.hide(); + if(response.status === true) { + // needs to be window.open, document.location.href kills the extjs response handler... + window.open('plugins/calendarimporter/php/download.php?fileid='+response.fileid+'&basedir='+response.basedir+'&secid='+response.secid+'&realname='+response.realname,"Download"); } else { container.getNotifier().notify('error', 'Export Failed', 'ICal File creation failed!'); - } + } }, importCheckedEvents: function () { diff --git a/php/module.calendarexporter.php b/php/module.calendarexporter.php index 55c7a3e..234ec5c 100644 --- a/php/module.calendarexporter.php +++ b/php/module.calendarexporter.php @@ -1,4 +1,4 @@ - $event["startdate"], - "DTEND" => $event["duedate"], - "DTSTAMP" => $event["creation_time"], - "DESCRIPTION" => "nothing...", + "UID" => $this->randomstring(10) . "-" . $this->randomstring(5) . "-ics@zarafa-export-plugin", // generate uid + "DTSTART" => $this->getIcalDate($event["commonstart"]) . "Z", // this times are utc! + "DTEND" => $this->getIcalDate($event["commonend"]) . "Z", + "DTSTAMP" => $this->getIcalDate($event["creation_time"]) . "Z", + "DESCRIPTION" => str_replace("\n", "\\n",$event["description"]), "LOCATION" => $event["location"], "SUMMARY" => $event["subject"] ); @@ -134,6 +142,131 @@ class CalendarexporterModule extends Module { fwrite($fh, $end); } + private function loadEventDescription($event) { + $entryid = $this->getActionEntryID($event); + $store = $this->getActionStore($event); + + $basedate = null; + + $properties = $GLOBALS['properties']->getAppointmentProperties(); + $plaintext = true; + + $data = array(); + + if($store && $entryid) { + $message = $GLOBALS['operations']->openMessage($store, $entryid); + + + // add all standard properties from the series/normal message + $data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $properties, (isset($plaintext) && $plaintext)); + + // if appointment is recurring then only we should get properties of occurence if basedate is supplied + if($data['item']['props']['recurring'] === true) { + if(isset($basedate) && $basedate) { + $recur = new Recurrence($store, $message); + + $exceptionatt = $recur->getExceptionAttachment($basedate); + + // Single occurences are never recurring + $data['item']['props']['recurring'] = false; + + if($exceptionatt) { + // Existing exception (open existing item, which includes basedate) + $exceptionattProps = mapi_getprops($exceptionatt, array(PR_ATTACH_NUM)); + $exception = mapi_attach_openobj($exceptionatt, 0); + + // overwrite properties with the ones from the exception + $exceptionProps = $GLOBALS['operations']->getMessageProps($store, $exception, $properties, (isset($plaintext) && $plaintext)); + + /** + * If recurring item has set reminder to true then + * all occurrences before the 'flagdueby' value(of recurring item) + * should not show that reminder is set. + */ + if (isset($exceptionProps['props']['reminder']) && $data['item']['props']['reminder'] == true) { + $flagDueByDay = $recur->dayStartOf($data['item']['props']['flagdueby']); + + if ($flagDueByDay > $basedate) { + $exceptionProps['props']['reminder'] = false; + } + } + + // The properties must be merged, if the recipients or attachments are present in the exception + // then that list should be used. Otherwise the list from the series must be applied (this + // corresponds with OL2007). + // @FIXME getMessageProps should not return empty string if exception doesn't contain body + // by this change we can handle a situation where user has set empty string in the body explicitly + if (!empty($exceptionProps['props']['body']) || !empty($exceptionProps['props']['html_body'])) { + if(!empty($exceptionProps['props']['body'])) { + $data['item']['props']['body'] = $exceptionProps['props']['body']; + } + + if(!empty($exceptionProps['props']['html_body'])) { + $data['item']['props']['html_body'] = $exceptionProps['props']['html_body']; + } + + $data['item']['props']['isHTML'] = $exceptionProps['props']['isHTML']; + } + // remove properties from $exceptionProps so array_merge will not overwrite it + unset($exceptionProps['props']['html_body']); + unset($exceptionProps['props']['body']); + unset($exceptionProps['props']['isHTML']); + + $data['item']['props'] = array_merge($data['item']['props'], $exceptionProps['props']); + if (isset($exceptionProps['recipients'])) { + $data['item']['recipients'] = $exceptionProps['recipients']; + } + + if (isset($exceptionProps['attachments'])) { + $data['item']['attachments'] = $exceptionProps['attachments']; + } + + // Make sure we are using the passed basedate and not something wrong in the opened item + $data['item']['props']['basedate'] = $basedate; + } else { + // opening an occurence of a recurring series (same as normal open, but add basedate, startdate and enddate) + $data['item']['props']['basedate'] = $basedate; + $data['item']['props']['startdate'] = $recur->getOccurrenceStart($basedate); + $data['item']['props']['duedate'] = $recur->getOccurrenceEnd($basedate); + $data['item']['props']['commonstart'] = $data['item']['props']['startdate']; + $data['item']['props']['commonend'] = $data['item']['props']['duedate']; + unset($data['item']['props']['reminder_time']); + + /** + * If recurring item has set reminder to true then + * all occurrences before the 'flagdueby' value(of recurring item) + * should not show that reminder is set. + */ + if (isset($exceptionProps['props']['reminder']) && $data['item']['props']['reminder'] == true) { + $flagDueByDay = $recur->dayStartOf($data['item']['props']['flagdueby']); + + if ($flagDueByDay > $basedate) { + $exceptionProps['props']['reminder'] = false; + } + } + } + } else { + // Opening a recurring series, get the recurrence information + $recur = new Recurrence($store, $message); + $recurpattern = $recur->getRecurrence(); + $tz = $recur->tz; // no function to do this at the moment + + // Add the recurrence pattern to the data + if(isset($recurpattern) && is_array($recurpattern)) { + $data['item']['props'] += $recurpattern; + } + + // Add the timezone information to the data + if(isset($tz) && is_array($tz)) { + $data['item']['props'] += $tz; + } + } + } + } + + return $data['item']['props']['body']; + } + private function exportCalendar($actionType, $actionData) { $secid = $this->randomstring(); $this->createSecIDFile($secid); @@ -145,6 +278,7 @@ class CalendarexporterModule extends Module { $this->writeICSHead($fh, $actionData["calendar"]); foreach($actionData["data"]["item"] as $event) { + $event["props"]["description"] = $this->loadEventDescription($event); $this->writeEvent($fh, $event["props"]); }