Horde_SyncMl_Device_sync4j::vevent2sif PHP Method

vevent2sif() public method

public vevent2sif ( $vcard )
    public function vevent2sif($vcard)
    {
        /* Some special handling for all-day vEvents that are not passed
         * as TYPE=DATE (TYPE=DATE does not exist for vCalendar 1.0) */
        if (preg_match('/(\\r\\n|\\r|\\n)DTSTART:.*T000000(\\r\\n|\\r|\\n)/', $vcard)) {
            if (preg_match('/(\\r\\n|\\r|\\n)DTEND:(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)T235959(\\r\\n|\\r|\\n)/', $vcard, $m)) {
                $vcard = preg_replace('/(\\r\\n|\\r|\\n)DTSTART:(.*)T000000(\\r\\n|\\r|\\n)/', "\$1DTSTART;VALUE=DATE:\$2\$3", $vcard);
                $vcard = preg_replace('/(\\r\\n|\\r|\\n)DTEND:(.*)T235959(\\r\\n|\\r|\\n)/', "\$1DTEND;VALUE=DATE:\$2\$3", $vcard);
            }
            // @TODO: else: handle case with DTEND= T240000
        }
        $iCal = new Horde_Icalendar();
        if (!$iCal->parsevCalendar($vcard)) {
            // @TODO: NEVER use die() in a library.
            die("There was an error importing the data.");
        }
        $components = $iCal->getComponents();
        switch (count($components)) {
            case 0:
                // @TODO: NEVER use die() in a library.
                die("No data was found.");
            case 1:
                $content = $components[0];
                break;
            default:
                // @TODO: NEVER use die() in a library.
                die("Multiple components found; only one is supported.");
        }
        $hash = array('ReminderSet' => 0, 'IsRecurring' => 0, 'BusyStatus' => 2);
        $alarm = $end = null;
        $start = $content->getAttribute('DTSTART');
        $start_params = $content->getAttribute('DTSTART', true);
        if (!empty($start_params[0]['VALUE']) && $start_params[0]['VALUE'] == 'DATE') {
            $hash['AllDayEvent'] = 1;
            $hash['Start'] = sprintf('%04d-%02d-%02d', $start['year'], $start['month'], $start['mday']);
            $start = mktime(0, 0, 0, $start['month'], $start['mday'], $start['year']);
        } else {
            $hash['AllDayEvent'] = 0;
            $hash['Start'] = Horde_Icalendar::_exportDateTime($start);
        }
        foreach ($content->getAllAttributes() as $item) {
            $GLOBALS['backend']->logMessage(sprintf('Sync4j for name %s, value %s', $item['name'], is_string($item['value']) ? $item['value'] : var_export($item['value'], true)), 'DEBUG');
            switch (Horde_String::upper($item['name'])) {
                case 'DTSTART':
                    break;
                case 'DTEND':
                    if (!empty($item['params']['VALUE']) && $item['params']['VALUE'] == 'DATE') {
                        $hash['AllDayEvent'] = 1;
                        $date = new Horde_Date($item['value']['year'], $item['value']['month'], $item['value']['mday']);
                        $date->mday--;
                        $hash['End'] = $date->format('Y-m-d');
                        $end = $date->datestamp();
                    } else {
                        $hash['AllDayEvent'] = 0;
                        $hash['End'] = Horde_Icalendar::_exportDateTime($item['value']);
                        $end = $item['value'];
                    }
                    break;
                case 'SUMMARY':
                    $hash['Subject'] = $item['value'];
                    break;
                case 'DESCRIPTION':
                    $hash['Body'] = $item['value'];
                    break;
                case 'LOCATION':
                    $hash['Location'] = $item['value'];
                    break;
                case 'CATEGORIES':
                    $hash['Categories'] = $item['value'];
                    break;
                case 'AALARM':
                    $hash['ReminderSet'] = 1;
                    $alarm = $item['value'];
                    break;
                case 'STATUS':
                    switch (Horde_String::upper($item['value'])) {
                        case 'FREE':
                        case 'CANCELLED':
                            $hash['BusyStatus'] = 0;
                            break;
                        case 'TENTATIVE':
                            $hash['BusyStatus'] = 1;
                            break;
                        case 'CONFIRMED':
                            $hash['BusyStatus'] = 2;
                            break;
                    }
                    break;
                case 'CLASS':
                    switch (Horde_String::upper($item['value'])) {
                        case 'PUBLIC':
                            $hash['Sensitivity'] = 0;
                            break;
                        case 'PRIVATE':
                            $hash['Sensitivity'] = 2;
                            break;
                        case 'CONFIDENTIAL':
                            $hash['Sensitivity'] = 3;
                            break;
                    }
                    break;
                case 'RRULE':
                    // Parse the recurrence rule into keys and values.
                    $rdata = array();
                    $parts = explode(';', $item['value']);
                    foreach ($parts as $part) {
                        list($key, $value) = explode('=', $part, 2);
                        $rdata[Horde_String::upper($key)] = $value;
                    }
                    if (!isset($rdata['FREQ'])) {
                        break;
                    }
                    $hash['IsRecurring'] = 1;
                    if (isset($rdata['BYDAY'])) {
                        $maskdays = array('SU' => Horde_Date::MASK_SUNDAY, 'MO' => Horde_Date::MASK_MONDAY, 'TU' => Horde_Date::MASK_TUESDAY, 'WE' => Horde_Date::MASK_WEDNESDAY, 'TH' => Horde_Date::MASK_THURSDAY, 'FR' => Horde_Date::MASK_FRIDAY, 'SA' => Horde_Date::MASK_SATURDAY);
                        $days = explode(',', $rdata['BYDAY']);
                        $mask = 0;
                        foreach ($days as $day) {
                            $instance = (int) $day;
                            $mask |= $maskdays[str_replace($instance, '', $day)];
                        }
                    }
                    $hash['Interval'] = isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1;
                    switch (Horde_String::upper($rdata['FREQ'])) {
                        case 'DAILY':
                            $hash['RecurrenceType'] = 0;
                            break;
                        case 'WEEKLY':
                            $hash['RecurrenceType'] = 1;
                            if (isset($rdata['BYDAY'])) {
                                $hash['DayOfWeekMask'] = $mask;
                            }
                            break;
                        case 'MONTHLY':
                            if (isset($rdata['BYDAY'])) {
                                $hash['RecurrenceType'] = 3;
                                $hash['Instance'] = $instance;
                                $hash['DayOfWeekMask'] = $mask;
                            } else {
                                $hash['RecurrenceType'] = 2;
                                $hash['DayOfMonth'] = date('j', $start);
                            }
                            break;
                        case 'YEARLY':
                            if (isset($rdata['BYDAY'])) {
                                $hash['RecurrenceType'] = 6;
                                $hash['Instance'] = $instance;
                                $hash['DayOfWeekMask'] = $mask;
                            } else {
                                $hash['RecurrenceType'] = 5;
                                $hash['DayOfMonth'] = date('j', $start);
                            }
                            $hash['MonthOfYear'] = date('n', $start);
                            unset($hash['Interval']);
                            break;
                    }
                    if (isset($rdata['UNTIL'])) {
                        $hash['NoEndDate'] = 0;
                        $hash['PatternEndDate'] = $rdata['UNTIL'];
                    } elseif (isset($rdata['COUNT'])) {
                        $hash['NoEndDate'] = 0;
                        $hash['Occurrences'] = $rdata['COUNT'];
                    } else {
                        $hash['NoEndDate'] = 1;
                    }
                    break;
                case 'EXDATE':
                    if (empty($hash['Exceptions'])) {
                        $hash['Exceptions'] = array();
                    }
                    foreach ($item['values'] as $date) {
                        if ($hash['AllDayEvent'] == 1) {
                            $d = new Horde_Date(array('year' => $date['year'], 'month' => $date['month'], 'mday' => $date['mday'] + 1));
                            $hash['Exceptions'][] = array('ExcludeDate' => $d->format('Y-m-d'));
                        } else {
                            $hash['Exceptions'][] = array('ExcludeDate' => Horde_Icalendar::_exportDate($date));
                        }
                    }
                    break;
            }
        }
        if (!empty($start)) {
            if ($hash['ReminderSet'] && !empty($alarm) && $start != $alarm) {
                $hash['ReminderMinutesBeforeStart'] = ($start - $alarm) / 60;
            } else {
                // Parse VALARM components.
                foreach ($content->getComponents() as $component) {
                    if ($component->getType() != 'vAlarm') {
                        continue;
                    }
                    try {
                        $trigger = $component->getAttribute('TRIGGER');
                    } catch (Horde_Icalendar_Exception $e) {
                        continue;
                    }
                    if (is_array($trigger) || empty($trigger)) {
                        continue;
                    }
                    $hash['ReminderSet'] = 1;
                    $hash['ReminderMinutesBeforeStart'] = -$trigger / 60;
                }
            }
        }
        if (empty($hash['AllDayEvent']) && !empty($start) && !empty($end) && $start != $end) {
            $hash['Duration'] = ($end - $start) / 60;
            $GLOBALS['backend']->logMessage('Duration set to ' . $hash['Duration'], 'DEBUG');
        }
        return Horde_SyncMl_Device_sync4j::array2sif($hash, '<?xml version="1.0"?><appointment>', '</appointment>');
    }

