Horde_Icalendar::_exportvData PHP Method

_exportvData() protected method

Export this component in vCal format.
protected _exportvData ( string $base = 'VCALENDAR' ) : string
$base string The type of the base object.
return string vCal format data.
    protected function _exportvData($base = 'VCALENDAR')
    {
        $result = 'BEGIN:' . Horde_String::upper($base) . $this->_newline;
        // VERSION is not allowed for entries enclosed in VCALENDAR/ICALENDAR,
        // as it is part of the enclosing VCALENDAR/ICALENDAR. See rfc2445
        if ($base !== 'VEVENT' && $base !== 'VTODO' && $base !== 'VALARM' && $base !== 'VJOURNAL' && $base !== 'VFREEBUSY' && $base != 'VTIMEZONE' && $base != 'STANDARD' && $base != 'DAYLIGHT') {
            // Ensure that version is the first attribute.
            $result .= 'VERSION:' . $this->_version . $this->_newline;
        }
        foreach ($this->_attributes as $attribute) {
            $name = $attribute['name'];
            if ($name == 'VERSION') {
                // Already done.
                continue;
            }
            $params_str = '';
            $params = $attribute['params'];
            if ($params) {
                foreach ($params as $param_name => $param_value) {
                    /* Skip CHARSET for iCalendar 2.0 data, not allowed. */
                    if ($param_name == 'CHARSET' && !$this->_oldFormat) {
                        continue;
                    }
                    /* Skip VALUE=DATE for vCalendar 1.0 data, not allowed. */
                    if ($this->_oldFormat && $param_name == 'VALUE' && $param_value == 'DATE') {
                        continue;
                    }
                    if ($param_value === null) {
                        $params_str .= ";{$param_name}";
                    } else {
                        if (!is_array($param_value)) {
                            $param_value = array($param_value);
                        }
                        foreach ($param_value as &$one_param_value) {
                            $len = strlen($one_param_value);
                            $safe_value = '';
                            $quote = false;
                            for ($i = 0; $i < $len; ++$i) {
                                $ord = ord($one_param_value[$i]);
                                // Accept only valid characters.
                                if ($ord == 9 || $ord == 32 || $ord == 33 || $ord >= 35 && $ord <= 126 || $ord >= 128) {
                                    $safe_value .= $one_param_value[$i];
                                    // Characters above 128 do not need to be
                                    // quoted as per RFC2445 but Outlook requires
                                    // this.
                                    if ($ord == 44 || $ord == 58 || $ord == 59 || $ord >= 128) {
                                        $quote = true;
                                    }
                                }
                            }
                            if ($quote) {
                                $safe_value = '"' . $safe_value . '"';
                            }
                            $one_param_value = $safe_value;
                        }
                        $params_str .= ";{$param_name}=" . implode(',', $param_value);
                    }
                }
            }
            $value = $attribute['value'];
            switch ($name) {
                // Date fields.
                case 'COMPLETED':
                case 'CREATED':
                case 'DCREATED':
                case 'LAST-MODIFIED':
                case 'X-MOZ-LASTACK':
                case 'X-MOZ-SNOOZE-TIME':
                    $value = $this->_exportDateTime($value);
                    break;
                case 'DTEND':
                case 'DTSTART':
                case 'DTSTAMP':
                case 'DUE':
                case 'AALARM':
                case 'RECURRENCE-ID':
                    $floating = $base == 'STANDARD' || $base == 'DAYLIGHT' || isset($params['TZID']);
                    if (isset($params['VALUE'])) {
                        if ($params['VALUE'] == 'DATE') {
                            // VCALENDAR 1.0 uses T000000 - T235959 for all day events:
                            if ($this->_oldFormat && $name == 'DTEND') {
                                $d = new Horde_Date($value);
                                $value = new Horde_Date(array('year' => $d->year, 'month' => $d->month, 'mday' => $d->mday - 1));
                                $value = $this->_exportDate($value, '235959');
                            } else {
                                $value = $this->_exportDate($value, '000000');
                            }
                        } else {
                            $value = $this->_exportDateTime($value, $floating);
                        }
                    } else {
                        $value = $this->_exportDateTime($value, $floating);
                    }
                    break;
                    // Comma seperated dates.
                // Comma seperated dates.
                case 'EXDATE':
                case 'RDATE':
                    $floating = $base == 'STANDARD' || $base == 'DAYLIGHT';
                    $dates = array();
                    foreach ($value as $date) {
                        if (isset($params['VALUE'])) {
                            if ($params['VALUE'] == 'DATE') {
                                $dates[] = $this->_exportDate($date, '000000');
                            } elseif ($params['VALUE'] == 'PERIOD') {
                                $dates[] = $this->_exportPeriod($date);
                            } else {
                                $dates[] = $this->_exportDateTime($date, $floating);
                            }
                        } else {
                            $dates[] = $this->_exportDateTime($date, $floating);
                        }
                    }
                    $value = implode($this->_oldFormat ? ';' : ',', $dates);
                    break;
                case 'TRIGGER':
                    if (isset($params['VALUE'])) {
                        if ($params['VALUE'] == 'DATE-TIME') {
                            $value = $this->_exportDateTime($value);
                        } elseif ($params['VALUE'] == 'DURATION') {
                            $value = $this->_exportDuration($value);
                        }
                    } else {
                        $value = $this->_exportDuration($value);
                    }
                    break;
                    // Duration fields.
                // Duration fields.
                case 'DURATION':
                    $value = $this->_exportDuration($value);
                    break;
                    // Period of time fields.
                // Period of time fields.
                case 'FREEBUSY':
                    $value_str = '';
                    foreach ($value as $period) {
                        $value_str .= empty($value_str) ? '' : ',';
                        $value_str .= $this->_exportPeriod($period);
                    }
                    $value = $value_str;
                    break;
                    // UTC offset fields.
                // UTC offset fields.
                case 'TZOFFSETFROM':
                case 'TZOFFSETTO':
                    $value = $this->_exportUtcOffset($value);
                    break;
                    // Integer fields.
                // Integer fields.
                case 'PERCENT-COMPLETE':
                case 'PRIORITY':
                case 'REPEAT':
                case 'SEQUENCE':
                    $value = "{$value}";
                    break;
                    // Geo fields.
                // Geo fields.
                case 'GEO':
                    if ($this->_oldFormat) {
                        $value = $value['longitude'] . ',' . $value['latitude'];
                    } else {
                        $value = $value['latitude'] . ';' . $value['longitude'];
                    }
                    break;
                    // Recurrence fields.
                // Recurrence fields.
                case 'EXRULE':
                case 'RRULE':
                    break;
                default:
                    if ($this->_oldFormat) {
                        if (is_array($attribute['values']) && count($attribute['values']) > 1) {
                            $values = $attribute['values'];
                            if ($name == 'N' || $name == 'ADR' || $name == 'ORG') {
                                $glue = ';';
                            } else {
                                $glue = ',';
                            }
                            $values = str_replace(';', '\\;', $values);
                            $value = implode($glue, $values);
                        } else {
                            /* vcard 2.1 and vcalendar 1.0 escape only
                             * semicolons */
                            $value = str_replace(';', '\\;', $value);
                        }
                        // Text containing newlines or ASCII >= 127 must be BASE64
                        // or QUOTED-PRINTABLE encoded. Currently we use
                        // QUOTED-PRINTABLE as default.
                        if (preg_match("/[^ -]/", $value) && empty($params['ENCODING'])) {
                            $params['ENCODING'] = 'QUOTED-PRINTABLE';
                            $params_str .= ';ENCODING=QUOTED-PRINTABLE';
                            // Add CHARSET as well. At least the synthesis client
                            // gets confused otherwise
                            if (empty($params['CHARSET'])) {
                                $params['CHARSET'] = 'UTF-8';
                                $params_str .= ';CHARSET=' . $params['CHARSET'];
                            }
                        }
                    } else {
                        if (is_array($attribute['values']) && count($attribute['values'])) {
                            $values = $attribute['values'];
                            if ($name == 'N' || $name == 'ADR' || $name == 'ORG') {
                                $glue = ';';
                            } else {
                                $glue = ',';
                            }
                            // As of rfc 2426 2.5 semicolon and comma must be
                            // escaped.
                            $values = str_replace(array('\\', ';', ','), array('\\\\', '\\;', '\\,'), $values);
                            $value = implode($glue, $values);
                        } else {
                            // As of rfc 2426 2.5 semicolon and comma must be
                            // escaped.
                            $value = str_replace(array('\\', ';', ','), array('\\\\', '\\;', '\\,'), $value);
                        }
                        $value = preg_replace('/\\r?\\n/', '\\n', $value);
                    }
                    break;
            }
            $value = str_replace("\r", '', $value);
            if (!empty($params['ENCODING']) && $params['ENCODING'] == 'QUOTED-PRINTABLE' && strlen(trim($value))) {
                $result .= $name . $params_str . ':' . preg_replace(array('/(?<!\\r)\\n/', '/(?<!=)\\r\\n/'), array("\r\n", "=0D=0A=\r\n "), quoted_printable_encode($value)) . $this->_newline;
            } else {
                $attr_string = $name . $params_str . ':' . $value;
                if (!$this->_oldFormat) {
                    if (isset($params['ENCODING']) && $params['ENCODING'] == 'b') {
                        $attr_string = trim(chunk_split($attr_string, 75, $this->_newline . ' '));
                    } else {
                        $attr_string = Horde_String::wordwrap($attr_string, 75, $this->_newline . ' ', true, true);
                    }
                }
                $result .= $attr_string . $this->_newline;
            }
        }
        $tzs = array();
        foreach ($this->_components as $component) {
            if (!$component instanceof Horde_Icalendar_Vtimezone || !isset($tzs[$component->getAttribute('TZID')])) {
                $result .= $component->exportvCalendar();
                if ($component instanceof Horde_Icalendar_Vtimezone) {
                    $tzs[$component->getAttribute('TZID')] = true;
                }
            }
        }
        return $result . 'END:' . $base . $this->_newline;
    }