Tiny bug with date function in t3lib_befunc. Casted timestamp to integer.
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_parsehtml.php
index e33f122..566c663 100644 (file)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * @subpackage t3lib
  */
 class t3lib_parsehtml  {
  * @subpackage t3lib
  */
 class t3lib_parsehtml  {
-       var $caseShift_cache=array();
 
 
-
-       // *******************************************'
-       // COPY FROM class.tslib_content.php: / BEGIN
-       // substituteSubpart
-       // Cleaned locally 2/2003 !!!! (so different from tslib_content version)
-       // *******************************************'
+       protected $caseShift_cache = array();
 
        /**
 
        /**
-        * Returns the first subpart encapsulated in the marker, $marker (possibly present in $content as a HTML comment)
+        * Returns the first subpart encapsulated in the marker, $marker
+        * (possibly present in $content as a HTML comment)
         *
         * @param       string          Content with subpart wrapped in fx. "###CONTENT_PART###" inside.
         * @param       string          Marker string, eg. "###CONTENT_PART###"
         * @return      string
         */
         *
         * @param       string          Content with subpart wrapped in fx. "###CONTENT_PART###" inside.
         * @param       string          Marker string, eg. "###CONTENT_PART###"
         * @return      string
         */
-       function getSubpart($content, $marker)  {
+       public static function getSubpart($content, $marker) {
                $start = strpos($content, $marker);
                $start = strpos($content, $marker);
-               if ($start===false)     { return ''; }
+
+               if ($start === false) {
+                       return '';
+               }
+
                $start += strlen($marker);
                $start += strlen($marker);
-               $stop = strpos($content, $marker, $start);
-                       // Q: What shall get returned if no stop marker is given /*everything till the end*/ or nothing
-               if ($stop===false)      { return /*substr($content, $start)*/ ''; }
+               $stop   = strpos($content, $marker, $start);
+
+                       // Q: What shall get returned if no stop marker is given
+                       // /*everything till the end*/ or nothing?
+               if ($stop===false) {
+                       return ''; /*substr($content, $start)*/
+               }
+
                $content = substr($content, $start, $stop-$start);
                $content = substr($content, $start, $stop-$start);
+
                $matches = array();
                $matches = array();
-               if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $content, $matches)===1)      {
+               if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $content, $matches) === 1) {
                        return $matches[2];
                }
                        return $matches[2];
                }
-               $matches = array();
-               if (preg_match('/(.*)(\<\!\-\-[^\>]*)$/s', $content, $matches)===1)     {
+
+               $matches = array(); // resetting $matches
+               if (preg_match('/(.*)(\<\!\-\-[^\>]*)$/s', $content, $matches) === 1) {
                        return $matches[1];
                }
                        return $matches[1];
                }
-               $matches = array();
-               if (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $content, $matches)===1)      {
+
+               $matches = array(); // resetting $matches
+               if (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $content, $matches) === 1) {
                        return $matches[2];
                }
                        return $matches[2];
                }
+
                return $content;
        }
 
                return $content;
        }
 