Usage Example

Example #1
0
 /**
  * Converts the content from the backend to a format suitable for the
  * client device.
  *
  * Strips the uid (primary key) information as client and server might use
  * different ones.
  *
  * @param string $content      The content to convert
  * @param string $contentType  The content type of content as returned
  *                             from the backend
  * @param string $database     The server database URI.
  *
  * @return array  Three-element array with the converted content, the
  *                (possibly changed) new content type, and encoding type
  *                (like b64 as used by Funambol).
  */
 public function convertServer2Client($content, $contentType, $database)
 {
     $database = $GLOBALS['backend']->normalize($database);
     list($content, $contentType, $encodingType) = parent::convertServer2Client($content, $contentType, $database);
     if ($this->requestedContentType == $contentType) {
         if ($contentType == 'text/calendar' || $contentType == 'text/x-vcalendar') {
             $si = $GLOBALS['backend']->state->sourceURI;
             if (stristr($si, 'fol-') !== false) {
                 // The Funambol Outlook connector uses invalid STATUS
                 // values. Actually it maps MeetingStatus values of the
                 // Outlook event to the STATUS property, which is
                 // completely useless. So drop the STATUS altogether.
                 $content = preg_replace('/^STATUS:.*\\r?\\n/im', '', $content);
             }
         }
         return array($content, $contentType, $encodingType);
     }
     switch ($contentType) {
         case 'text/calendar':
         case 'text/x-vcalendar':
             switch ($database) {
                 case 'calendar':
                     $content = Horde_SyncMl_Device_sync4j::vevent2sif($content);
                     $content = base64_encode($content);
                     $contentType = 'text/x-s4j-sife';
                     break 2;
                 case 'tasks':
                     $content = Horde_SyncMl_Device_sync4j::vtodo2sif($content);
                     $content = base64_encode($content);
                     $contentType = 'text/x-s4j-sift';
                     break 2;
             }
             break;
         case 'text/x-vcard':
             $content = Horde_SyncMl_Device_sync4j::vcard2sif($content);
             $content = base64_encode($content);
             $contentType = 'text/x-s4j-sifc';
             break;
         case 'text/x-vnote':
         case 'text/plain':
             $content = Horde_SyncMl_Device_sync4j::vnote2sif($content);
             $content = base64_encode($content);
             $contentType = 'text/x-s4j-sifn';
             break;
     }
     $l = "\nOutput converted for client ({$contentType}):\n" . base64_decode($content) . "\n";
     $GLOBALS['backend']->logFile(Horde_SyncMl_Backend::LOGFILE_DATA, $l);
     return array($content, $contentType, 'b64');
 }