30 const VOID_ELEMENTS =
'area|base|br|col|command|embed|hr|img|input|keygen|meta|param|source|track|wbr';
40 $start = strpos($content, $marker);
41 if ($start === FALSE) {
44 $start += strlen($marker);
45 $stop = strpos($content, $marker, $start);
48 if ($stop === FALSE) {
51 $content = substr($content, $start, $stop - $start);
53 if (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $content, $matches) === 1) {
58 if (preg_match(
'/(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $content, $matches) === 1) {
63 if (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)$/s', $content, $matches) === 1) {
79 static public function substituteSubpart($content, $marker, $subpartContent, $recursive = TRUE, $keepMarker = FALSE) {
80 $start = strpos($content, $marker);
81 if ($start === FALSE) {
84 $startAM = $start + strlen($marker);
85 $stop = strpos($content, $marker, $startAM);
86 if ($stop === FALSE) {
89 $stopAM = $stop + strlen($marker);
90 $before = substr($content, 0, $start);
91 $after = substr($content, $stopAM);
92 $between = substr($content, $startAM, $stop - $startAM);
94 $after = self::substituteSubpart($after, $marker, $subpartContent, $recursive, $keepMarker);
98 if (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
99 $before .= $marker . $matches[1];
100 $between = $matches[2];
101 $after = $matches[3] . $marker . $after;
102 } elseif (preg_match(
'/^(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
104 $between = $matches[1];
105 $after = $matches[2] . $marker . $after;
106 } elseif (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)$/s', $between, $matches) === 1) {
107 $before .= $marker . $matches[1];
108 $between = $matches[2];
109 $after = $marker . $after;
112 $after = $marker . $after;
116 if (preg_match(
'/^(.*)\\<\\!\\-\\-[^\\>]*$/s', $before, $matches) === 1) {
117 $before = $matches[1];
119 if (is_array($subpartContent)) {
121 if (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
122 $between = $matches[2];
123 } elseif (preg_match(
'/^(.*)(\\<\\!\\-\\-[^\\>]*)$/s', $between, $matches) === 1) {
124 $between = $matches[1];
125 } elseif (preg_match(
'/^([^\\<]*\\-\\-\\>)(.*)$/s', $between, $matches) === 1) {
126 $between = $matches[2];
131 if (preg_match(
'/^[^\\<]*\\-\\-\\>(.*)$/s', $after, $matches) === 1) {
132 $after = $matches[1];
135 if (is_array($subpartContent)) {
136 $between = $subpartContent[0] . $between . $subpartContent[1];
138 $between = $subpartContent;
140 return $before . $between . $after;
151 foreach ($subpartsContent as $subpartMarker => $subpartContent) {
152 $content = self::substituteSubpart($content, $subpartMarker, $subpartContent);
168 return str_replace($marker, $markContent, $content);
189 static public function substituteMarkerArray($content, $markContentArray, $wrap =
'', $uppercase = FALSE, $deleteUnused = FALSE) {
190 if (is_array($markContentArray)) {
194 foreach ($markContentArray as $marker => $markContent) {
197 $marker = strtr($marker,
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
199 if (count($wrapArr) > 0) {
200 $marker = $wrapArr[0] . $marker . $wrapArr[1];
203 $replace[] = $markContent;
205 $content = str_replace($search, $replace, $content);
206 unset($search, $replace);
209 $wrapArr = array(
'###',
'###');
211 $content = preg_replace(
'/' . preg_quote($wrapArr[0],
'/') .
'([A-Z0-9_|\\-]*)' . preg_quote($wrapArr[1],
'/') .
'/is',
'', $content);
254 $singleItems = array();
255 $compoundItems = array();
257 foreach ($markersAndSubparts as $markerName => $markerContent) {
258 if (is_array($markerContent)) {
259 $compoundItems[] = $markerName;
261 $singleItems[$markerName] = $markerContent;
264 $subTemplates = array();
265 $subpartSubstitutes = array();
267 foreach ($compoundItems as $subpartMarker) {
270 $subpartMarker = strtr($subpartMarker,
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
272 if (count($wraps) > 0) {
273 $subpartMarker = $wraps[0] . $subpartMarker . $wraps[1];
275 $subTemplates[$subpartMarker] = self::getSubpart($content, $subpartMarker);
278 foreach ($compoundItems as $subpartMarker) {
279 $completeMarker = $subpartMarker;
282 $completeMarker = strtr($completeMarker,
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
284 if (count($wraps) > 0) {
285 $completeMarker = $wraps[0] . $completeMarker . $wraps[1];
287 if (count($markersAndSubparts[$subpartMarker]) > 0) {
288 foreach ($markersAndSubparts[$subpartMarker] as $partialMarkersAndSubparts) {
289 $subpartSubstitutes[$completeMarker] .= self::substituteMarkerAndSubpartArrayRecursive($subTemplates[$completeMarker],
290 $partialMarkersAndSubparts, $wrap, $uppercase, $deleteUnused);
293 $subpartSubstitutes[$completeMarker] =
'';
297 $result = self::substituteSubpartArray($content, $subpartSubstitutes);
298 $result = self::substituteMarkerArray(
$result, $singleItems, $wrap, $uppercase, $deleteUnused);
321 foreach ($tags as &$tag) {
322 $tag = preg_quote($tag,
'/');
324 $regexStr =
'/\\<\\/?(' . implode(
'|', $tags) .
')(\\s*\\>|\\s[^\\>]*\\>)/si';
325 $parts = preg_split($regexStr, $content);
327 $pointer = strlen($parts[0]);
332 while (list($k, $v) = each($parts)) {
333 $isEndTag = substr($content, $pointer, 2) ==
'</' ? 1 : 0;
334 $tagLen = strcspn(substr($content, $pointer),
'>') + 1;
340 $newParts[] = $buffer;
346 $mbuffer = substr($content, $pointer, strlen($v) + $tagLen);
347 $pointer += strlen($mbuffer);
354 if ($eliminateExtraEndTags && $nested < 0) {
359 $buffer .= substr($content, $pointer, $tagLen);
363 if (!$nested && !$eliminated) {
364 $newParts[] = $buffer;
368 $mbuffer = substr($content, $pointer, strlen($v));
369 $pointer += strlen($mbuffer);
373 $newParts[] = $buffer;
392 foreach ($parts as $k => $v) {
395 $tagsArray = array();
397 $tagsArray[
'tag_end'] =
'</' . $firstTagName .
'>';
398 $tagsArray[
'tag_name'] = strtolower($firstTagName);
399 $tagsArray[
'add_level'] = 1;
402 $tagsArray = $procObj->{$callBackTags}($tagsArray, $level);
404 $parts[$k] = $tagsArray[
'tag_start'] . $tagsArray[
'content'] . $tagsArray[
'tag_end'];
406 if ($callBackContent) {
407 $parts[$k] = $procObj->{$callBackContent}($parts[$k], $level);
411 return implode(
'', $parts);
427 foreach ($tags as &$tag) {
428 $tag = preg_quote($tag,
'/');
430 $regexStr =
'/\\<(' . implode(
'|', $tags) .
')(\\s[^>]*)?\\/?>/si';
431 $parts = preg_split($regexStr, $content);
432 $pointer = strlen($parts[0]);
434 $newParts[] = $parts[0];
437 while (list($k, $v) = each($parts)) {
438 $tagLen = strcspn(substr($content, $pointer),
'>') + 1;
441 $tag = substr($content, $pointer, $tagLen);
443 $pointer += strlen($tag);
446 $pointer += strlen($v);
461 public function getAllParts($parts, $tag_parts = TRUE, $include_tag = TRUE) {
463 foreach ($parts as $k => $v) {
464 if (($k + ($tag_parts ? 0 : 1)) % 2) {
484 $start = strpos($str,
'>');
486 $end = strrpos($str,
'<');
488 return substr($str, $start + 1, $end - $start - 1);
501 $endLen = strpos($str,
'>') + 1;
502 return substr($str, 0, $endLen);
516 if (preg_match(
'/^\\s*\\<([^\\s\\>]+)(\\s|\\>)/', $str, $matches) === 1) {
517 if (!$preserveCase) {
518 return strtoupper($matches[1]);
539 $attributes = array();
540 $attributesMeta = array();
541 if (is_array($components)) {
542 foreach ($components as $key => $val) {
547 $attributes[$name] = $deHSC ? htmlspecialchars_decode($val) : $val;
548 $attributesMeta[$name][
'dashType'] = $metaC[$key];
552 if ($namekey = preg_replace(
'/[^[:alnum:]_\\:\\-]/',
'', $val)) {
553 $name = strtolower($namekey);
554 $attributesMeta[$name] = array();
555 $attributesMeta[$name][
'origTag'] = $namekey;
556 $attributes[$name] =
'';
564 return array($attributes, $attributesMeta);
580 if (preg_match(
'/(\\<[^\\s]+\\s+)?(.*?)\\s*(\\>)?$/s', $tag, $matches) !== 1) {
581 return array(array(), array());
583 $tag_tmp = $matches[2];
584 $metaValue = array();
587 if (preg_match_all(
'/("[^"]*"|\'[^\']*\'|[^\\s"\'\\=]+|\\=)/s', $tag_tmp, $matches) > 0) {
588 foreach ($matches[1] as $part) {
589 $firstChar = $part[0];
590 if ($firstChar ==
'"' || $firstChar ==
'\'') {
591 $metaValue[] = $firstChar;
592 $value[] = substr($part, 1, -1);
599 return array($value, $metaValue);
616 public 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') {
617 $content = strtolower($content);
618 $analyzedOutput = array();
620 $analyzedOutput[
'counts'] = array();
622 $analyzedOutput[
'errors'] = array();
624 $analyzedOutput[
'warnings'] = array();
626 $analyzedOutput[
'blocks'] = array();
628 $analyzedOutput[
'solo'] = array();
630 $blockTags = explode(
',', $blockTags);
631 foreach ($blockTags as $tagName) {
632 $countBegin = count(preg_split((
'/\\<' . preg_quote($tagName,
'/') .
'(\\s|\\>)/s'), $content)) - 1;
633 $countEnd = count(preg_split((
'/\\<\\/' . preg_quote($tagName,
'/') .
'(\\s|\\>)/s'), $content)) - 1;
634 $analyzedOutput[
'blocks'][$tagName] = array($countBegin, $countEnd, $countBegin - $countEnd);
636 $analyzedOutput[
'counts'][$tagName] = $countBegin;
638 if ($countBegin - $countEnd) {
639 if ($countBegin - $countEnd > 0) {
640 $analyzedOutput[
'errors'][$tagName] =
'There were more start-tags (' . $countBegin .
') than end-tags (' . $countEnd .
') for the element "' . $tagName .
'". There should be an equal amount!';
642 $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.';
647 $soloTags = explode(
',', $soloTags);
648 foreach ($soloTags as $tagName) {
649 $countBegin = count(preg_split((
'/\\<' . preg_quote($tagName,
'/') .
'(\\s|\\>)/s'), $content)) - 1;
650 $countEnd = count(preg_split((
'/\\<\\/' . preg_quote($tagName,
'/') .
'(\\s|\\>)/s'), $content)) - 1;
651 $analyzedOutput[
'solo'][$tagName] = array($countBegin, $countEnd);
653 $analyzedOutput[
'counts'][$tagName] = $countBegin;
656 $analyzedOutput[
'warnings'][$tagName] =
'There were end-tags found (' . $countEnd .
') for the element "' . $tagName .
'". This was not expected (although XHTML technically allows it).';
659 return $analyzedOutput;
704 public function HTMLcleaner($content, $tags = array(), $keepAll = 0, $hSC = 0, $addConfig = array()) {
705 $newContent = array();
706 $tokArr = explode(
'<', $content);
707 $newContent[] = $this->
processContent(current($tokArr), $hSC, $addConfig);
710 $tagRegister = array();
715 while (list(, $tok) = each($tokArr)) {
717 if (($eocPos = strpos($tok,
'-->')) === FALSE) {
719 $newContent[$c++] =
'<' . $tok;
723 $newContent[$c++] =
'<' . substr($tok, 0, ($eocPos + 3));
724 $tok = substr($tok, $eocPos + 3);
727 } elseif ($inCdata) {
728 if (($eocPos = strpos($tok,
'/*]]>*/')) === FALSE) {
730 $newContent[$c++] =
'<' . $tok;
734 $newContent[$c++] =
'<' . substr($tok, 0, $eocPos + 10);
735 $tok = substr($tok, $eocPos + 10);
738 } elseif (substr($tok, 0, 3) ==
'!--') {
739 if (($eocPos = strpos($tok,
'-->')) === FALSE) {
741 $newContent[$c++] =
'<' . $tok;
746 $newContent[$c++] =
'<' . substr($tok, 0, ($eocPos + 3));
747 $tok = substr($tok, $eocPos + 3);
749 } elseif (substr($tok, 0, 10) ===
'![CDATA[*/') {
750 if (($eocPos = strpos($tok,
'/*]]>*/')) === FALSE) {
752 $newContent[$c++] =
'<' . $tok;
757 $newContent[$c++] =
'<' . substr($tok, 0, $eocPos + 10);
758 $tok = substr($tok, $eocPos + 10);
761 $firstChar = $tok[0];
763 if (!$skipTag && preg_match(
'/[[:alnum:]\\/]/', $firstChar) == 1) {
764 $tagEnd = strpos($tok,
'>');
767 $endTag = $firstChar ==
'/' ? 1 : 0;
768 $tagContent = substr($tok, $endTag, $tagEnd - $endTag);
769 $tagParts = preg_split(
'/\\s+/s', $tagContent, 2);
770 $tagName = strtolower($tagParts[0]);
772 if (isset($tags[$tagName])) {
774 if (is_array($tags[$tagName])) {
775 if (preg_match(
'/^(' . self::VOID_ELEMENTS .
' )$/i', $tagName)) {
781 if ((
string)$tags[$tagName][
'overrideAttribs'] !==
'') {
782 $tagParts[1] = $tags[$tagName][
'overrideAttribs'];
785 if ((
string)$tags[$tagName][
'allowedAttribs'] !==
'') {
787 if ((
string)$tags[$tagName][
'allowedAttribs'] ===
'0') {
789 } elseif (trim($tagParts[1])) {
792 $newTagAttrib = array();
793 if (!($tList = $tags[$tagName][
'_allowedAttribs'])) {
795 $tList = ($tags[$tagName][
'_allowedAttribs'] =
GeneralUtility::trimExplode(
',', strtolower($tags[$tagName][
'allowedAttribs']), TRUE));
797 foreach ($tList as $allowTag) {
798 if (isset($tagAttrib[0][$allowTag])) {
799 $newTagAttrib[$allowTag] = $tagAttrib[0][$allowTag];
806 if (is_array($tags[$tagName][
'fixAttrib'])) {
809 foreach ($tags[$tagName][
'fixAttrib'] as $attr => $params) {
810 if (strlen($params[
'set'])) {
811 $tagAttrib[0][$attr] = $params[
'set'];
813 if (isset($params[
'unset']) && !empty($params[
'unset'])) {
814 unset($tagAttrib[0][$attr]);
816 if (!isset($tagAttrib[0][$attr]) && (
string)$params[
'default'] !==
'') {
817 $tagAttrib[0][$attr] = $params[
'default'];
819 if ($params[
'always'] || isset($tagAttrib[0][$attr])) {
820 if ($params[
'trim']) {
821 $tagAttrib[0][$attr] = trim($tagAttrib[0][$attr]);
823 if ($params[
'intval']) {
824 $tagAttrib[0][$attr] = (int)$tagAttrib[0][$attr];
826 if ($params[
'lower']) {
827 $tagAttrib[0][$attr] = strtolower($tagAttrib[0][$attr]);
829 if ($params[
'upper']) {
830 $tagAttrib[0][$attr] = strtoupper($tagAttrib[0][$attr]);
832 if ($params[
'range']) {
833 if (isset($params[
'range'][1])) {
839 if (is_array($params[
'list'])) {
842 if ($attr ==
'class') {
843 $newClasses = array();
845 foreach ($classes as $class) {
846 if (in_array($class, $params[
'list'])) {
847 $newClasses[] = $class;
850 if (count($newClasses)) {
851 $tagAttrib[0][$attr] = implode(
' ', $newClasses);
853 $tagAttrib[0][$attr] =
'';
856 if (!in_array($this->
caseShift($tagAttrib[0][$attr], $params[
'casesensitiveComp']), $this->
caseShift($params[
'list'], $params[
'casesensitiveComp'], $tagName))) {
857 $tagAttrib[0][$attr] = $params[
'list'][0];
861 if ($params[
'removeIfFalse'] && $params[
'removeIfFalse'] !=
'blank' && !$tagAttrib[0][$attr] || $params[
'removeIfFalse'] ==
'blank' && (
string)$tagAttrib[0][$attr] ===
'') {
862 unset($tagAttrib[0][$attr]);
864 if ((
string)$params[
'removeIfEquals'] !==
'' && $this->
caseShift($tagAttrib[0][$attr], $params[
'casesensitiveComp']) === $this->
caseShift($params[
'removeIfEquals'], $params[
'casesensitiveComp'])) {
865 unset($tagAttrib[0][$attr]);
867 if ($params[
'prefixLocalAnchors']) {
868 if ($tagAttrib[0][$attr][0] ===
'#') {
869 if ($params[
'prefixLocalAnchors'] == 2) {
872 $prefix = $contentObjectRenderer->getUrlToCurrentLocation();
876 $tagAttrib[0][$attr] = $prefix . $tagAttrib[0][$attr];
879 if ($params[
'prefixRelPathWith']) {
880 $urlParts = parse_url($tagAttrib[0][$attr]);
881 if (!$urlParts[
'scheme'] && $urlParts[
'path'][0] !==
'/') {
883 $tagAttrib[0][$attr] = $params[
'prefixRelPathWith'] . $tagAttrib[0][$attr];
886 if ($params[
'userFunc']) {
898 if ($tags[$tagName][
'protect']) {
906 if ($tags[$tagName][
'remap']) {
907 $tagParts[0] = $tags[$tagName][
'remap'];
910 if ($endTag || trim($tagParts[1]) || !$tags[$tagName][
'rmTagIfNoAttrib']) {
913 if ($endTag && $tags[$tagName][
'allowedAttribs'] === 0 && $tags[$tagName][
'rmTagIfNoAttrib'] === 1) {
916 if ($tags[$tagName][
'nesting']) {
917 if (!is_array($tagRegister[$tagName])) {
918 $tagRegister[$tagName] = array();
922 if ($tags[$tagName][
'nesting'] ==
'global') {
923 $lastEl = end($tagStack);
924 if ($tagName !== $lastEl) {
925 if (in_array($tagName, $tagStack)) {
926 while (count($tagStack) && $tagName !== $lastEl) {
927 $elPos = end($tagRegister[$lastEl]);
928 unset($newContent[$elPos]);
929 array_pop($tagRegister[$lastEl]);
930 array_pop($tagStack);
931 $lastEl = end($tagStack);
939 if (!count($tagRegister[$tagName]) || !$correctTag) {
942 array_pop($tagRegister[$tagName]);
943 if ($tags[$tagName][
'nesting'] ==
'global') {
944 array_pop($tagStack);
948 array_push($tagRegister[$tagName], $c);
949 if ($tags[$tagName][
'nesting'] ==
'global') {
950 array_push($tagStack, $tagName);
956 $newContent[$c++] = $this->
processTag($lt . ($endTag ?
'/' :
'') . trim(($tagParts[0] .
' ' . $tagParts[1])) . ($emptyTag ?
' /' :
'') . $gt, $addConfig, $endTag, $lt ==
'<');
960 $newContent[$c++] = $this->
processTag(
'<' . ($endTag ?
'/' :
'') . $tagContent .
'>', $addConfig, $endTag);
962 } elseif ($keepAll) {
964 if ($keepAll ===
'protect') {
971 $newContent[$c++] = $this->
processTag($lt . ($endTag ?
'/' :
'') . $tagContent . $gt, $addConfig, $endTag, $lt ==
'<');
973 $newContent[$c++] = $this->
processContent(substr($tok, $tagEnd + 1), $hSC, $addConfig);
975 $newContent[$c++] = $this->
processContent(
'<' . $tok, $hSC, $addConfig);
978 $newContent[$c++] = $this->
processContent(($skipTag ?
'' :
'<') . $tok, $hSC, $addConfig);
984 foreach ($tagRegister as $tag => $positions) {
985 foreach ($positions as $pKey) {
986 unset($newContent[$pKey]);
989 return implode(
'', $newContent);
1003 $value = htmlspecialchars($value);
1004 } elseif ($dir === 2) {
1005 $value = htmlspecialchars($value, ENT_COMPAT,
'UTF-8', FALSE);
1006 } elseif ($dir === -1) {
1007 $value = htmlspecialchars_decode($value);
1023 $parts = $this->
splitTags(
'embed,td,table,body,img,input,form,link,script,a,param', $content);
1024 foreach ($parts as $k => $v) {
1028 $tagEnd = substr($v, -2) ==
'/>' ?
' />' :
'>';
1032 $prefix = isset($alternatives[strtoupper($firstTagName)]) ? $alternatives[strtoupper($firstTagName)] : $main_prefix;
1033 switch (strtolower($firstTagName)) {
1039 $src = $params[0][
'background'];
1041 $params[0][
'background'] = $this->
prefixRelPath($prefix, $params[0][
'background'], $suffix);
1052 $src = $params[0][
'src'];
1054 $params[0][
'src'] = $this->
prefixRelPath($prefix, $params[0][
'src'], $suffix);
1061 $src = $params[0][
'href'];
1063 $params[0][
'href'] = $this->
prefixRelPath($prefix, $params[0][
'href'], $suffix);
1068 $src = $params[0][
'action'];
1070 $params[0][
'action'] = $this->
prefixRelPath($prefix, $params[0][
'action'], $suffix);
1075 $test = $params[0][
'name'];
1076 if ($test && $test ===
'movie') {
1077 if ($params[0][
'value']) {
1078 $params[0][
'value'] = $this->
prefixRelPath($prefix, $params[0][
'value'], $suffix);
1084 if ($somethingDone) {
1085 $tagParts = preg_split(
'/\\s+/s', $v, 2);
1087 $parts[$k] =
'<' . trim((strtolower($firstTagName) .
' ' . $tagParts[1])) . $tagEnd;
1091 $content = implode(
'', $parts);
1093 $prefix = isset($alternatives[
'style']) ? $alternatives[
'style'] : $main_prefix;
1094 if (strlen($prefix)) {
1096 foreach ($parts as $k => &$part) {
1098 $part = preg_replace(
'/(url[[:space:]]*\\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\\))/i',
'\\1' . $prefix .
'\\2' . $suffix .
'\\3', $part);
1102 $content = implode(
'', $parts);
1120 if ($srcVal[0] !==
'/' && $srcVal[0] !==
'#') {
1121 $urlParts = parse_url($srcVal);
1123 if (!$urlParts[
'scheme']) {
1124 $srcVal = $prefix . $srcVal . $suffix;
1141 public function cleanFontTags($value, $keepFace = 0, $keepSize = 0, $keepColor = 0) {
1144 foreach ($fontSplit as $k => $v) {
1148 $newAttribs = array();
1149 if ($keepFace && $attribArray[
'face']) {
1150 $newAttribs[] =
'face="' . $attribArray[
'face'] .
'"';
1152 if ($keepSize && $attribArray[
'size']) {
1153 $newAttribs[] =
'size="' . $attribArray[
'size'] .
'"';
1155 if ($keepColor && $attribArray[
'color']) {
1156 $newAttribs[] =
'color="' . $attribArray[
'color'] .
'"';
1159 if (count($newAttribs)) {
1160 $fontSplit[$k] =
'<font ' . implode(
' ', $newAttribs) .
'>' . $innerContent .
'</font>';
1162 $fontSplit[$k] = $innerContent;
1166 return implode(
'', $fontSplit);
1179 public function mapTags($value, $tags = array(), $ltChar =
'<', $ltChar2 =
'<') {
1180 foreach ($tags as $from => $to) {
1181 $value = preg_replace(
'/' . preg_quote($ltChar,
'/') .
'(\\/)?' . $from .
'\\s([^\\>])*(\\/)?\\>/', $ltChar2 .
'$1' . $to .
' $2$3>', $value);
1196 $contentParts = explode(
'<', $content);
1197 next($contentParts);
1199 while (list($k, $tok) = each($contentParts)) {
1200 $firstChar = $tok[0];
1201 if (trim($firstChar) !==
'') {
1202 $subparts = explode(
'>', $tok, 2);
1203 $tagEnd = strlen($subparts[0]);
1204 if (strlen($tok) != $tagEnd) {
1205 $endTag = $firstChar ==
'/' ? 1 : 0;
1206 $tagContent = substr($tok, $endTag, $tagEnd - $endTag);
1207 $tagParts = preg_split(
'/\\s+/s', $tagContent, 2);
1208 $tagName = strtolower($tagParts[0]);
1209 if ((
string)$tagList ===
'' || in_array($tagName, $tagsArray)) {
1210 $contentParts[$k] =
'<' . $subparts[0] .
'>' . $subparts[1];
1212 $contentParts[$k] =
'<' . $tok;
1215 $contentParts[$k] =
'<' . $tok;
1218 $contentParts[$k] =
'<' . $tok;
1221 return implode(
'', $contentParts);
1235 $cacheKey .= $flag ? 1 : 0;
1236 if (is_array($str)) {
1237 if (!$cacheKey || !isset($this->caseShift_cache[$cacheKey])) {
1238 foreach ($str as &$v) {
1240 $v = strtoupper($v);
1245 $this->caseShift_cache[$cacheKey] = $str;
1248 $str = $this->caseShift_cache[$cacheKey];
1251 $str = strtoupper($str);
1268 foreach ($tagAttrib as $k => $v) {
1270 $attr = strtolower($k);
1271 if ((
string)$v !==
'' || isset($meta[$k][
'dashType'])) {
1272 $attr .=
'="' . htmlspecialchars($v) .
'"';
1275 $attr = $meta[$k][
'origTag'] ?: $k;
1276 if (strcmp($v,
'') || isset($meta[$k][
'dashType'])) {
1278 $attr .=
'=' . $dash . $v . $dash;
1283 return implode(
' ', $accu);
1297 return is_array($attr[0]) ? $attr[0] : array();
1309 public function indentLines($content, $number = 1, $indentChar = TAB) {
1310 $preTab = str_pad(
'', $number * strlen($indentChar), $indentChar);
1311 $lines = explode(LF, str_replace(CR,
'', $content));
1312 foreach ($lines as &$line) {
1313 $line = $preTab . $line;
1316 return implode(LF, $lines);
1331 $keepTags = array_merge($alTags, $keepTags);
1333 if (is_array($TSconfig[
'tags.'])) {
1334 foreach ($TSconfig[
'tags.'] as $key => $tagC) {
1335 if (!is_array($tagC) && $key == strtolower($key)) {
1336 if ((
string)$tagC ===
'0') {
1337 unset($keepTags[$key]);
1339 if ((
string)$tagC ===
'1' && !isset($keepTags[$key])) {
1340 $keepTags[$key] = 1;
1344 foreach ($TSconfig[
'tags.'] as $key => $tagC) {
1345 if (is_array($tagC) && $key == strtolower($key)) {
1346 $key = substr($key, 0, -1);
1347 if (!is_array($keepTags[$key])) {
1348 $keepTags[$key] = array();
1350 if (is_array($tagC[
'fixAttrib.'])) {
1351 foreach ($tagC[
'fixAttrib.'] as $atName => $atConfig) {
1352 if (is_array($atConfig)) {
1353 $atName = substr($atName, 0, -1);
1354 if (!is_array($keepTags[$key][
'fixAttrib'][$atName])) {
1355 $keepTags[$key][
'fixAttrib'][$atName] = array();
1357 $keepTags[$key][
'fixAttrib'][$atName] = array_merge($keepTags[$key][
'fixAttrib'][$atName], $atConfig);
1359 if ((
string)$keepTags[$key][
'fixAttrib'][$atName][
'range'] !==
'') {
1360 $keepTags[$key][
'fixAttrib'][$atName][
'range'] =
GeneralUtility::trimExplode(
',', $keepTags[$key][
'fixAttrib'][$atName][
'range']);
1362 if ((
string)$keepTags[$key][
'fixAttrib'][$atName][
'list'] !==
'') {
1368 unset($tagC[
'fixAttrib.']);
1369 unset($tagC[
'fixAttrib']);
1370 if (isset($tagC[
'rmTagIfNoAttrib']) && $tagC[
'rmTagIfNoAttrib'] && empty($tagC[
'nesting'])) {
1371 $tagC[
'nesting'] = 1;
1374 $keepTags[$key] = array_merge($keepTags[$key], $tagC);
1379 if ($TSconfig[
'localNesting']) {
1381 foreach ($lN as $tn) {
1382 if (isset($keepTags[$tn])) {
1383 if (!is_array($keepTags[$tn])) {
1384 $keepTags[$tn] = array();
1386 $keepTags[$tn][
'nesting'] = 1;
1390 if ($TSconfig[
'globalNesting']) {
1392 foreach ($lN as $tn) {
1393 if (isset($keepTags[$tn])) {
1394 if (!is_array($keepTags[$tn])) {
1395 $keepTags[$tn] = array();
1397 $keepTags[$tn][
'nesting'] =
'global';
1401 if ($TSconfig[
'rmTagIfNoAttrib']) {
1403 foreach ($lN as $tn) {
1404 if (isset($keepTags[$tn])) {
1405 if (!is_array($keepTags[$tn])) {
1406 $keepTags[$tn] = array();
1408 $keepTags[$tn][
'rmTagIfNoAttrib'] = 1;
1409 if (empty($keepTags[$tn][
'nesting'])) {
1410 $keepTags[$tn][
'nesting'] = 1;
1415 if ($TSconfig[
'noAttrib']) {
1417 foreach ($lN as $tn) {
1418 if (isset($keepTags[$tn])) {
1419 if (!is_array($keepTags[$tn])) {
1420 $keepTags[$tn] = array();
1422 $keepTags[$tn][
'allowedAttribs'] = 0;
1426 if ($TSconfig[
'removeTags']) {
1428 foreach ($lN as $tn) {
1429 $keepTags[$tn] = array();
1430 $keepTags[$tn][
'allowedAttribs'] = 0;
1431 $keepTags[$tn][
'rmTagIfNoAttrib'] = 1;
1435 $addConfig = array();
1436 if ($TSconfig[
'xhtml_cleaning']) {
1437 $addConfig[
'xhtml'] = 1;
1441 '' . $TSconfig[
'keepNonMatchedTags'],
1442 (
int)$TSconfig[
'htmlSpecialChars'],
1474 $content = $this->HTMLcleaner($content, array(), 1, 0, array(
'xhtml' => 1));
1490 public function processTag($value, $conf, $endTag, $protected = 0) {
1492 if ($protected || !count($conf)) {
1497 if ($conf[
'xhtml']) {
1500 $value = strtolower($value);
1501 } elseif (substr($value, 0, 4) !=
'<!--') {
1504 $inValue = substr($value, 1, substr($value, -2) ==
'/>' ? -2 : -1);
1506 list($tagName, $tagP) = preg_split(
'/\\s+/s', $inValue, 2);
1507 $tagName = strtolower($tagName);
1510 if ($tagName ===
'img' && !isset($tagAttrib[0][
'alt'])) {
1511 $tagAttrib[0][
'alt'] =
'';
1514 if ($tagName ===
'script' && !isset($tagAttrib[0][
'type'])) {
1515 $tagAttrib[0][
'type'] =
'text/javascript';
1519 foreach ($tagAttrib[0] as $attrib_name => $attrib_value) {
1523 $newTag =
'<' . trim(($tagName .
' ' . implode(
' ', $outA)));
1525 if (
GeneralUtility::inList(
'img,br,hr,meta,link,base,area,input,param,col', $tagName) || substr($value, -2) ==
'/>') {
static substituteSubpartArray($content, array $subpartsContent)
getFirstTagName($str, $preserveCase=FALSE)
splitIntoBlock($tag, $content, $eliminateExtraEndTags=FALSE)
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')
removeFirstAndLastTag($str)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
mapTags($value, $tags=array(), $ltChar='<', $ltChar2='<')
HTMLparserConfig($TSconfig, $keepTags=array())
static canBeInterpretedAsInteger($var)
static getIndpEnv($getEnvName)
getAllParts($parts, $tag_parts=TRUE, $include_tag=TRUE)
indentLines($content, $number=1, $indentChar=TAB)
static makeInstance($className)
prefixRelPath($prefix, $srcVal, $suffix='')
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
split_tag_attributes($tag)
static substituteMarkerAndSubpartArrayRecursive($content, array $markersAndSubparts, $wrap='', $uppercase=FALSE, $deleteUnused=FALSE)
compileTagAttribs($tagAttrib, $meta=array(), $xhtmlClean=0)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
get_tag_attributes($tag, $deHSC=0)
caseShift($str, $flag, $cacheKey='')
splitIntoBlockRecursiveProc($tag, $content, &$procObj, $callBackContent, $callBackTags, $level=0)
splitTags($tag, $content)
static substituteMarker($content, $marker, $markContent)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren't numeric.
processContent($value, $dir, $conf)
static getSubpart($content, $marker)
prefixResourcePath($main_prefix, $content, $alternatives=array(), $suffix='')
static substituteMarkerArray($content, $markContentArray, $wrap='', $uppercase=FALSE, $deleteUnused=FALSE)
static substituteSubpart($content, $marker, $subpartContent, $recursive=TRUE, $keepMarker=FALSE)
bidir_htmlspecialchars($value, $dir)
cleanFontTags($value, $keepFace=0, $keepSize=0, $keepColor=0)
static inList($list, $item)
processTag($value, $conf, $endTag, $protected=0)
get_tag_attributes_classic($tag, $deHSC=0)
unprotectTags($content, $tagList='')