From: Steffen Kamper Date: Wed, 24 Nov 2010 12:54:37 +0000 (+0000) Subject: Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_parsehtml X-Git-Tag: TYPO3_4-5-0beta2~160 X-Git-Url: http://git.typo3.org/Packages/TYPO3.CMS.git/commitdiff_plain/7543d184c9ab0feb7d2b504faa51e0d726c1e6fe Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_parsehtml git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9557 709f56b5-9817-0410-a4d7-c38de5d9e867 --- diff --git a/ChangeLog b/ChangeLog index e023e39f8cc3..9392bc2cf064 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 2010-11-24 Steffen Kamper + * Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_parsehtml * Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_pagetree * Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_pagerenderer * Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_page diff --git a/t3lib/class.t3lib_parsehtml.php b/t3lib/class.t3lib_parsehtml.php index 91a72b79d3b2..1b92a0f9cc80 100644 --- a/t3lib/class.t3lib_parsehtml.php +++ b/t3lib/class.t3lib_parsehtml.php @@ -1,29 +1,29 @@ )(.*)(\<\!\-\-[^\>]*)$/s', $content, $matches) === 1) { @@ -164,21 +146,21 @@ class t3lib_parsehtml { public static function substituteSubpart($content, $marker, $subpartContent, $recursive = 1, $keepMarker = 0) { $start = strpos($content, $marker); - if ($start === false) { + if ($start === FALSE) { return $content; } $startAM = $start + strlen($marker); - $stop = strpos($content, $marker, $startAM); + $stop = strpos($content, $marker, $startAM); - if ($stop===false) { + if ($stop === FALSE) { return $content; } - $stopAM = $stop + strlen($marker); - $before = substr($content, 0, $start); - $after = substr($content, $stopAM); - $between = substr($content, $startAM, $stop-$startAM); + $stopAM = $stop + strlen($marker); + $before = substr($content, 0, $start); + $after = substr($content, $stopAM); + $between = substr($content, $startAM, $stop - $startAM); if ($recursive) { $after = self::substituteSubpart( @@ -193,20 +175,20 @@ class t3lib_parsehtml { if ($keepMarker) { $matches = array(); if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) { - $before .= $marker.$matches[1]; - $between = $matches[2]; - $after = $matches[3] . $marker . $after; + $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; + $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 . $matches[1]; + $between = $matches[2]; + $after = $marker . $after; + } else { $before .= $marker; - $after = $marker . $after; + $after = $marker . $after; } } else { @@ -219,9 +201,9 @@ class t3lib_parsehtml { $matches = array(); if (preg_match('/^([^\<]*\-\-\>)(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) { $between = $matches[2]; - } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches)===1) { + } elseif (preg_match('/^(.*)(\<\!\-\-[^\>]*)$/s', $between, $matches) === 1) { $between = $matches[1]; - } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches)===1) { + } elseif (preg_match('/^([^\<]*\-\-\>)(.*)$/s', $between, $matches) === 1) { $between = $matches[2]; } } @@ -234,7 +216,7 @@ class t3lib_parsehtml { if (is_array($subpartContent)) { $between = $subpartContent[0] . $between . $subpartContent[1]; - } else { + } else { $between = $subpartContent; } @@ -328,11 +310,6 @@ class t3lib_parsehtml { } - - - - - /************************************ * * Parsing HTML code @@ -350,52 +327,52 @@ class t3lib_parsehtml { * @return array Even numbers in the array are outside the blocks, Odd numbers are block-content. * @see splitTags(), getAllParts(), removeFirstAndLastTag() */ - function splitIntoBlock($tag,$content,$eliminateExtraEndTags=0) { - $tags=array_unique(t3lib_div::trimExplode(',',$tag,1)); - $regexStr = '/\<\/?('.implode('|', $tags).')(\s*\>|\s[^\>]*\>)/si'; + function splitIntoBlock($tag, $content, $eliminateExtraEndTags = 0) { + $tags = array_unique(t3lib_div::trimExplode(',', $tag, 1)); + $regexStr = '/\<\/?(' . implode('|', $tags) . ')(\s*\>|\s[^\>]*\>)/si'; $parts = preg_split($regexStr, $content); - $newParts=array(); - $pointer=strlen($parts[0]); - $buffer=$parts[0]; - $nested=0; + $newParts = array(); + $pointer = strlen($parts[0]); + $buffer = $parts[0]; + $nested = 0; reset($parts); next($parts); - while(list($k,$v)=each($parts)) { - $isEndTag= substr($content,$pointer,2)=='')+1; - - if (!$isEndTag) { // We meet a start-tag: - if (!$nested) { // Ground level: - $newParts[]=$buffer; // previous buffer stored - $buffer=''; + while (list($k, $v) = each($parts)) { + $isEndTag = substr($content, $pointer, 2) == '') + 1; + + if (!$isEndTag) { // We meet a start-tag: + if (!$nested) { // Ground level: + $newParts[] = $buffer; // previous buffer stored + $buffer = ''; } - $nested++; // We are inside now! - $mbuffer=substr($content,$pointer,strlen($v)+$tagLen); // New buffer set and pointer increased - $pointer+=strlen($mbuffer); - $buffer.=$mbuffer; - } else { // If we meet an endtag: - $nested--; // decrease nested-level - $eliminated=0; - if ($eliminateExtraEndTags && $nested<0) { - $nested=0; - $eliminated=1; + $nested++; // We are inside now! + $mbuffer = substr($content, $pointer, strlen($v) + $tagLen); // New buffer set and pointer increased + $pointer += strlen($mbuffer); + $buffer .= $mbuffer; + } else { // If we meet an endtag: + $nested--; // decrease nested-level + $eliminated = 0; + if ($eliminateExtraEndTags && $nested < 0) { + $nested = 0; + $eliminated = 1; } else { - $buffer.=substr($content,$pointer,$tagLen); // In any case, add the endtag to current buffer and increase pointer + $buffer .= substr($content, $pointer, $tagLen); // In any case, add the endtag to current buffer and increase pointer } - $pointer+=$tagLen; - if (!$nested && !$eliminated) { // if we're back on ground level, (and not by eliminating tags... - $newParts[]=$buffer; - $buffer=''; + $pointer += $tagLen; + if (!$nested && !$eliminated) { // if we're back on ground level, (and not by eliminating tags... + $newParts[] = $buffer; + $buffer = ''; } - $mbuffer=substr($content,$pointer,strlen($v)); // New buffer set and pointer increased - $pointer+=strlen($mbuffer); - $buffer.=$mbuffer; + $mbuffer = substr($content, $pointer, strlen($v)); // New buffer set and pointer increased + $pointer += strlen($mbuffer); + $buffer .= $mbuffer; } } - $newParts[]=$buffer; + $newParts[] = $buffer; return $newParts; } @@ -411,30 +388,34 @@ class t3lib_parsehtml { * @return string Processed content * @see splitIntoBlock() */ - function splitIntoBlockRecursiveProc($tag,$content,&$procObj,$callBackContent,$callBackTags,$level=0) { - $parts = $this->splitIntoBlock($tag,$content,TRUE); - foreach($parts as $k => $v) { - if ($k%2) { + function splitIntoBlockRecursiveProc($tag, $content, &$procObj, $callBackContent, $callBackTags, $level = 0) { + $parts = $this->splitIntoBlock($tag, $content, TRUE); + foreach ($parts as $k => $v) { + if ($k % 2) { $firstTagName = $this->getFirstTagName($v, TRUE); $tagsArray = array(); $tagsArray['tag_start'] = $this->getFirstTag($v); - $tagsArray['tag_end'] = ''; + $tagsArray['tag_end'] = ''; $tagsArray['tag_name'] = strtolower($firstTagName); $tagsArray['add_level'] = 1; - $tagsArray['content'] = $this->splitIntoBlockRecursiveProc($tag,$this->removeFirstAndLastTag($v),$procObj,$callBackContent,$callBackTags,$level+$tagsArray['add_level']); + $tagsArray['content'] = $this->splitIntoBlockRecursiveProc($tag, $this->removeFirstAndLastTag($v), $procObj, $callBackContent, $callBackTags, $level + $tagsArray['add_level']); - if ($callBackTags) $tagsArray = $procObj->$callBackTags($tagsArray,$level); + if ($callBackTags) { + $tagsArray = $procObj->$callBackTags($tagsArray, $level); + } $parts[$k] = - $tagsArray['tag_start']. - $tagsArray['content']. - $tagsArray['tag_end']; + $tagsArray['tag_start'] . + $tagsArray['content'] . + $tagsArray['tag_end']; } else { - if ($callBackContent) $parts[$k] = $procObj->$callBackContent($parts[$k],$level); + if ($callBackContent) { + $parts[$k] = $procObj->$callBackContent($parts[$k], $level); + } } } - return implode('',$parts); + return implode('', $parts); } /** @@ -447,9 +428,9 @@ class t3lib_parsehtml { * @return array Even numbers in the array are outside the blocks, Odd numbers are block-content. * @see splitIntoBlock(), getAllParts(), removeFirstAndLastTag() */ - function splitTags($tag,$content) { - $tags = t3lib_div::trimExplode(',',$tag,1); - $regexStr = '/\<('.implode('|', $tags).')(\s[^>]*)?\/?>/si'; + function splitTags($tag, $content) { + $tags = t3lib_div::trimExplode(',', $tag, 1); + $regexStr = '/\<(' . implode('|', $tags) . ')(\s[^>]*)?\/?>/si'; $parts = preg_split($regexStr, $content); $pointer = strlen($parts[0]); @@ -457,17 +438,17 @@ class t3lib_parsehtml { $newParts[] = $parts[0]; reset($parts); next($parts); - while(list($k,$v)=each($parts)) { - $tagLen = strcspn(substr($content,$pointer),'>')+1; + while (list($k, $v) = each($parts)) { + $tagLen = strcspn(substr($content, $pointer), '>') + 1; // Set tag: - $tag = substr($content,$pointer,$tagLen); // New buffer set and pointer increased + $tag = substr($content, $pointer, $tagLen); // New buffer set and pointer increased $newParts[] = $tag; - $pointer+= strlen($tag); + $pointer += strlen($tag); // Set content: $newParts[] = $v; - $pointer+= strlen($v); + $pointer += strlen($v); } return $newParts; } @@ -481,12 +462,14 @@ class t3lib_parsehtml { * @return array Tag-parts/Non-tag-parts depending on input argument settings * @see splitIntoBlock(), splitTags() */ - function getAllParts($parts,$tag_parts=1,$include_tag=1) { - $newParts=array(); - foreach ($parts as $k => $v) { - if (($k+($tag_parts?0:1))%2) { - if (!$include_tag) $v=$this->removeFirstAndLastTag($v); - $newParts[]=$v; + function getAllParts($parts, $tag_parts = 1, $include_tag = 1) { + $newParts = array(); + foreach ($parts as $k => $v) { + if (($k + ($tag_parts ? 0 : 1)) % 2) { + if (!$include_tag) { + $v = $this->removeFirstAndLastTag($v); + } + $newParts[] = $v; } } return $newParts; @@ -499,13 +482,13 @@ class t3lib_parsehtml { * @param string String to process * @return string */ - function removeFirstAndLastTag($str) { + function removeFirstAndLastTag($str) { // End of first tag: - $start = strpos($str,'>'); + $start = strpos($str, '>'); // Begin of last tag: - $end = strrpos($str,'<'); + $end = strrpos($str, '<'); // return - return substr($str, $start+1, $end-$start-1); + return substr($str, $start + 1, $end - $start - 1); } /** @@ -515,10 +498,10 @@ class t3lib_parsehtml { * @param string HTML string with tags * @return string */ - function getFirstTag($str) { + function getFirstTag($str) { // First: - $endLen = strpos($str,'>')+1; - return substr($str,0,$endLen); + $endLen = strpos($str, '>') + 1; + return substr($str, 0, $endLen); } /** @@ -529,10 +512,10 @@ class t3lib_parsehtml { * @return string Tag name in upper case * @see getFirstTag() */ - function getFirstTagName($str,$preserveCase=FALSE) { + function getFirstTagName($str, $preserveCase = FALSE) { $matches = array(); - if (preg_match('/^\s*\<([^\s\>]+)(\s|\>)/', $str, $matches)===1) { - if (!$preserveCase) { + if (preg_match('/^\s*\<([^\s\>]+)(\s|\>)/', $str, $matches) === 1) { + if (!$preserveCase) { return strtoupper($matches[1]); } return $matches[1]; @@ -548,35 +531,35 @@ class t3lib_parsehtml { * @param boolean If set, the attribute values are de-htmlspecialchar'ed. Should actually always be set! * @return array array(Tag attributes,Attribute meta-data) */ - function get_tag_attributes($tag,$deHSC=0) { - list($components,$metaC) = $this->split_tag_attributes($tag); - $name = ''; // attribute name is stored here - $valuemode = false; + function get_tag_attributes($tag, $deHSC = 0) { + list($components, $metaC) = $this->split_tag_attributes($tag); + $name = ''; // attribute name is stored here + $valuemode = FALSE; $attributes = array(); $attributesMeta = array(); - if (is_array($components)) { - foreach ($components as $key => $val) { - if ($val != '=') { // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value - if ($valuemode) { - if ($name) { - $attributes[$name] = $deHSC?t3lib_div::htmlspecialchars_decode($val):$val; - $attributesMeta[$name]['dashType']=$metaC[$key]; + if (is_array($components)) { + foreach ($components as $key => $val) { + if ($val != '=') { // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value + if ($valuemode) { + if ($name) { + $attributes[$name] = $deHSC ? t3lib_div::htmlspecialchars_decode($val) : $val; + $attributesMeta[$name]['dashType'] = $metaC[$key]; $name = ''; } } else { - if ($namekey = preg_replace('/[^[:alnum:]_\:\-]/','',$val)) { + if ($namekey = preg_replace('/[^[:alnum:]_\:\-]/', '', $val)) { $name = strtolower($namekey); - $attributesMeta[$name]=array(); - $attributesMeta[$name]['origTag']=$namekey; + $attributesMeta[$name] = array(); + $attributesMeta[$name]['origTag'] = $namekey; $attributes[$name] = ''; } } - $valuemode = false; + $valuemode = FALSE; } else { - $valuemode = true; + $valuemode = TRUE; } } - return array($attributes,$attributesMeta); + return array($attributes, $attributesMeta); } } @@ -589,9 +572,9 @@ class t3lib_parsehtml { * @access private * @see t3lib_div::split_tag_attributes() */ - function split_tag_attributes($tag) { + function split_tag_attributes($tag) { $matches = array(); - if (preg_match('/(\<[^\s]+\s+)?(.*?)\s*(\>)?$/s', $tag, $matches)!==1) { + if (preg_match('/(\<[^\s]+\s+)?(.*?)\s*(\>)?$/s', $tag, $matches) !== 1) { return array(array(), array()); } $tag_tmp = $matches[2]; @@ -599,19 +582,19 @@ class t3lib_parsehtml { $metaValue = array(); $value = array(); $matches = array(); - if (preg_match_all('/("[^"]*"|\'[^\']*\'|[^\s"\'\=]+|\=)/s', $tag_tmp, $matches)>0) { - foreach ($matches[1] as $part) { + if (preg_match_all('/("[^"]*"|\'[^\']*\'|[^\s"\'\=]+|\=)/s', $tag_tmp, $matches) > 0) { + foreach ($matches[1] as $part) { $firstChar = substr($part, 0, 1); - if ($firstChar=='"' || $firstChar=="'") { + if ($firstChar == '"' || $firstChar == "'") { $metaValue[] = $firstChar; $value[] = substr($part, 1, -1); - } else { + } else { $metaValue[] = ''; $value[] = $part; } } } - return array($value,$metaValue); + return array($value, $metaValue); } /** @@ -627,40 +610,44 @@ class t3lib_parsehtml { * @param string Tag names for solo tags (eg. img, br or input) in lowercase, commalist ("img,br,input") * @return array Analyse data. */ - function checkTagTypeCounts($content,$blockTags='a,b,blockquote,body,div,em,font,form,h1,h2,h3,h4,h5,h6,i,li,map,ol,option,p,pre,select,span,strong,table,td,textarea,tr,u,ul', $soloTags='br,hr,img,input,area') { + function checkTagTypeCounts($content, $blockTags = 'a,b,blockquote,body,div,em,font,form,h1,h2,h3,h4,h5,h6,i,li,map,ol,option,p,pre,select,span,strong,table,td,textarea,tr,u,ul', $soloTags = 'br,hr,img,input,area') { $content = strtolower($content); - $analyzedOutput=array(); - $analyzedOutput['counts']=array(); // Counts appearances of start-tags - $analyzedOutput['errors']=array(); // Lists ERRORS - $analyzedOutput['warnings']=array(); // Lists warnings. - $analyzedOutput['blocks']=array(); // Lists stats for block-tags - $analyzedOutput['solo']=array(); // Lists stats for solo-tags + $analyzedOutput = array(); + $analyzedOutput['counts'] = array(); // Counts appearances of start-tags + $analyzedOutput['errors'] = array(); // Lists ERRORS + $analyzedOutput['warnings'] = array(); // Lists warnings. + $analyzedOutput['blocks'] = array(); // Lists stats for block-tags + $analyzedOutput['solo'] = array(); // Lists stats for solo-tags // Block tags, must have endings... - $blockTags = explode(',',$blockTags); - foreach($blockTags as $tagName) { - $countBegin = count(preg_split('/\<'.$tagName.'(\s|\>)/s',$content))-1; - $countEnd = count(preg_split('/\<\/'.$tagName.'(\s|\>)/s',$content))-1; - $analyzedOutput['blocks'][$tagName]=array($countBegin,$countEnd,$countBegin-$countEnd); - if ($countBegin) $analyzedOutput['counts'][$tagName]=$countBegin; - if ($countBegin-$countEnd) { - if ($countBegin-$countEnd > 0) { - $analyzedOutput['errors'][$tagName]='There were more start-tags ('.$countBegin.') than end-tags ('.$countEnd.') for the element "'.$tagName.'". There should be an equal amount!'; + $blockTags = explode(',', $blockTags); + foreach ($blockTags as $tagName) { + $countBegin = count(preg_split('/\<' . $tagName . '(\s|\>)/s', $content)) - 1; + $countEnd = count(preg_split('/\<\/' . $tagName . '(\s|\>)/s', $content)) - 1; + $analyzedOutput['blocks'][$tagName] = array($countBegin, $countEnd, $countBegin - $countEnd); + if ($countBegin) { + $analyzedOutput['counts'][$tagName] = $countBegin; + } + if ($countBegin - $countEnd) { + if ($countBegin - $countEnd > 0) { + $analyzedOutput['errors'][$tagName] = 'There were more start-tags (' . $countBegin . ') than end-tags (' . $countEnd . ') for the element "' . $tagName . '". There should be an equal amount!'; } else { - $analyzedOutput['warnings'][$tagName]='There were more end-tags ('.$countEnd.') than start-tags ('.$countBegin.') for the element "'.$tagName.'". There should be an equal amount! However the problem is not fatal.'; + $analyzedOutput['warnings'][$tagName] = 'There were more end-tags (' . $countEnd . ') than start-tags (' . $countBegin . ') for the element "' . $tagName . '". There should be an equal amount! However the problem is not fatal.'; } } } // Solo tags, must NOT have endings... - $soloTags = explode(',',$soloTags); - foreach($soloTags as $tagName) { - $countBegin = count(preg_split('/\<'.$tagName.'(\s|\>)/s',$content))-1; - $countEnd = count(preg_split('/\<\/'.$tagName.'(\s|\>)/s',$content))-1; - $analyzedOutput['solo'][$tagName]=array($countBegin,$countEnd); - if ($countBegin) $analyzedOutput['counts'][$tagName]=$countBegin; - if ($countEnd) { - $analyzedOutput['warnings'][$tagName]='There were end-tags found ('.$countEnd.') for the element "'.$tagName.'". This was not expected (although XHTML technically allows it).'; + $soloTags = explode(',', $soloTags); + foreach ($soloTags as $tagName) { + $countBegin = count(preg_split('/\<' . $tagName . '(\s|\>)/s', $content)) - 1; + $countEnd = count(preg_split('/\<\/' . $tagName . '(\s|\>)/s', $content)) - 1; + $analyzedOutput['solo'][$tagName] = array($countBegin, $countEnd); + if ($countBegin) { + $analyzedOutput['counts'][$tagName] = $countBegin; + } + if ($countEnd) { + $analyzedOutput['warnings'][$tagName] = 'There were end-tags found (' . $countEnd . ') for the element "' . $tagName . '". This was not expected (although XHTML technically allows it).'; } } @@ -668,16 +655,6 @@ class t3lib_parsehtml { } - - - - - - - - - - /********************************* * * Clean HTML code @@ -690,28 +667,28 @@ class t3lib_parsehtml { * Initializing the $tags array to allow a list of tags (in this case ,, and ), set it like this: $tags = array_flip(explode(',','b,a,i,u')) * If the value of the $tags[$tagname] entry is an array, advanced processing of the tags is initialized. These are the options: * - * $tags[$tagname] = Array( - * 'overrideAttribs' => '' If set, this string is preset as the attributes of the tag - * 'allowedAttribs' => '0' (zero) = no attributes allowed, '[commalist of attributes]' = only allowed attributes. If blank, all attributes are allowed. - * 'fixAttrib' => Array( - * '[attribute name]' => Array ( - * 'set' => Force the attribute value to this value. - * 'unset' => Boolean: If set, the attribute is unset. - * 'default' => If no attribute exists by this name, this value is set as default value (if this value is not blank) - * 'always' => Boolean. If set, the attribute is always processed. Normally an attribute is processed only if it exists - * 'trim,intval,lower,upper' => All booleans. If any of these keys are set, the value is passed through the respective PHP-functions. - * 'range' => Array ('[low limit]','[high limit, optional]') Setting integer range. - * 'list' => Array ('[value1/default]','[value2]','[value3]') Attribute must be in this list. If not, the value is set to the first element. - * 'removeIfFalse' => Boolean/'blank'. If set, then the attribute is removed if it is 'false'. If this value is set to 'blank' then the value must be a blank string (that means a 'zero' value will not be removed) - * 'removeIfEquals' => [value] If the attribute value matches the value set here, then it is removed. - * 'casesensitiveComp' => 1 If set, then the removeIfEquals and list comparisons will be case sensitive. Otherwise not. - * ) - * ), - * 'protect' => '', Boolean. If set, the tag <> is converted to < and > - * 'remap' => '', String. If set, the tagname is remapped to this tagname - * 'rmTagIfNoAttrib' => '', Boolean. If set, then the tag is removed if no attributes happend to be there. - * 'nesting' => '', Boolean/'global'. If set true, then this tag must have starting and ending tags in the correct order. Any tags not in this order will be discarded. Thus '' will be converted to ''. Is the value 'global' then true nesting in relation to other tags marked for 'global' nesting control is preserved. This means that if and are set for global nesting then this string '' is converted to '' - * ) + * $tags[$tagname] = Array( + * 'overrideAttribs' => '' If set, this string is preset as the attributes of the tag + * 'allowedAttribs' => '0' (zero) = no attributes allowed, '[commalist of attributes]' = only allowed attributes. If blank, all attributes are allowed. + * 'fixAttrib' => Array( + * '[attribute name]' => Array ( + * 'set' => Force the attribute value to this value. + * 'unset' => Boolean: If set, the attribute is unset. + * 'default' => If no attribute exists by this name, this value is set as default value (if this value is not blank) + * 'always' => Boolean. If set, the attribute is always processed. Normally an attribute is processed only if it exists + * 'trim,intval,lower,upper' => All booleans. If any of these keys are set, the value is passed through the respective PHP-functions. + * 'range' => Array ('[low limit]','[high limit, optional]') Setting integer range. + * 'list' => Array ('[value1/default]','[value2]','[value3]') Attribute must be in this list. If not, the value is set to the first element. + * 'removeIfFalse' => Boolean/'blank'. If set, then the attribute is removed if it is 'false'. If this value is set to 'blank' then the value must be a blank string (that means a 'zero' value will not be removed) + * 'removeIfEquals' => [value] If the attribute value matches the value set here, then it is removed. + * 'casesensitiveComp' => 1 If set, then the removeIfEquals and list comparisons will be case sensitive. Otherwise not. + * ) + * ), + * 'protect' => '', Boolean. If set, the tag <> is converted to < and > + * 'remap' => '', String. If set, the tagname is remapped to this tagname + * 'rmTagIfNoAttrib' => '', Boolean. If set, then the tag is removed if no attributes happend to be there. + * 'nesting' => '', Boolean/'global'. If set true, then this tag must have starting and ending tags in the correct order. Any tags not in this order will be discarded. Thus '' will be converted to ''. Is the value 'global' then true nesting in relation to other tags marked for 'global' nesting control is preserved. This means that if and are set for global nesting then this string '' is converted to '' + * ) * * @param string $content; is the HTML-content being processed. This is also the result being returned. * @param array $tags; is an array where each key is a tagname in lowercase. Only tags present as keys in this array are preserved. The value of the key can be an array with a vast number of options to configure. @@ -720,94 +697,112 @@ class t3lib_parsehtml { * @param array Configuration array send along as $conf to the internal functions ->processContent() and ->processTag() * @return string Processed HTML content */ - function HTMLcleaner($content, $tags=array(),$keepAll=0,$hSC=0,$addConfig=array()) { + function HTMLcleaner($content, $tags = array(), $keepAll = 0, $hSC = 0, $addConfig = array()) { $newContent = array(); - $tokArr = explode('<',$content); - $newContent[] = $this->processContent(current($tokArr),$hSC,$addConfig); + $tokArr = explode('<', $content); + $newContent[] = $this->processContent(current($tokArr), $hSC, $addConfig); next($tokArr); $c = 1; $tagRegister = array(); $tagStack = array(); - $inComment = false; $skipTag = false; - while(list(,$tok)=each($tokArr)) { + $inComment = FALSE; + $skipTag = FALSE; + 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. + 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 + // 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; + $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 + 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; + $inComment = TRUE; continue; } - // Start and end of comment are both in the current token. Add comment and proceed with rest of the token + // 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; + $skipTag = TRUE; } - $firstChar = substr($tok,0,1); - 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 and - $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; - $tagContent = substr($tok,$endTag,$tagEnd-$endTag); - $tagParts = preg_split('/\s+/s',$tagContent,2); + $firstChar = substr($tok, 0, 1); + 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 and + $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; + $tagContent = substr($tok, $endTag, $tagEnd - $endTag); + $tagParts = preg_split('/\s+/s', $tagContent, 2); $tagName = strtolower($tagParts[0]); - if (isset($tags[$tagName])) { - if (is_array($tags[$tagName])) { // If there is processing to do for the tag: + if (isset($tags[$tagName])) { + if (is_array($tags[$tagName])) { // If there is processing to do for the tag: - if (!$endTag) { // If NOT an endtag, do attribute processing (added dec. 2003) + if (!$endTag) { // If NOT an endtag, do attribute processing (added dec. 2003) // Override attributes - if (strcmp($tags[$tagName]['overrideAttribs'],'')) { - $tagParts[1]=$tags[$tagName]['overrideAttribs']; + if (strcmp($tags[$tagName]['overrideAttribs'], '')) { + $tagParts[1] = $tags[$tagName]['overrideAttribs']; } // Allowed tags - if (strcmp($tags[$tagName]['allowedAttribs'],'')) { - if (!strcmp($tags[$tagName]['allowedAttribs'],'0')) { // No attribs allowed - $tagParts[1]=''; + if (strcmp($tags[$tagName]['allowedAttribs'], '')) { + if (!strcmp($tags[$tagName]['allowedAttribs'], '0')) { // No attribs allowed + $tagParts[1] = ''; } elseif (trim($tagParts[1])) { $tagAttrib = $this->get_tag_attributes($tagParts[1]); - $tagParts[1]=''; + $tagParts[1] = ''; $newTagAttrib = array(); - if (!($tList = $tags[$tagName]['_allowedAttribs'])) { + if (!($tList = $tags[$tagName]['_allowedAttribs'])) { // Just explode attribts for tag once - $tList = $tags[$tagName]['_allowedAttribs'] = t3lib_div::trimExplode(',',strtolower($tags[$tagName]['allowedAttribs']),1); + $tList = $tags[$tagName]['_allowedAttribs'] = t3lib_div::trimExplode(',', strtolower($tags[$tagName]['allowedAttribs']), 1); } - foreach ($tList as $allowTag) { - if (isset($tagAttrib[0][$allowTag])) $newTagAttrib[$allowTag]=$tagAttrib[0][$allowTag]; + foreach ($tList as $allowTag) { + if (isset($tagAttrib[0][$allowTag])) { + $newTagAttrib[$allowTag] = $tagAttrib[0][$allowTag]; + } } - $tagParts[1]=$this->compileTagAttribs($newTagAttrib,$tagAttrib[1]); + $tagParts[1] = $this->compileTagAttribs($newTagAttrib, $tagAttrib[1]); } } // Fixed attrib values - if (is_array($tags[$tagName]['fixAttrib'])) { + if (is_array($tags[$tagName]['fixAttrib'])) { $tagAttrib = $this->get_tag_attributes($tagParts[1]); - $tagParts[1]=''; + $tagParts[1] = ''; foreach ($tags[$tagName]['fixAttrib'] as $attr => $params) { - if (strlen($params['set'])) $tagAttrib[0][$attr] = $params['set']; - if (strlen($params['unset'])) unset($tagAttrib[0][$attr]); - if (strcmp($params['default'],'') && !isset($tagAttrib[0][$attr])) $tagAttrib[0][$attr]=$params['default']; - if ($params['always'] || isset($tagAttrib[0][$attr])) { - if ($params['trim']) {$tagAttrib[0][$attr]=trim($tagAttrib[0][$attr]);} - if ($params['intval']) {$tagAttrib[0][$attr]=intval($tagAttrib[0][$attr]);} - if ($params['lower']) {$tagAttrib[0][$attr]=strtolower($tagAttrib[0][$attr]);} - if ($params['upper']) {$tagAttrib[0][$attr]=strtoupper($tagAttrib[0][$attr]);} - if ($params['range']) { - if (isset($params['range'][1])) { - $tagAttrib[0][$attr]=t3lib_div::intInRange($tagAttrib[0][$attr],intval($params['range'][0]),intval($params['range'][1])); + if (strlen($params['set'])) { + $tagAttrib[0][$attr] = $params['set']; + } + if (strlen($params['unset'])) { + unset($tagAttrib[0][$attr]); + } + if (strcmp($params['default'], '') && !isset($tagAttrib[0][$attr])) { + $tagAttrib[0][$attr] = $params['default']; + } + if ($params['always'] || isset($tagAttrib[0][$attr])) { + if ($params['trim']) { + $tagAttrib[0][$attr] = trim($tagAttrib[0][$attr]); + } + if ($params['intval']) { + $tagAttrib[0][$attr] = intval($tagAttrib[0][$attr]); + } + if ($params['lower']) { + $tagAttrib[0][$attr] = strtolower($tagAttrib[0][$attr]); + } + if ($params['upper']) { + $tagAttrib[0][$attr] = strtoupper($tagAttrib[0][$attr]); + } + if ($params['range']) { + if (isset($params['range'][1])) { + $tagAttrib[0][$attr] = t3lib_div::intInRange($tagAttrib[0][$attr], intval($params['range'][0]), intval($params['range'][1])); } else { - $tagAttrib[0][$attr]=t3lib_div::intInRange($tagAttrib[0][$attr],intval($params['range'][0])); + $tagAttrib[0][$attr] = t3lib_div::intInRange($tagAttrib[0][$attr], intval($params['range'][0])); } } if (is_array($params['list'])) { @@ -827,71 +822,77 @@ class t3lib_parsehtml { $tagAttrib[0][$attr] = ''; } } else { - if (!in_array($this->caseShift($tagAttrib[0][$attr],$params['casesensitiveComp']),$this->caseShift($params['list'],$params['casesensitiveComp'],$tagName))) { - $tagAttrib[0][$attr]=$params['list'][0]; + if (!in_array($this->caseShift($tagAttrib[0][$attr], $params['casesensitiveComp']), $this->caseShift($params['list'], $params['casesensitiveComp'], $tagName))) { + $tagAttrib[0][$attr] = $params['list'][0]; } } } - if (($params['removeIfFalse'] && $params['removeIfFalse']!='blank' && !$tagAttrib[0][$attr]) || ($params['removeIfFalse']=='blank' && !strcmp($tagAttrib[0][$attr],''))) { + if (($params['removeIfFalse'] && $params['removeIfFalse'] != 'blank' && !$tagAttrib[0][$attr]) || ($params['removeIfFalse'] == 'blank' && !strcmp($tagAttrib[0][$attr], ''))) { unset($tagAttrib[0][$attr]); } - if (strcmp($params['removeIfEquals'],'') && !strcmp($this->caseShift($tagAttrib[0][$attr],$params['casesensitiveComp']),$this->caseShift($params['removeIfEquals'],$params['casesensitiveComp']))) { + if (strcmp($params['removeIfEquals'], '') && !strcmp($this->caseShift($tagAttrib[0][$attr], $params['casesensitiveComp']), $this->caseShift($params['removeIfEquals'], $params['casesensitiveComp']))) { unset($tagAttrib[0][$attr]); } - if ($params['prefixLocalAnchors']) { - if (substr($tagAttrib[0][$attr],0,1)=='#') { + if ($params['prefixLocalAnchors']) { + if (substr($tagAttrib[0][$attr], 0, 1) == '#') { $prefix = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'); - $tagAttrib[0][$attr] = $prefix.$tagAttrib[0][$attr]; - if ($params['prefixLocalAnchors']==2 && t3lib_div::isFirstPartOfStr($prefix,t3lib_div::getIndpEnv('TYPO3_SITE_URL'))) { - $tagAttrib[0][$attr] = substr($tagAttrib[0][$attr],strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL'))); + $tagAttrib[0][$attr] = $prefix . $tagAttrib[0][$attr]; + if ($params['prefixLocalAnchors'] == 2 && t3lib_div::isFirstPartOfStr($prefix, t3lib_div::getIndpEnv('TYPO3_SITE_URL'))) { + $tagAttrib[0][$attr] = substr($tagAttrib[0][$attr], strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL'))); } } } - if ($params['prefixRelPathWith']) { + if ($params['prefixRelPathWith']) { $urlParts = parse_url($tagAttrib[0][$attr]); - if (!$urlParts['scheme'] && substr($urlParts['path'],0,1)!='/') { // If it is NOT an absolute URL (by http: or starting "/") - $tagAttrib[0][$attr] = $params['prefixRelPathWith'].$tagAttrib[0][$attr]; + if (!$urlParts['scheme'] && substr($urlParts['path'], 0, 1) != '/') { // If it is NOT an absolute URL (by http: or starting "/") + $tagAttrib[0][$attr] = $params['prefixRelPathWith'] . $tagAttrib[0][$attr]; } } - if ($params['userFunc']) { - $tagAttrib[0][$attr] = t3lib_div::callUserFunction($params['userFunc'],$tagAttrib[0][$attr],$this); + if ($params['userFunc']) { + $tagAttrib[0][$attr] = t3lib_div::callUserFunction($params['userFunc'], $tagAttrib[0][$attr], $this); } } } - $tagParts[1]=$this->compileTagAttribs($tagAttrib[0],$tagAttrib[1]); + $tagParts[1] = $this->compileTagAttribs($tagAttrib[0], $tagAttrib[1]); } - } else { // If endTag, remove any possible attributes: - $tagParts[1]=''; + } else { // If endTag, remove any possible attributes: + $tagParts[1] = ''; } // Protecting the tag by converting < and > to < and > ?? - if ($tags[$tagName]['protect']) { - $lt = '<'; $gt = '>'; + if ($tags[$tagName]['protect']) { + $lt = '<'; + $gt = '>'; } else { - $lt = '<'; $gt = '>'; + $lt = '<'; + $gt = '>'; } // Remapping tag name? - if ($tags[$tagName]['remap']) $tagParts[0] = $tags[$tagName]['remap']; + if ($tags[$tagName]['remap']) { + $tagParts[0] = $tags[$tagName]['remap']; + } // rmTagIfNoAttrib - if ($endTag || trim($tagParts[1]) || !$tags[$tagName]['rmTagIfNoAttrib']) { + if ($endTag || trim($tagParts[1]) || !$tags[$tagName]['rmTagIfNoAttrib']) { $setTag = !$tags[$tagName]['rmTagIfNoAttrib']; - if ($tags[$tagName]['nesting']) { - if (!is_array($tagRegister[$tagName])) $tagRegister[$tagName]=array(); + if ($tags[$tagName]['nesting']) { + if (!is_array($tagRegister[$tagName])) { + $tagRegister[$tagName] = array(); + } - if ($endTag) { -/* if ($tags[$tagName]['nesting']=='global') { + if ($endTag) { + /* if ($tags[$tagName]['nesting']=='global') { + $lastEl = end($tagStack); + $correctTag = !strcmp($tagName,$lastEl); + } else $correctTag=1; + */ + $correctTag = 1; + if ($tags[$tagName]['nesting'] == 'global') { $lastEl = end($tagStack); - $correctTag = !strcmp($tagName,$lastEl); - } else $correctTag=1; - */ - $correctTag=1; - if ($tags[$tagName]['nesting']=='global') { - $lastEl = end($tagStack); - if (strcmp($tagName,$lastEl)) { - if (in_array($tagName,$tagStack)) { - while(count($tagStack) && strcmp($tagName,$lastEl)) { + if (strcmp($tagName, $lastEl)) { + if (in_array($tagName, $tagStack)) { + while (count($tagStack) && strcmp($tagName, $lastEl)) { $elPos = end($tagRegister[$lastEl]); unset($newContent[$elPos]); @@ -900,56 +901,62 @@ class t3lib_parsehtml { $lastEl = end($tagStack); } } else { - $correctTag=0; // In this case the + $correctTag = 0; // In this case the } } } - if (!count($tagRegister[$tagName]) || !$correctTag) { - $setTag=0; + if (!count($tagRegister[$tagName]) || !$correctTag) { + $setTag = 0; } else { array_pop($tagRegister[$tagName]); - if ($tags[$tagName]['nesting']=='global') {array_pop($tagStack);} + if ($tags[$tagName]['nesting'] == 'global') { + array_pop($tagStack); + } } } else { - array_push($tagRegister[$tagName],$c); - if ($tags[$tagName]['nesting']=='global') {array_push($tagStack,$tagName);} + array_push($tagRegister[$tagName], $c); + if ($tags[$tagName]['nesting'] == 'global') { + array_push($tagStack, $tagName); + } } } - if ($setTag) { + if ($setTag) { // Setting the tag - $newContent[$c++]=$this->processTag($lt.($endTag?'/':'').trim($tagParts[0].' '.$tagParts[1]).$gt,$addConfig,$endTag,$lt=='<'); + $newContent[$c++] = $this->processTag($lt . ($endTag ? '/' : '') . trim($tagParts[0] . ' ' . $tagParts[1]) . $gt, $addConfig, $endTag, $lt == '<'); } } } else { - $newContent[$c++]=$this->processTag('<'.($endTag?'/':'').$tagContent.'>',$addConfig,$endTag); + $newContent[$c++] = $this->processTag('<' . ($endTag ? '/' : '') . $tagContent . '>', $addConfig, $endTag); } - } elseif ($keepAll) { // This is if the tag was not defined in the array for processing: - if (!strcmp($keepAll,'protect')) { - $lt = '<'; $gt = '>'; + } elseif ($keepAll) { // This is if the tag was not defined in the array for processing: + if (!strcmp($keepAll, 'protect')) { + $lt = '<'; + $gt = '>'; } else { - $lt = '<'; $gt = '>'; + $lt = '<'; + $gt = '>'; } - $newContent[$c++]=$this->processTag($lt.($endTag?'/':'').$tagContent.$gt,$addConfig,$endTag,$lt=='<'); + $newContent[$c++] = $this->processTag($lt . ($endTag ? '/' : '') . $tagContent . $gt, $addConfig, $endTag, $lt == '<'); } - $newContent[$c++]=$this->processContent(substr($tok,$tagEnd+1),$hSC,$addConfig); + $newContent[$c++] = $this->processContent(substr($tok, $tagEnd + 1), $hSC, $addConfig); } else { - $newContent[$c++]=$this->processContent('<'.$tok,$hSC,$addConfig); // There were not end-bracket, so no tag... + $newContent[$c++] = $this->processContent('<' . $tok, $hSC, $addConfig); // There were not end-bracket, so no tag... } } else { - $newContent[$c++]=$this->processContent(($skipTag ? '' : '<') . $tok, $hSC, $addConfig); // It was not a tag anyways - $skipTag = false; + $newContent[$c++] = $this->processContent(($skipTag ? '' : '<') . $tok, $hSC, $addConfig); // It was not a tag anyways + $skipTag = FALSE; } } // Unsetting tags: - foreach ($tagRegister as $tag => $positions) { - foreach ($positions as $pKey) { + foreach ($tagRegister as $tag => $positions) { + foreach ($positions as $pKey) { unset($newContent[$pKey]); } } - return implode('',$newContent); + return implode('', $newContent); } /** @@ -959,16 +966,16 @@ class t3lib_parsehtml { * @param integer Direction: forth ($dir=1, dir=2 for preserving entities) AND back ($dir=-1) * @return string Output value */ - function bidir_htmlspecialchars($value,$dir) { - if ($dir==1) { + function bidir_htmlspecialchars($value, $dir) { + if ($dir == 1) { $value = htmlspecialchars($value); - } elseif ($dir==2) { + } elseif ($dir == 2) { $value = t3lib_div::deHSCentities(htmlspecialchars($value)); - } elseif ($dir==-1) { - $value = str_replace('>','>',$value); - $value = str_replace('<','<',$value); - $value = str_replace('"','"',$value); - $value = str_replace('&','&',$value); + } elseif ($dir == -1) { + $value = str_replace('>', '>', $value); + $value = str_replace('<', '<', $value); + $value = str_replace('"', '"', $value); + $value = str_replace('&', '&', $value); } return $value; } @@ -982,25 +989,25 @@ class t3lib_parsehtml { * @param string Suffix string (put after the resource). * @return string Processed HTML content */ - function prefixResourcePath($main_prefix,$content,$alternatives=array(),$suffix='') { + function prefixResourcePath($main_prefix, $content, $alternatives = array(), $suffix = '') { - $parts = $this->splitTags('embed,td,table,body,img,input,form,link,script,a,param',$content); - foreach ($parts as $k => $v) { - if ($k%2) { + $parts = $this->splitTags('embed,td,table,body,img,input,form,link,script,a,param', $content); + foreach ($parts as $k => $v) { + if ($k % 2) { $params = $this->get_tag_attributes($v); - $tagEnd = substr($v,-2)=='/>' ? ' />' : '>'; // Detect tag-ending so that it is re-applied correctly. - $firstTagName = $this->getFirstTagName($v); // The 'name' of the first tag - $somethingDone=0; + $tagEnd = substr($v, -2) == '/>' ? ' />' : '>'; // Detect tag-ending so that it is re-applied correctly. + $firstTagName = $this->getFirstTagName($v); // The 'name' of the first tag + $somethingDone = 0; $prefix = isset($alternatives[strtoupper($firstTagName)]) ? $alternatives[strtoupper($firstTagName)] : $main_prefix; - switch(strtolower($firstTagName)) { + switch (strtolower($firstTagName)) { // background - attribute: case 'td': case 'body': case 'table': $src = $params[0]['background']; - if ($src) { - $params[0]['background'] = $this->prefixRelPath($prefix,$params[0]['background'],$suffix); - $somethingDone=1; + if ($src) { + $params[0]['background'] = $this->prefixRelPath($prefix, $params[0]['background'], $suffix); + $somethingDone = 1; } break; // src attribute @@ -1009,25 +1016,25 @@ class t3lib_parsehtml { case 'script': case 'embed': $src = $params[0]['src']; - if ($src) { - $params[0]['src'] = $this->prefixRelPath($prefix,$params[0]['src'],$suffix); - $somethingDone=1; + if ($src) { + $params[0]['src'] = $this->prefixRelPath($prefix, $params[0]['src'], $suffix); + $somethingDone = 1; } break; case 'link': case 'a': $src = $params[0]['href']; - if ($src) { - $params[0]['href'] = $this->prefixRelPath($prefix,$params[0]['href'],$suffix); - $somethingDone=1; + if ($src) { + $params[0]['href'] = $this->prefixRelPath($prefix, $params[0]['href'], $suffix); + $somethingDone = 1; } break; // action attribute case 'form': $src = $params[0]['action']; - if ($src) { - $params[0]['action'] = $this->prefixRelPath($prefix,$params[0]['action'],$suffix); - $somethingDone=1; + if ($src) { + $params[0]['action'] = $this->prefixRelPath($prefix, $params[0]['action'], $suffix); + $somethingDone = 1; } break; // value attribute @@ -1041,25 +1048,25 @@ class t3lib_parsehtml { } break; } - if ($somethingDone) { - $tagParts = preg_split('/\s+/s',$v,2); - $tagParts[1]=$this->compileTagAttribs($params[0],$params[1]); - $parts[$k] = '<'.trim(strtolower($firstTagName).' '.$tagParts[1]).$tagEnd; + if ($somethingDone) { + $tagParts = preg_split('/\s+/s', $v, 2); + $tagParts[1] = $this->compileTagAttribs($params[0], $params[1]); + $parts[$k] = '<' . trim(strtolower($firstTagName) . ' ' . $tagParts[1]) . $tagEnd; } } } - $content = implode('',$parts); + $content = implode('', $parts); // Fix