@@ -153,73 +161,171 @@ class t3lib_parsehtml    {
         * @param       boolean         If set, the marker around the subpart is not removed, but kept in the output
         * @return      string          Processed input content
         */
         * @param       boolean         If set, the marker around the subpart is not removed, but kept in the output
         * @return      string          Processed input content
         */
-       function substituteSubpart($content,$marker,$subpartContent,$recursive=1,$keepMarker=0) {
+       public static function substituteSubpart($content, $marker, $subpartContent, $recursive = 1, $keepMarker = 0) {
                $start = strpos($content, $marker);
                $start = strpos($content, $marker);
-               if ($start===false)     { return $content; }
-               $startAM = $start+strlen($marker);
-               $stop = strpos($content, $marker, $startAM);
-               if ($stop===false)      { return $content; }
-               $stopAM = $stop+strlen($marker);
-               $before = substr($content, 0, $start);
-               $after = substr($content, $stopAM);
+
+               if ($start === false) {
+                       return $content;
+               }
+
+               $startAM = $start + strlen($marker);
+               $stop    = strpos($content, $marker, $startAM);
+
+               if ($stop===false) {
+                       return $content;
+               }
+
+               $stopAM  = $stop + strlen($marker);
+               $before  = substr($content, 0, $start);
+               $after   = substr($content, $stopAM);
                $between = substr($content, $startAM, $stop-$startAM);
 
                $between = substr($content, $startAM, $stop-$startAM);
 
-               if ($recursive) {
-                       $after = t3lib_parsehtml::substituteSubpart($after, $marker, $subpartContent, $recursive, $keepMarker);
+               if ($recursive) {
+                       $after = t3lib_parsehtml::substituteSubpart(
+                               $after,
+                               $marker,
+                               $subpartContent,
+                               $recursive,
+                               $keepMarker
+                       );
                }
 
                }
 
-               if ($keepMarker)        {
+               if ($keepMarker) {
                        $matches = array();
                        $matches = array();
-                       if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1)      {
-                               $before .= $marker.$matches[1];
-                               $between = $matches[2];
-                               $after = $matches[3].$marker.$after;
-                       } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1)      {
-                               $before .= $marker;
-                               $between = $matches[1];
-                               $after = $matches[2].$marker.$after;
-                       } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches)===1)        {
-                               $before .= $marker.$matches[1];
-                               $between = $matches[2];
-                               $after = $marker.$after;
+                       if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) {
+                               $before  .= $marker.$matches[1];
+                               $between  = $matches[2];
+                               $after    = $matches[3] . $marker . $after;
+                       } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) {
+                               $before  .= $marker;
+                               $between  = $matches[1];
+                               $after    = $matches[2] . $marker . $after;
+                       } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches) === 1) {
+                               $before  .= $marker . $matches[1];
+                               $between  = $matches[2];
+                               $after    = $marker . $after;
                        } else  {
                                $before .= $marker;
                        } else  {
                                $before .= $marker;
-                               $after = $marker.$after;
+                               $after   = $marker . $after;
                        }
                        }
-               } else  {
+
+               } else {
                        $matches = array();
                        $matches = array();
-                       if (preg_match('/^(.*)\<\!\-\-[^\>]*$/s', $before, $matches)===1)       {
+                       if (preg_match('/^(.*)\<\!\-\-[^\>]*$/s', $before, $matches) === 1) {
                                $before = $matches[1];
                        }
                                $before = $matches[1];
                        }
-                       if (is_array($subpartContent))  {
+
+                       if (is_array($subpartContent)) {
                                $matches = array();
                                $matches = array();
-                               if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1)      {
+                               if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) {
                                        $between = $matches[2];
                                        $between = $matches[2];
-                               } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1)      {
+                               } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1) {
                                        $between = $matches[1];
                                        $between = $matches[1];
-                               } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches)===1)        {
+                               } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches)===1) {
                                        $between = $matches[2];
                                }
                        }
                                        $between = $matches[2];
                                }
                        }
-                       $matches = array();
-                       if (preg_match('/^[^\<]*\-\-\>(.*)$/s', $after, $matches)===1)  {
+
+                       $matches = array(); // resetting $matches
+                       if (preg_match('/^[^\<]*\-\-\>(.*)$/s', $after, $matches) === 1) {
                                $after = $matches[1];
                        }
                }
 
                                $after = $matches[1];
                        }
                }
 
-               if (is_array($subpartContent))  {
-                       $between = $subpartContent[0].$between.$subpartContent[1];
+               if (is_array($subpartContent)) {
+                       $between = $subpartContent[0] . $between . $subpartContent[1];
                } else  {
                        $between = $subpartContent;
                }
 
                } else  {
                        $between = $subpartContent;
                }
 
