Andreas Vogt: iCalendar Datei

Hallo,
erstelle eine icl Datei per php mit Desciption aus Datenbank mit HTML-Breaks.
Wenn ich die icl in Outlook öffne habe ich immer diese <br /> Zeichen anstatt des Zeilenumbruchs.
habe diverses mit str_replace versucht, ohne Erfolg.
Kann mir jemand weiterhelfen?

Gruß Andreas

  1. Hi,

    erstelle eine icl Datei per php mit Desciption aus Datenbank mit HTML-Breaks.

    warum? Wird der Inhalt dieser Datei denn als HTML interpretiert? Vermutlich nicht.

    Wenn ich die icl in Outlook öffne habe ich immer diese <br /> Zeichen anstatt des Zeilenumbruchs.
    habe diverses mit str_replace versucht, ohne Erfolg.
    Kann mir jemand weiterhelfen?

    Ich würde das Übel an der Wurzel anpacken und gar nicht erst <br> generieren, sondern direkt einen normalen Zeilenumbruch, also "\r\n" (Windows) oder "\n" (Linux).

    Ciao,
     Martin

    --
    Eine Neandertaler-Sippe sitzt in ihrer kalten Höhle. Seufzt der Stammesälteste: "Hoffentlich erfindet bald jemand das Feuer!"
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hallo

      Ich würde das Übel an der Wurzel anpacken und gar nicht erst <br> generieren, sondern direkt einen normalen Zeilenumbruch, also "\r\n" (Windows) oder "\n" (Linux).

      Hab ich versucht das mit str_replace zu machen. Meine Header machen daraus 2 Slashes //

      Hier meine Header:
      header('Pragma: ');
      header('Cache-Control: no-cache');
      if (!$context['browser']['is_gecko'])
      header('Content-Transfer-Encoding: binary');
      header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');
      header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . 'GMT');
      header('Accept-Ranges: bytes');
      header('Connection: close');
      header('Content-Disposition: attachment; filename=' . $event['title'] . '.ics');
      header('Content-Type: text/calendar; charset=UTF-8');

      Andreas

      1. Hi,

        Ich würde das Übel an der Wurzel anpacken und gar nicht erst <br> generieren, sondern direkt einen normalen Zeilenumbruch, also "\r\n" (Windows) oder "\n" (Linux).
        Hab ich versucht das mit str_replace zu machen.

        du hast mich nicht verstanden! Ich meinte nicht, erst <br> zu erzeugen und dann zu ersetzen, sondern von Anfang an normale Zeilenumbrüche auszugeben.

        Meine Header machen daraus 2 Slashes //

        Diese Header -auch wenn etliche davon IMO Unfug sind- haben damit nichts zu tun. Gar nichts.

        Ciao,
         Martin

        --
        Die letzten Worte des Neandertalers:
        Möchte doch zu gern wissen, was in der Höhle ist ...
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Hallo,
          sorry, nicht möglich, dahinter steht ein Forensystem (SMF)

          Andreas

          1. Mahlzeit,

            sorry, nicht möglich, dahinter steht ein Forensystem (SMF)

            Wäre sinnvoll, solch relevanten Infos von Anfang an zu geben, hätte Arbeit gespart.
            Eine weitere relevante Info ist das Aussehen deines str_replace. Hellseher sind alle im Nachbarforum unter www.selfhellseher.de

            --
            42
            1. Hallo,
              wie soll die str_replace aussehen?
              da wird <br /> gegen \n\n, oder \r\n oder noch zig andere Varianten getauscht die ich erfolglos getestet habe.
              Auch mit Slash vor den Backslashes habe ich getestet.

              $description = utf8_encode(getCalendarPostingBody($_REQUEST['topic']));
              $description = str_replace("<br />", "\n\n", $description);

              Andreas

              1. Mahlzeit,

                wie soll die str_replace aussehen?

                so nicht:

                $description = utf8_encode(getCalendarPostingBody($_REQUEST['topic']));
                $description = str_replace("<br />", "\n\n", $description);

                Hast du es mal ohne der oberen Zeile probiert?
                Hast du dir den Text vorher und nachher anzeigen lassen?
                Was passiert im restlichen Code mit $description?

                da wird <br /> gegen \n\n, oder \r\n oder noch zig andere Varianten getauscht die ich erfolglos getestet habe.

                Nein.

                Auch mit Slash vor den Backslashes habe ich getestet.

                Wie genau?

                Und wenn du wieder, trotz Aufforderung, die relevanten Infos verweigerst, musst du doch ins Nachbarforum gehen, dann bin ich raus.

                --
                42
                1. Hallo,

                  Und wenn du wieder, trotz Aufforderung, die relevanten Infos verweigerst, musst du doch ins Nachbarforum gehen, dann bin ich raus.

                  sorry, kenne kein Nachbarforum von Selfhtml.

                  wenn ich utf8_encode() weglasse fehlen mir die kompletten Umlaute, darauf kann ich nicht verzichten.

                  Die Funktion zur ermittlung des Description-Textes sieht so aus:

                  function getCalendarPostingBody($topic)  
                  {  
                  	global $smcFunc;  
                    
                  	$request = $smcFunc['db_query']('', '  
                  		SELECT body FROM {db_prefix}messages Where id_topic = ' . $topic . '  
                  		Order By id_msg ASC Limit 1'  
                  	);  
                  	$row = $smcFunc['db_fetch_assoc']($request);  
                  	$return_value = $row['body'];  
                  	$smcFunc['db_free_result']($request);  
                  	return $return_value;  
                  }
                  

                  Der Code welcher die ics-Datei erstellt sieht so aus (in wesentlichen Teilen)

                  	$description = '';  
                  	$summary = '';  
                  	$location='';  
                  	if (isset($_REQUEST['topic']))  
                  	{  
                  		if (strlen($_REQUEST['topic'])>0)  
                  		{  
                  			$summary = utf8_encode(getCalendarPostingTitle($_REQUEST['topic']));  
                  			$description = utf8_encode(getCalendarPostingBody($_REQUEST['topic']));  
                  			$description = str_replace("<br />", "\n\n", $description);  
                  		}  
                  		$location = utf8_encode(getCalendarPostingLocation($_REQUEST['eventid']));  
                  	}  
                    
                  	// This is what we will be sending later.  
                  	$filecontents = '';  
                  	$filecontents .= 'BEGIN:VCALENDAR' . "\n";  
                  	$filecontents .= 'VERSION:2.0' . "\n";  
                  	$filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 1.0 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\n";  
                  	$filecontents .= 'BEGIN:VEVENT' . "\n";  
                  	$filecontents .= 'DTSTART:' . $date . "\n";  
                  	$filecontents .= 'DTEND:' . $date . "\n";  
                  	$filecontents .= 'LOCATION:'. $location . "\n";  
                  	$filecontents .= 'SUMMARY:' . (isset($_REQUEST['topic']) ?  utf8_encode(implode('',$title)) : $summary) . "\n";  
                  	$filecontents .= 'DESCRIPTION:' . $description ."\n";  
                  	$filecontents .= 'END:VEVENT'."\n";  
                  	$filecontents .= 'END:VCALENDAR';  
                    
                  	// Send some standard headers.  
                  	ob_end_clean();  
                  	if (!empty($modSettings['enableCompressedOutput']))  
                  		@ob_start('ob_gzhandler');  
                  	else  
                  		ob_start();  
                    
                  	// Send the file headers  
                  	header('Pragma: ');  
                  	header('Cache-Control: no-cache');  
                  	if (!$context['browser']['is_gecko'])  
                  		header('Content-Transfer-Encoding: binary');  
                  	header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');  
                  	header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . 'GMT');  
                  	header('Accept-Ranges: bytes');  
                  	header('Connection: close');  
                  	header('Content-Disposition: attachment; filename=' . $event['title'] . '.ics');  
                    
                  	// How big is it?  
                  	if (empty($modSettings['enableCompressedOutput']))  
                  		header('Content-Length: ' . $smcFunc['strlen']($filecontents));  
                    
                  	// This is a calendar item!  
                  	header('Content-Type: text/calendar; charset=UTF-8');  
                    
                  	// Chuck out the card.  
                  	echo $filecontents;  
                    
                  	// Off we pop - lovely!  
                  	obExit(false);
                  

                  Lass ich die utf8_encode Funktion weg, ändert sich nichts. Scheinbar dient "\n" als Steuerzeichen, denn im Text der ical Datei sind diese nicht sichtbar, und wenn ich die Datei mit Outlook öffne bricht der Description-Text beim ersten "\n" ab.

                  Gruß Andreas

                  1. Hello,

                    Der Code welcher die ics-Datei erstellt sieht so aus (in wesentlichen Teilen)

                    // This is what we will be sending later.

                    Diese zwei Zeilen lassen mich aufhorchen:
                    Werden die Daten per eMail versendet?
                    Stammt das Script von einem Rechner, der mit Linux läuft?
                    Und du versuchst es jetzt entweder auf Windows oder (siehe unten *)?

                    Dann wären die "\n" passend, weil das Mailscript die alle gegen "\r\n" austauscht.

                    Windows erwartet "\r\n".

                    Da Du mit PHP arbeitest, solltest Du mal versuchsweise alle "\n" gegen PHP_EOL austauschen. Das geht natürlich nur im Quellcode, da PHP_EOL eine Konstante ist, die je nach System gegen "\n" oder "\r\n" ausgestauscht wird.

                    *) Wenn Du allerdings die Daten als Datei transportierst, vergiss, was ich geschrieben habe, bzw tausche alle "\n" gegen "\r\n" :-)

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bikers-lodge.com
                    1. Hallo,

                      Diese zwei Zeilen lassen mich aufhorchen:
                      Werden die Daten per eMail versendet?
                      Stammt das Script von einem Rechner, der mit Linux läuft?
                      Und du versuchst es jetzt entweder auf Windows oder (siehe unten *)?

                      Die Daten werden per Header gesendet, d.H. wie ein Download.
                      Auf dem Webspace läuft Linux.

                      Dann wären die "\n" passend, weil das Mailscript die alle gegen "\r\n" austauscht.
                      Windows erwartet "\r\n".

                      Wenn ich von meinem Word aus ein Kalendereintrag als ics verschicke, steht im Text \n\n für ein Zeilenumbruch.

                      Da Du mit PHP arbeitest, solltest Du mal versuchsweise alle "\n" gegen PHP_EOL austauschen. gemacht, ohne Erfolg. Beim ersten Umbruch bricht der Text ab. Ich benötige \n nicht als Steuerzeichen sondern als Text in der ics-Datei.

                      Hier kann man das mal testen:
                      http://www.swhv-kreisgruppe-13.de/index.php?action=calendar

                      klick auf das orangene icon.

                      Gruß Andreas

                      1. Hello,

                        Die Daten werden per Header gesendet, d.H. wie ein Download.

                        Also HTTP?
                        Dann gehören in für die Header da als Zeilenenden "\r\n" rein.

                        Auf dem Webspace läuft Linux.

                        Das ist dann unerheblich, denn die Formvorschrift stammt aus dem Protokoll, und das ist plattformunabhängig.

                        Aber das betrifft nicht die versandte Datei. Wenn es wie ein Download abgewickelt wird, dann sind Content-Encoding und Content-Transfer-Encoding anzugeben.

                        Wenn als CTE base64 benutzt wird, sollte man nach jeweils 78 Zeichen einen Zeilenumbruch einfügen und der sollte aus CRLF bestehen. Dann hat eine "Zeile" maximal 80 Bytes, nicht zu verwechseln mit "Zeichen". Das sind dann weniger.

                        Wenn ich von meinem Word aus ein Kalendereintrag als ics verschicke, steht im Text \n\n für ein Zeilenumbruch.

                        Da liegt irgendwo der Hase im Pfeffer.
                        Ich habe die rfc5545 noch nicht ganz durchschaut, aber wie ich es verstanden habe, wird auch CRLF als Zeilenende verlangt.

                        Das sollte dann wahrscheinlich ein doppletes CRLF werden, also "\r\n\r\n"

                        http://www.swhv-kreisgruppe-13.de/index.php?action=calendar

                        klick auf das orangene icon.

                        Ich habe es angesehen. Mit einem Editor (Notepad++) sind die Daten normal lesbar, und haben LF als Zeilenende.

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        http://bikers-lodge.com
                        1. Hi,

                          Die Daten werden per Header gesendet, d.H. wie ein Download.
                          Also HTTP?
                          Dann gehören in für die Header da als Zeilenenden "\r\n" rein.

                          ja, stimmt - das macht die PHP-Funktion header() aber selbst. Wenn man diese Funktion verwendet, wird mit jedem Aufruf ein HTTP-Header übergeben, und zwar ohne Delimiter.

                          Wenn als CTE base64 benutzt wird, sollte man nach jeweils 78 Zeichen einen Zeilenumbruch einfügen und der sollte aus CRLF bestehen. Dann hat eine "Zeile" maximal 80 Bytes, nicht zu verwechseln mit "Zeichen". Das sind dann weniger.

                          Nö. Die base64-Codierung führt dazu, dass die entstehende Textwurst nur noch aus ASCII-Zeichen besteht. Damit sind dann also 78 Zeichen auch genau 78 Bytes, mit CRLF hintendran erhält man 80 Zeichen, respektive 80 Bytes pro Zeile.

                          Ich habe die rfc5545 noch nicht ganz durchschaut, aber wie ich es verstanden habe, wird auch CRLF als Zeilenende verlangt.

                          "Ja, aber."
                          Genau wie bei e-Mail-Headern kann eine lange Zeile jederzeit durch CR/LF unterbrochen werden; man muss dann nur dafür sorgen, dass die Fortsetzungszeile um _genau_ein_ Tab oder Blank eingerückt ist, damit sie als Fortsetzung der vorhergehenden Zeile gilt (siehe RFC 5545 Abschnitt 3.1).

                          Das sollte dann wahrscheinlich ein doppletes CRLF werden, also "\r\n\r\n"

                          Nein.

                          Ciao,
                           Martin

                          --
                          Die letzten Worte des Helden:
                          Feigling! Traust dich ja doch nicht!
                          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                          1. Hello,

                            Wenn als CTE base64 benutzt wird, sollte man nach jeweils 78 Zeichen einen Zeilenumbruch einfügen und der sollte aus CRLF bestehen. Dann hat eine "Zeile" maximal 80 Bytes, nicht zu verwechseln mit "Zeichen". Das sind dann weniger.

                            Nö. Die base64-Codierung führt dazu, dass die entstehende Textwurst nur noch aus ASCII-Zeichen besteht. Damit sind dann also 78 Zeichen auch genau 78 Bytes, mit CRLF hintendran erhält man 80 Zeichen, respektive 80 Bytes pro Zeile.

                            So meinte ich das auch. Also 80 Bytes pro "Zeile" im übertragenen Stream.
                            Da können dann immer nur weniger als 78 Zeichen des ursprünglichen Textes drinstecken.

                            Ich habe die rfc5545 noch nicht ganz durchschaut, aber wie ich es verstanden habe, wird auch CRLF als Zeilenende verlangt.

                            "Ja, aber."
                            Genau wie bei e-Mail-Headern kann eine lange Zeile jederzeit durch CR/LF unterbrochen werden; man muss dann nur dafür sorgen, dass die Fortsetzungszeile um _genau_ein_ Tab oder Blank eingerückt ist, damit sie als Fortsetzung der vorhergehenden Zeile gilt (siehe RFC 5545 Abschnitt 3.1).

                            Das könnte doch schon ein Hinweis sein!

                            Das Format ist aber ohnehin "stupid". Müsste doch mit dem Teufel zugehen, wenn man da den Fehler nicht findet.

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            http://bikers-lodge.com
  2. Hello,

    erstelle eine icl Datei per php mit Desciption aus Datenbank mit HTML-Breaks.
    Wenn ich die icl in Outlook öffne habe ich immer diese <br /> Zeichen anstatt des Zeilenumbruchs.
    habe diverses mit str_replace versucht, ohne Erfolg.
    Kann mir jemand weiterhelfen?

    Wenn man es richtig machen will, muss man wahrscheilich erst einmal ein paar Seiten lesen:

    http://tools.ietf.org/html/rfc5545

    Formatbeschreibung zu *.ics oder *.ical

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
  3. Hallo,
    ich hab mir nochmal eine aus meinem eigenen Kalender erstellte ics-Datei genauer angeschaut, und festgestellt dass diese neben der Description immer noch einen HTML-Teil besitzt. Also hab ich mein Code ein wenig angepasst - und die <br /> brauche ich so gar nicht mehr ersetzten. Ich musste nur die Formatierung von $date anpassen.

    ...

      
    	$filecontents .= 'BEGIN:VCALENDAR' . "\r\n";  
    	$filecontents .= 'VERSION:2.0' . "\r\n";  
    	$filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 1.0 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\r\n";  
    	$filecontents .= 'BEGIN:VEVENT' . "\r\n";  
    	$filecontents .= 'CLASS:PUBLIC' . "\r\n";  
    	$filecontents .= 'DTSTART;TZID="W. Europe Standard Time":' . $date . "\r\n";  
    	$filecontents .= 'DTEND;TZID="W. Europe Standard Time":' . $date . "\r\n";  
    	$filecontents .= 'LOCATION:'. $location . "\r\n";  
    	$filecontents .= 'SEQUENCE:0' . "\r\n";  
    	$filecontents .= 'SUMMARY;LANGUAGE=de:' . (isset($_REQUEST['topic']) ?  utf8_encode(implode('',$title)) : $summary) . "\r\n";  
    	$filecontents .= 'X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E\r\n';  
    	$filecontents .= 'N">\n<HTML>\n<HEAD>\n<META NAME="Generator" CONTENT="MS Exchange Server ve\r\n';  
    	$filecontents .= 'rsion 14.02.5004.000">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Converted f\r\n';  
    	$filecontents .= 'rom text/rtf format -->\n\n<P DIR=LTR><SPAN LANG="de"><FONT FACE="Calibri">\r\n';  
    	  
    	$filecontents .= $description;  
    	  
    	$filecontents .= '</FONT></SPAN><SPAN LANG="de"></SPAN></P>\n\n</BODY>\n</HTML>' . "\r\n";  
    	$filecontents .= 'X-MICROSOFT-CDO-BUSYSTATUS:BUSY' . "\r\n";  
    	$filecontents .= 'X-MICROSOFT-CDO-IMPORTANCE:1' . "\r\n";  
    	$filecontents .= 'X-MICROSOFT-DISALLOW-COUNTER:FALSE' . "\r\n";  
    	$filecontents .= 'X-MS-OLK-AUTOFILLLOCATION:FALSE' . "\r\n";  
    	$filecontents .= 'X-MS-OLK-AUTOSTARTCHECK:FALSE' . "\r\n";  
    	$filecontents .= 'X-MS-OLK-CONFTYPE:0' . "\r\n";  
    	$filecontents .= 'END:VEVENT'."\r\n";  
    	$filecontents .= 'END:VCALENDAR';
    

    ...

    Gruß Andreas