diff --git a/infolog/inc/class.infolog_groupdav.inc.php b/infolog/inc/class.infolog_groupdav.inc.php
index 36eed70e4e..f6a11166c7 100644
--- a/infolog/inc/class.infolog_groupdav.inc.php
+++ b/infolog/inc/class.infolog_groupdav.inc.php
@@ -90,10 +90,9 @@ class infolog_groupdav extends groupdav_handler
{
return $task;
}
- include_once(EGW_INCLUDE_ROOT.'/icalsrv/inc/class.boinfolog_vtodos.inc.php');
- $handler =& new boinfolog_vtodos($this->bo);
- $vtodo = $handler->export_vtodo($task,UMM_UID2UID);
- $options['data'] = $handler->render_velt2vcal($vtodo);
+ include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.vcalinfolog.inc.php');
+ $handler = new vcalinfolog();
+ $options['data'] = $handler->exportVTODO($id,'2.0',false,false); // keep UID the client set and no extra charset attributes
$options['mimetype'] = 'text/calendar; charset=utf-8';
header('Content-Encoding: identity');
header('ETag: '.$this->get_etag($task));
@@ -115,13 +114,12 @@ class infolog_groupdav extends groupdav_handler
{
return $ok;
}
- include_once(EGW_INCLUDE_ROOT.'/icalsrv/inc/class.boinfolog_vtodos.inc.php');
- $handler =& new boinfolog_vtodos($this->bo);
- $vcalelm =& $handler->parse_vcal2velt($options['content']);
- if (!($info_id = $handler->import_vtodo($vcalelm, $uid_mapping_import=UMM_UID2UID, $reimport_missing_events=false, $id)) > 0)
+ include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.vcalinfolog.inc.php');
+ $handler = new vcalinfolog();
+ if (!($info_id = $handler->importVCal($options['content'],is_numeric($id) ? $id : -1)))
{
if ($this->debug) error_log(__METHOD__."(,$id) import_vtodo($options[content]) returned false");
- return false; // something went wrong ...
+ return '403 Forbidden';
}
header('ETag: '.$this->get_etag($info_id));
if (is_null($ok) || $id != $info_id)
diff --git a/infolog/inc/class.vcalinfolog.inc.php b/infolog/inc/class.vcalinfolog.inc.php
index df66f462a3..73ba0cb560 100644
--- a/infolog/inc/class.vcalinfolog.inc.php
+++ b/infolog/inc/class.vcalinfolog.inc.php
@@ -10,346 +10,362 @@
* @version $Id$
*/
- require_once EGW_SERVER_ROOT.'/infolog/inc/class.boinfolog.inc.php';
- require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php';
+require_once EGW_SERVER_ROOT.'/infolog/inc/class.boinfolog.inc.php';
+require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php';
- class vcalinfolog extends boinfolog
+class vcalinfolog extends boinfolog
+{
+ var $egw_priority2vcal_priority = array(
+ 0 => 3,
+ 1 => 2,
+ 2 => 1,
+ 3 => 1,
+ );
+
+ var $vcal_priority2egw_priority = array(
+ 1 => 2,
+ 2 => 1,
+ 3 => 0,
+ );
+
+ /**
+ * Exports one InfoLog tast to an iCalendar VTODO
+ *
+ * @param int $_taskID info_id
+ * @param string $version='2.0' could be '1.0' too
+ * @param boolean $force_own_uid=true ignore the stored and maybe from the client transfered uid and generate a new one
+ * RalfBecker: GroupDAV/CalDAV requires to switch that non RFC conform behavior off, dont know if SyncML still needs it
+ * @param boolean $extra_charset_attribute=true GroupDAV/CalDAV dont need the charset attribute and some clients have problems with it
+ * @return string/boolean string with vCal or false on error (eg. no permission to read the event)
+ */
+ function exportVTODO($_taskID, $_version='2.0',$force_own_uid=true,$extra_charset_attribute=true)
{
- var $egw_priority2vcal_priority = array(
- 0 => 3,
- 1 => 2,
- 2 => 1,
- 3 => 1,
- );
+ $taskData = $this->read($_taskID);
- var $vcal_priority2egw_priority = array(
- 1 => 2,
- 2 => 1,
- 3 => 0,
- );
+ $taskData = $GLOBALS['egw']->translation->convert($taskData, $GLOBALS['egw']->translation->charset(), 'UTF-8');
- function exportVTODO($_taskID, $_version)
+ $taskGUID = $GLOBALS['egw']->common->generate_uid('infolog_task',$_taskID);
+
+ $vcal = &new Horde_iCalendar;
+ $vcal->setAttribute('VERSION',$_version);
+ $vcal->setAttribute('METHOD','PUBLISH');
+
+ $vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
+
+ // set fields that may contain non-ascii chars and encode them if necessary
+ foreach(array(
+ 'SUMMARY' => $taskData['info_subject'],
+ 'DESCRIPTION' => $taskData['info_des'],
+ 'LOCATION' => $taskData['info_location'],
+ ) as $field => $value)
{
- $taskData = $this->read($_taskID);
-
- $taskData = $GLOBALS['egw']->translation->convert($taskData, $GLOBALS['egw']->translation->charset(), 'UTF-8');
-
- //_debug_array($taskData);
-
- $taskGUID = $GLOBALS['egw']->common->generate_uid('infolog_task',$_taskID);
- #print "
";
- #print $GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add');
- #print "
";
-
- $vcal = &new Horde_iCalendar;
- $vcal->setAttribute('VERSION',$_version);
- $vcal->setAttribute('METHOD','PUBLISH');
-
- $vevent = Horde_iCalendar::newComponent('VTODO',$vcal);
-
+ $vevent->setAttribute($field,$value);
$options = array();
-
- $vevent->setAttribute('SUMMARY',$taskData['info_subject']);
- $vevent->setAttribute('DESCRIPTION',$taskData['info_des']);
- $vevent->setAttribute('LOCATION',$taskData['info_location']);
- if($taskData['info_startdate'])
- $vevent->setAttribute('DTSTART',$taskData['info_startdate']);
- if($taskData['info_enddate'])
- $vevent->setAttribute('DUE',$taskData['info_enddate']);
- if($taskData['info_datecompleted'])
- $vevent->setAttribute('COMPLETED',$taskData['info_datecompleted']);
- $vevent->setAttribute('DTSTAMP',time());
- $vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
- $vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
- $vevent->setAttribute('UID',$taskGUID);
- $vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
- $vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
- // we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
- $vevent->setAttribute('X-INFOLOG-STATUS',$taskData['info_status']);
- $vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
-
- if (!empty($taskData['info_cat']))
+ if(preg_match('/([\000-\012\015\016\020-\037\075])/',$value))
{
- $cats = $this->get_categories(array($taskData['info_cat']));
- $vevent->setAttribute('CATEGORIES', $cats[0]);
+ $options['ENCODING'] = 'QUOTED-PRINTABLE';
}
-
- #$vevent->setAttribute('TRANSP','OPAQUE');
- # status
- # ATTENDEE
-
- $options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
- $vevent->setParameter('SUMMARY', $options);
- $vevent->setParameter('DESCRIPTION', $options);
-
- $vcal->addComponent($vevent);
-
- #print "
";
- #print $vcal->exportvCalendar();
- #print "
";
-
- return $vcal->exportvCalendar();
- }
-
- function importVTODO(&$_vcalData, $_taskID=-1)
- {
- if(!$taskData = $this->vtodotoegw($_vcalData)) {
- return false;
- }
-
- if($_taskID > 0) {
- $taskData['info_id'] = $_taskID;
- }
-
- // we suppose that a not set status in a vtodo means that the task did not started yet
- if(empty($taskData['info_status'])) {
- $taskData['info_status'] = 'not-started';
- }
-
- #_debug_array($taskData);exit;
- return $this->write($taskData);
- }
-
- function searchVTODO($_vcalData)
- {
- if(!$egwData = $this->vtodotoegw($_vcalData)) {
- return false;
- }
-
- #unset($egwData['info_priority']);
-
- $filter = array('col_filter' => $egwData);
- if($foundItems = $this->search($filter)) {
- if(count($foundItems) > 0) {
- $itemIDs = array_keys($foundItems);
- return $itemIDs[0];
- }
- }
-
- return false;
- }
-
- function vtodotoegw($_vcalData)
- {
- $vcal = &new Horde_iCalendar;
- if(!$vcal->parsevCalendar($_vcalData)) {
- return FALSE;
- }
-
- $components = $vcal->getComponents();
-
- if(count($components) > 0)
+ if($extra_charset_attribute && preg_match('/([\177-\377])/',$value))
{
- $component = $components[0];
- if(is_a($component, 'Horde_iCalendar_vtodo'))
- {
- if($_taskID>0)
- $taskData['info_id'] = $_taskID;
-
- foreach($component->_attributes as $attributes)
- {
- #print $attributes['name'].' - '.$attributes['value'].'
';
- switch($attributes['name'])
- {
- case 'CLASS':
- $taskData['info_access'] = strtolower($attributes['value']);
- break;
- case 'DESCRIPTION':
- $taskData['info_des'] = $attributes['value'];
- break;
- case 'LOCATION':
- $taskData['info_location'] = $attributes['value'];
- break;
- case 'DUE':
- $taskData['info_enddate'] = $attributes['value'];
- break;
- case 'COMPLETED':
- $taskData['info_datecompleted'] = $attributes['value'];
- break;
- case 'DTSTART':
- $taskData['info_startdate'] = $attributes['value'];
- break;
- case 'PRIORITY':
- if (1 <= $attributes['value'] && $attributes['value'] <= 3)
- {
- $taskData['info_priority'] = $this->vcal_priority2egw_priority[$attributes['value']];
- }
- else
- {
- $taskData['info_priority'] = 1; // default = normal
- }
- break;
- case 'STATUS':
- // check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
- foreach($component->_attributes as $attr)
- {
- if ($attr['name'] == 'X-INFOLOG-STATUS') break;
- }
- $taskData['info_status'] = $this->vtodo2status($attributes['value'],
- $attr['name'] == 'X-INFOLOG-STATUS' ? $attr['value'] : null);
- break;
- case 'SUMMARY':
- $taskData['info_subject'] = $attributes['value'];
- break;
-
- case 'CATEGORIES':
- {
- $cats = $this->find_or_add_categories(explode(',', $attributes['value']));
- $taskData['info_cat'] = $cats[0];
- }
- break;
- }
- }
- # the horde ical class does already convert in parsevCalendar
- # do NOT convert here
- #$taskData = $GLOBALS['egw']->translation->convert($taskData, 'UTF-8');
-
- return $taskData;
- }
+ $options['CHARSET'] = 'UTF-8';
}
- return FALSE;
+ if ($options) $vevent->setParameter($field, $options);
}
+ if($taskData['info_startdate'])
+ $vevent->setAttribute('DTSTART',$taskData['info_startdate']);
+ if($taskData['info_enddate'])
+ $vevent->setAttribute('DUE',$taskData['info_enddate']);
+ if($taskData['info_datecompleted'])
+ $vevent->setAttribute('COMPLETED',$taskData['info_datecompleted']);
+ $vevent->setAttribute('DTSTAMP',time());
+ $vevent->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
+ $vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
+ $vevent->setAttribute('UID',$force_own_uid ? $taskGUID : $taskData['info_uid']);
+ $vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
+ $vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
+ // we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
+ $vevent->setAttribute('X-INFOLOG-STATUS',$taskData['info_status']);
+ $vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
- function exportVNOTE($_noteID, $_type)
+ if (!empty($taskData['info_cat']))
{
- $note = $this->read($_noteID);
- $note = $GLOBALS['egw']->translation->convert($note, $GLOBALS['egw']->translation->charset(), 'UTF-8');
-
- switch($_type)
- {
- case 'text/plain':
- $txt = $note['info_subject']."\n\n".$note['info_des'];
- return $txt;
- break;
-
- case 'text/x-vnote':
- $noteGUID = $GLOBALS['egw']->common->generate_uid('infolog_note',$_noteID);
- $vnote = &new Horde_iCalendar_vnote();
- $vNote->setAttribute('VERSION', '1.1');
- $vnote->setAttribute('SUMMARY',$note['info_subject']);
- $vnote->setAttribute('BODY',$note['info_des']);
- if($note['info_startdate'])
- $vnote->setAttribute('DCREATED',$note['info_startdate']);
- $vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
- $vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
- if (!empty($note['info_cat']))
- {
- $cats = $this->get_categories(array($note['info_cat']));
- $vnote->setAttribute('CATEGORIES', $cats[0]);
- }
-
- #$vnote->setAttribute('UID',$noteGUID);
- #$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
-
- #$options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
- #$vnote->setParameter('SUMMARY', $options);
- #$vnote->setParameter('DESCRIPTION', $options);
-
- return $vnote->exportvCalendar();
- break;
- }
- return false;
+ $cats = $this->get_categories(array($taskData['info_cat']));
+ $vevent->setAttribute('CATEGORIES', $cats[0]);
}
-
- function importVNOTE(&$_vcalData, $_type, $_noteID = -1)
- {
- if(!$note = $this->vnotetoegw($_vcalData, $_type))
- {
- return false;
- }
-
- if($_noteID > 0)
- {
- $note['info_id'] = $_noteID;
- }
+ $vcal->addComponent($vevent);
- if(empty($note['info_status'])) {
- $note['info_status'] = 'done';
- }
-
- #_debug_array($taskData);exit;
- return $this->write($note);
- }
-
- function searchVNOTE($_vcalData, $_type)
- {
- if(!$note = $this->vnotetoegw($_vcalData)) {
- return false;
- }
-
- $filter = array('col_filter' => $egwData);
- if($foundItems = $this->search($filter)) {
- if(count($foundItems) > 0) {
- $itemIDs = array_keys($foundItems);
- return $itemIDs[0];
- }
- }
-
- return false;
- }
-
- function vnotetoegw($_data, $_type)
- {
- switch($_type)
- {
- case 'text/plain':
- $note = array();
- $note['info_type'] = 'note';
- $botranslation =& CreateObject('phpgwapi.translation');
- $txt = $botranslation->convert($_data, 'utf-8');
- $txt = str_replace("\r\n", "\n", $txt);
-
- if (preg_match("/^(^\n)\n\n(.*)$/", $txt, $match))
- {
- $note['info_subject'] = $match[0];
- $note['info_des'] = $match[1];
- }
- else
- {
- $note['info_des'] = $txt;
- }
-
- return $note;
- break;
-
- case 'text/x-vnote':
- $vnote = &new Horde_iCalendar;
- if (!$vcal->parsevCalendar($_data))
- {
- return FALSE;
- }
- $components = $vnote->getComponent();
- if(count($components) > 0)
- {
- $component = $components[0];
- if(is_a($component, 'Horde_iCalendar_vnote'))
- {
- $note = array();
- $note['info_type'] = 'note';
-
- foreach($component->_attributes as $attribute)
- {
- switch ($attribute['name'])
- {
- case 'BODY':
- $note['info_des'] = $attribute['value'];
- break;
- case 'SUMMARY':
- $note['info_subject'] = $attribute['value'];
- break;
- case 'CATEGORIES':
- {
- $cats = $this->find_or_add_categories(explode(',', $attribute['value']));
- $note['info_cat'] = $cats[0];
- }
- break;
- }
- }
- }
- return $note;
- }
- }
- return FALSE;
- }
+ return $vcal->exportvCalendar();
}
+ /**
+ * Import a VTODO component of an iCal
+ *
+ * @param string $_vcalData
+ * @param int $_taskID=-1 info_id, default -1 = new entry
+ * @return int|boolean integer info_id or false on error
+ */
+ function importVTODO(&$_vcalData, $_taskID=-1)
+ {
+ if(!$taskData = $this->vtodotoegw($_vcalData,$_taskID))
+ {
+ return false;
+ }
+ // we suppose that a not set status in a vtodo means that the task did not started yet
+ if(empty($taskData['info_status']))
+ {
+ $taskData['info_status'] = 'not-started';
+ }
+ return $this->write($taskData);
+ }
+
+ function searchVTODO($_vcalData)
+ {
+ if(!$egwData = $this->vtodotoegw($_vcalData)) {
+ return false;
+ }
+
+ #unset($egwData['info_priority']);
+
+ $filter = array('col_filter' => $egwData);
+ if($foundItems = $this->search($filter)) {
+ if(count($foundItems) > 0) {
+ $itemIDs = array_keys($foundItems);
+ return $itemIDs[0];
+ }
+ }
+
+ return false;
+ }
+
+ function vtodotoegw($_vcalData,$_taskID=-1)
+ {
+ $vcal = &new Horde_iCalendar;
+ if(!$vcal->parsevCalendar($_vcalData))
+ {
+ return FALSE;
+ }
+
+ $components = $vcal->getComponents();
+
+ if(count($components) > 0)
+ {
+ $component = $components[0];
+ if(is_a($component, 'Horde_iCalendar_vtodo'))
+ {
+ $taskData = array();
+ if($_taskID > 0)
+ {
+ $taskData['info_id'] = $_taskID;
+ }
+ foreach($component->_attributes as $attributes)
+ {
+ switch($attributes['name'])
+ {
+ case 'CLASS':
+ $taskData['info_access'] = strtolower($attributes['value']);
+ break;
+ case 'DESCRIPTION':
+ $taskData['info_des'] = $attributes['value'];
+ break;
+ case 'LOCATION':
+ $taskData['info_location'] = $attributes['value'];
+ break;
+ case 'DUE':
+ $taskData['info_enddate'] = $attributes['value'];
+ break;
+ case 'COMPLETED':
+ $taskData['info_datecompleted'] = $attributes['value'];
+ break;
+ case 'DTSTART':
+ $taskData['info_startdate'] = $attributes['value'];
+ break;
+ case 'PRIORITY':
+ if (1 <= $attributes['value'] && $attributes['value'] <= 3)
+ {
+ $taskData['info_priority'] = $this->vcal_priority2egw_priority[$attributes['value']];
+ }
+ else
+ {
+ $taskData['info_priority'] = 1; // default = normal
+ }
+ break;
+ case 'STATUS':
+ // check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
+ foreach($component->_attributes as $attr)
+ {
+ if ($attr['name'] == 'X-INFOLOG-STATUS') break;
+ }
+ $taskData['info_status'] = $this->vtodo2status($attributes['value'],
+ $attr['name'] == 'X-INFOLOG-STATUS' ? $attr['value'] : null);
+ break;
+ case 'SUMMARY':
+ $taskData['info_subject'] = $attributes['value'];
+ break;
+
+ case 'CATEGORIES':
+ $cats = $this->find_or_add_categories(explode(',', $attributes['value']));
+ $taskData['info_cat'] = $cats[0];
+ break;
+ case 'UID':
+ $taskData['info_uid'] = $attributes['value'];
+ if ($_taskID <= 0 && !empty($attributes['value']) && ($uid_task = $this->read($attributes['value'])))
+ {
+ $taskData['info_id'] = $uid_task['id'];
+ unset($uid_task);
+ }
+ break;
+ }
+ }
+ # the horde ical class does already convert in parsevCalendar
+ # do NOT convert here
+ #$taskData = $GLOBALS['egw']->translation->convert($taskData, 'UTF-8');
+
+ return $taskData;
+ }
+ }
+ return FALSE;
+ }
+
+ function exportVNOTE($_noteID, $_type)
+ {
+ $note = $this->read($_noteID);
+ $note = $GLOBALS['egw']->translation->convert($note, $GLOBALS['egw']->translation->charset(), 'UTF-8');
+
+ switch($_type)
+ {
+ case 'text/plain':
+ $txt = $note['info_subject']."\n\n".$note['info_des'];
+ return $txt;
+ break;
+
+ case 'text/x-vnote':
+ $noteGUID = $GLOBALS['egw']->common->generate_uid('infolog_note',$_noteID);
+ $vnote = &new Horde_iCalendar_vnote();
+ $vNote->setAttribute('VERSION', '1.1');
+ $vnote->setAttribute('SUMMARY',$note['info_subject']);
+ $vnote->setAttribute('BODY',$note['info_des']);
+ if($note['info_startdate'])
+ $vnote->setAttribute('DCREATED',$note['info_startdate']);
+ $vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'add'));
+ $vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
+ if (!empty($note['info_cat']))
+ {
+ $cats = $this->get_categories(array($note['info_cat']));
+ $vnote->setAttribute('CATEGORIES', $cats[0]);
+ }
+
+ #$vnote->setAttribute('UID',$noteGUID);
+ #$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
+
+ #$options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
+ #$vnote->setParameter('SUMMARY', $options);
+ #$vnote->setParameter('DESCRIPTION', $options);
+
+ return $vnote->exportvCalendar();
+ break;
+ }
+ return false;
+ }
+
+ function importVNOTE(&$_vcalData, $_type, $_noteID = -1)
+ {
+ if(!$note = $this->vnotetoegw($_vcalData, $_type))
+ {
+ return false;
+ }
+
+ if($_noteID > 0)
+ {
+ $note['info_id'] = $_noteID;
+ }
+
+ if(empty($note['info_status'])) {
+ $note['info_status'] = 'done';
+ }
+
+ #_debug_array($taskData);exit;
+ return $this->write($note);
+ }
+
+ function searchVNOTE($_vcalData, $_type)
+ {
+ if(!$note = $this->vnotetoegw($_vcalData)) {
+ return false;
+ }
+
+ $filter = array('col_filter' => $egwData);
+ if($foundItems = $this->search($filter)) {
+ if(count($foundItems) > 0) {
+ $itemIDs = array_keys($foundItems);
+ return $itemIDs[0];
+ }
+ }
+
+ return false;
+ }
+
+ function vnotetoegw($_data, $_type)
+ {
+ switch($_type)
+ {
+ case 'text/plain':
+ $note = array();
+ $note['info_type'] = 'note';
+ $botranslation =& CreateObject('phpgwapi.translation');
+ $txt = $botranslation->convert($_data, 'utf-8');
+ $txt = str_replace("\r\n", "\n", $txt);
+
+ if (preg_match("/^(^\n)\n\n(.*)$/", $txt, $match))
+ {
+ $note['info_subject'] = $match[0];
+ $note['info_des'] = $match[1];
+ }
+ else
+ {
+ $note['info_des'] = $txt;
+ }
+
+ return $note;
+ break;
+
+ case 'text/x-vnote':
+ $vnote = &new Horde_iCalendar;
+ if (!$vcal->parsevCalendar($_data))
+ {
+ return FALSE;
+ }
+ $components = $vnote->getComponent();
+ if(count($components) > 0)
+ {
+ $component = $components[0];
+ if(is_a($component, 'Horde_iCalendar_vnote'))
+ {
+ $note = array();
+ $note['info_type'] = 'note';
+
+ foreach($component->_attributes as $attribute)
+ {
+ switch ($attribute['name'])
+ {
+ case 'BODY':
+ $note['info_des'] = $attribute['value'];
+ break;
+ case 'SUMMARY':
+ $note['info_subject'] = $attribute['value'];
+ break;
+ case 'CATEGORIES':
+ {
+ $cats = $this->find_or_add_categories(explode(',', $attribute['value']));
+ $note['info_cat'] = $cats[0];
+ }
+ break;
+ }
+ }
+ }
+ return $note;
+ }
+ }
+ return FALSE;
+ }
+}
+