From 9e61c0bc91397bf30861bb93773b01b9a605c1b1 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 8 Oct 2008 07:45:35 +0000 Subject: [PATCH] "fixed typo in filename of infolog_ical class" --- infolog/inc/class.infolog_ical.inc.php | 378 +++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 infolog/inc/class.infolog_ical.inc.php diff --git a/infolog/inc/class.infolog_ical.inc.php b/infolog/inc/class.infolog_ical.inc.php new file mode 100644 index 0000000000..8878b554cd --- /dev/null +++ b/infolog/inc/class.infolog_ical.inc.php @@ -0,0 +1,378 @@ + + * @package infolog + * @subpackage syncml + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @version $Id$ + */ + +require_once EGW_API_INC.'/horde/Horde/iCalendar.php'; + +/** + * InfoLog: Create and parse iCal's + * + */ +class infolog_ical extends infolog_bo +{ + 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) + { + $taskData = $this->read($_taskID); + + $taskData = $GLOBALS['egw']->translation->convert($taskData, $GLOBALS['egw']->translation->charset(), 'UTF-8'); + + $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) + { + $vevent->setAttribute($field,$value); + $options = array(); + if(preg_match('/([\000-\012\015\016\020-\037\075])/',$value)) + { + $options['ENCODING'] = 'QUOTED-PRINTABLE'; + } + if($extra_charset_attribute && preg_match('/([\177-\377])/',$value)) + { + $options['CHARSET'] = 'UTF-8'; + } + 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('PERCENT-COMPLETE',$taskData['info_percent']); + $vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]); + + if (!empty($taskData['info_cat'])) + { + $cats = $this->get_categories(array($taskData['info_cat'])); + $vevent->setAttribute('CATEGORIES', $cats[0]); + } + $vcal->addComponent($vevent); + + 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; + case 'PERCENT-COMPLETE': + $taskData['info_percent'] = (int) $attributes['value']; + 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; + } +} +