[BUGFIX] Line endings in ICS must be Windows style 73/37673/2
authorLorenz Ulrich <lorenz.ulrich@visol.ch>
Fri, 19 Sep 2014 08:15:32 +0000 (10:15 +0200)
committerPatrick Wiggelman <patrickwiggelman@roquin.nl>
Fri, 20 Mar 2015 08:46:37 +0000 (09:46 +0100)
According to RFC2445 (iCalendar specification), line endings must be in
Windows style (\r\n). The TrimViewHelper is adapted to replace other
line endings to Windows style for ICS only.

Furthermore, line feeds in the DESCRIPTION (teaser field of news) must
be processed to have a space at the beginning of a new line to make the
feed validate.

Resolves: #61731
Releases: 3.1
Change-Id: I1a4cdee123a5d6074f6c43330f23c7bf18d5ab19
Reviewed-on: http://review.typo3.org/37673
Reviewed-by: Patrick Wiggelman <patrickwiggelman@roquin.nl>
Tested-by: Patrick Wiggelman <patrickwiggelman@roquin.nl>
Classes/ViewHelpers/Format/NewlineToNewlineTagViewHelper.php [new file with mode: 0644]
Classes/ViewHelpers/Format/TrimViewHelper.php
Resources/Private/Partials/Event/Item.ics
Resources/Private/Templates/News/EventDetail.ics
Resources/Private/Templates/News/EventList.ics

diff --git a/Classes/ViewHelpers/Format/NewlineToNewlineTagViewHelper.php b/Classes/ViewHelpers/Format/NewlineToNewlineTagViewHelper.php
new file mode 100644 (file)
index 0000000..0d4904f
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
+
+/**
+ * Replaces newlines in a string by a proprietary <newline /> tag for later post-processing
+ * @see TrimViewHelper
+ * @author Lorenz Ulrich <lorenz.ulrich@visol.ch>
+ */
+class Tx_RoqNewsevent_ViewHelpers_Format_NewlineToNewlineTagViewHelper extends AbstractViewHelper {
+
+       /**
+        * @param string $content
+        * @return string
+        */
+       public function render($content = NULL) {
+               if (NULL === $content) {
+                       $content = $this->renderChildren();
+               }
+               $contentArray = explode(PHP_EOL, $content);
+               $returnContent = '';
+               $i = 0;
+               foreach ($contentArray as $line) {
+                       if ($i > 0) {
+                               $returnContent .= '<newline />';
+                       }
+                       $returnContent .= $line;
+                       $i++;
+               }
+               return $returnContent;
+
+       }
+
+}
\ No newline at end of file
index 65ec92b..68cdf8a 100644 (file)
@@ -8,27 +8,49 @@
  * @description:    ViewHelper to trim content with PHP trim function
  */
 
+define('CR', "\r");          // Carriage Return: Mac
+define('LF', "\n");          // Line Feed: Unix
+define('CRLF', "\r\n");      // Carriage Return and Line Feed: Windows
+
 class Tx_RoqNewsevent_ViewHelpers_Format_TrimViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
 
        /**
-     * @param boolean $replaceDoubleSpaces Flag which defines if double spaces must be replaced with single spaces
-     * @param boolean $trimTabs Flag which defines if (indentation) tabs must be trimmed
+        * @param boolean $replaceDoubleSpaces Flag which defines if double spaces must be replaced with single spaces
+        * @param boolean $trimTabs Flag which defines if (indentation) tabs must be trimmed
+        * @param boolean $removeNewlineTags Flag which enables replacing proprietary <newline /> tags by spaces
+        * @param boolean $useWindowsLineEndings Flag which enables replacing line endings by Windows-style line endings
         * @return string The trimmed string
         */
-       public function render($replaceDoubleSpaces = TRUE, $trimTabs = TRUE) {
+       public function render($replaceDoubleSpaces = TRUE, $trimTabs = TRUE, $removeNewlineTags = FALSE, $useWindowsLineEndings = FALSE) {
                $content = $this->renderChildren();
 
-        if($replaceDoubleSpaces) {
+
+        if ($replaceDoubleSpaces) {
             $content = preg_replace('/\s\s+/', ' ', $content);
         }
 
-        if($trimTabs) {
-            $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*|[\t]*[\r\n\']+/", "\n", $content);
+        if ($trimTabs) {
+            $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*|[\t]*[\r\n]+/", "\n", $content);
         } else {
-            $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n\']+/", "\n", $content);
+            $content = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $content);
         }
 
-        return $content;
+               if ($removeNewlineTags) {
+                       /*
+                        These tags are inserted by the NewlineToNewlineTagViewHelper and mark a newline
+                        inside a string (e.g. DESCRIPTION). This is a way of preserving them from striping
+                        because a new line inside the DESCRIPTION must be indented by at least one space.
+                       */
+                       $content = str_replace('<newline />', " ", $content);
+               }
+
+               if ($useWindowsLineEndings) {
+                       $content = str_replace(CR, CRLF, $content);
+                       $content = str_replace(LF, CRLF, $content);
+               }
+
+               return $content;
+
        }
 }
 
index 9137d1b..99a6c72 100644 (file)
@@ -3,7 +3,7 @@
 
 BEGIN:VEVENT
 SUMMARY:<n:format.striptags>{newsItem.title}</n:format.striptags>
-DESCRIPTION:<n:format.striptags>{newsItem.teaser}</n:format.striptags>
+DESCRIPTION:<e:format.newlineToNewlineTag content="{f:format.stripTags(value: '{newsItem.teaser}')}" />
 DTSTAMP:<e:format.date format="%Y%m%dT%H%I%SZ" strftime="1">{newsItem.datetime}</e:format.date>
 
 <e:if condition="'<f:format.date>{newsItem.eventEnddate}</f:format.date>' != ''">
index 1cc8795..7ec55ef 100644 (file)
@@ -1,4 +1,4 @@
-BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE">
+BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE" useWindowsLineEndings="TRUE" removeNewlineTags="TRUE">
 
     {namespace n=Tx_News_ViewHelpers}
     {namespace e=Tx_RoqNewsevent_ViewHelpers}
@@ -8,4 +8,4 @@ BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE">
 
     <f:render partial="Event/Item" arguments="{newsItem: newsItem, settings: settings}"/>
 
-</e:format.trim>
\ No newline at end of file
+END:VCALENDAR</e:format.trim>
\ No newline at end of file
index b7aee50..0705d8d 100644 (file)
@@ -1,4 +1,4 @@
-BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE">
+BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE" useWindowsLineEndings="TRUE" removeNewlineTags="TRUE">
 
     {namespace n=Tx_News_ViewHelpers}
     {namespace e=Tx_RoqNewsevent_ViewHelpers}
@@ -13,4 +13,4 @@ BEGIN:VCALENDAR<e:format.trim replaceDoubleSpaces="FALSE">
 
         </f:for>
     </f:if>
-</e:format.trim>
\ No newline at end of file
+END:VCALENDAR</e:format.trim>
\ No newline at end of file