-               return $before.$between.$after;
+               return $before . $between . $after;
+       }
+
+       /**
+        * Substitues multiple subparts at once
+        *
+        * @param       string          The content stream, typically HTML template content.
+        * @param       array           The array of key/value pairs being subpart/content values used in the substitution. For each element in this array the function will substitute a subpart in the content stream with the content.
+        * @return      string          The processed HTML content string.
+        */
+       public static function substituteSubpartArray($content, array $subpartsContent) {
+               foreach ($subpartsContent as $subpartMarker => $subpartContent) {
+                       $content = t3lib_parsehtml::substituteSubpart(
+                               $content,
+                               $subpartMarker,
+                               $subpartContent
+                       );
+               }
+
+               return $content;
        }
 
 
        }
 
 
-       // *******************************************'
-       // COPY FROM class.tslib_content.php: / END
-       // *******************************************'
+       /**
+        * Substitutes a marker string in the input content
+        * (by a simple str_replace())
+        *
+        * @param       string          The content stream, typically HTML template content.
+        * @param       string          The marker string, typically on the form "###[the marker string]###"
+        * @param       mixed           The content to insert instead of the marker string found.
+        * @return      string          The processed HTML content string.
+        * @see substituteSubpart()
+        */
+       public static function substituteMarker($content, $marker, $markContent) {
+               return str_replace($marker, $markContent, $content);
+       }
+
+
+       /**
+        * Traverses the input $markContentArray array and for each key the marker
+        * by the same name (possibly wrapped and in upper case) will be
+        * substituted with the keys value in the array. This is very useful if you
+        * have a data-record to substitute in some content. In particular when you
+        * use the $wrap and $uppercase values to pre-process the markers. Eg. a
+        * key name like "myfield" could effectively be represented by the marker
+        * "###MYFIELD###" if the wrap value was "###|###" and the $uppercase
+        * boolean true.
+        *
+        * @param       string          The content stream, typically HTML template content.
+        * @param       array           The array of key/value pairs being marker/content values used in the substitution. For each element in this array the function will substitute a marker in the content stream with the content.
+        * @param       string          A wrap value - [part 1] | [part 2] - for the markers before substitution
+        * @param       boolean         If set, all marker string substitution is done with upper-case markers.
+        * @param       boolean         If set, all unused marker are deleted.
+        * @return      string          The processed output stream
+        * @see substituteMarker(), substituteMarkerInObject(), TEMPLATE()
+        */
+       public static function substituteMarkerArray($content, $markContentArray, $wrap = '', $uppercase = 0, $deleteUnused = 0) {
+               if (is_array($markContentArray)) {
+                       $wrapArr = t3lib_div::trimExplode('|', $wrap);
+
+                       foreach ($markContentArray as $marker => $markContent) {
+                               if ($uppercase) {
+                                               // use strtr instead of strtoupper to avoid locale problems with Turkish
+                                       $marker = strtr(
+                                               $marker,
+                                               'abcdefghijklmnopqrstuvwxyz',
+                                               'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                                       );
+                               }
+
+                               if (count($wrapArr) > 0) {
+                                       $marker = $wrapArr[0] . $marker . $wrapArr[1];
+                               }
+
+                               $content = str_replace($marker, $markContent, $content);
+                       }
+
+                       if ($deleteUnused) {
+                               if (empty($wrap)) {
+                                       $wrapArr = array('###', '###');
+                               }
+
+                               $content = preg_replace('/'.preg_quote($wrapArr[0]).'([A-Z0-9_-|]*)'.preg_quote($wrapArr[1]).'/is', '', $content);
+                       }
+               }
+
+               return $content;
+       }
 
 
 
 
 
 
@@ -623,10 +729,33 @@ class t3lib_parsehtml     {
                $c = 1;
                $tagRegister = array();
                $tagStack = array();
                $c = 1;
                $tagRegister = array();
                $tagStack = array();
+               $inComment = false; $skipTag = false;
                while(list(,$tok)=each($tokArr))        {
                while(list(,$tok)=each($tokArr))        {
+                       if ($inComment) {
+                               if (($eocPos = strpos($tok, '-->')) === false) {
+                                       // End of comment is not found in the token. Go futher until end of comment is found in other tokens.
+                                       $newContent[$c++] = '<' . $tok;
+                                       continue;
+                               }
+                               // Comment ends in the middle of the token: add comment and proceed with rest of the token
+                               $newContent[$c++] = '<' . substr($tok, 0, $eocPos + 3);
+                               $tok = substr($tok, $eocPos + 3);
+                               $inComment = false; $skipTag = true;
+                       }
+                       elseif (substr($tok, 0, 3) == '!--') {
+                               if (($eocPos = strpos($tok, '-->')) === false) {
+                                       // Comment started in this token but it does end in the same token. Set a flag to skip till the end of comment
+                                       $newContent[$c++] = '<' . $tok;
+                                       $inComment = true;
+                                       continue;
+                               }
+                               // Start and end of comment are both in the current token. Add comment and proceed with rest of the token
+                               $newContent[$c++] = '<' . substr($tok, 0, $eocPos + 3);
+                               $tok = substr($tok, $eocPos + 3);
+                               $skipTag = true;
+                       }
                        $firstChar = substr($tok,0,1);
                        $firstChar = substr($tok,0,1);
-#                      if (strcmp(trim($firstChar),''))        {               // It is a tag...
-                       if (preg_match('/[[:alnum:]\/]/',$firstChar)==1)        {               // It is a tag... (first char is a-z0-9 or /) (fixed 19/01 2004). This also avoids triggering on <?xml..> and <!DOCTYPE..>
+                       if (!$skipTag && preg_match('/[[:alnum:]\/]/',$firstChar)==1)   {               // It is a tag... (first char is a-z0-9 or /) (fixed 19/01 2004). This also avoids triggering on <?xml..> and <!DOCTYPE..>
                                $tagEnd = strpos($tok,'>');
                                if ($tagEnd)    {       // If there is and end-bracket...       tagEnd can't be 0 as the first character can't be a >
                                        $endTag = $firstChar=='/' ? 1 : 0;
                                $tagEnd = strpos($tok,'>');
                                if ($tagEnd)    {       // If there is and end-bracket...       tagEnd can't be 0 as the first character can't be a >
                                        $endTag = $firstChar=='/' ? 1 : 0;
@@ -790,7 +919,8 @@ class t3lib_parsehtml       {
                                        $newContent[$c++]=$this->processContent('<'.$tok,$hSC,$addConfig);      // There were not end-bracket, so no tag...
                                }
                        } else {
                                        $newContent[$c++]=$this->processContent('<'.$tok,$hSC,$addConfig);      // There were not end-bracket, so no tag...
                                }
                        } else {
-                               $newContent[$c++]=$this->processContent('<'.$tok,$hSC,$addConfig);      // It was not a tag anyways
+                               $newContent[$c++]=$this->processContent(($skipTag ? '' : '<') . $tok, $hSC, $addConfig);        // It was not a tag anyways
+                               $skipTag = false;
                        }
                }
 
                        }
                }
 
@@ -898,7 +1028,7 @@ class t3lib_parsehtml      {
                        $parts = $this->splitIntoBlock('style',$content);
                        foreach($parts as $k => $v)     {
                                if ($k%2)       {
                        $parts = $this->splitIntoBlock('style',$content);
                        foreach($parts as $k => $v)     {
                                if ($k%2)       {
-                                       $parts[$k] = eregi_replace('(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))','\1'.$prefix.'\2'.$suffix.'\3',$parts[$k]);
+                                       $parts[$k] = preg_replace('/(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))/i','\1'.$prefix.'\2'.$suffix.'\3',$parts[$k]);
                                }
                        }
                        $content = implode('',$parts);
                                }
                        }
                        $content = implode('',$parts);
@@ -1323,4 +1453,5 @@ class t3lib_parsehtml     {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml.php'])        {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml.php']);
 }
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml.php'])        {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_parsehtml.php']);
 }
-?>
+
+?>
\ No newline at end of file