############################################ 1. userFuncs ############################################ tags through this method to filter out all but allowed objects, which are replaced by custom typotags. * * @param string object tag that will be parsed and replaced * @param array configuration array for userFunc. See parseVideoTags method for details on what kind of conf we're expecting. * @return string returns the string that will replace the entire * **/ function user_parseObjectVideos($content,$conf) { return $this->parseVideoTag($content,$conf); } /** * send all tags through this method to filter out all but allowed objects, which are replaced by custom typotags. Note * that this is called after the parsing of tags so it typically will not parse embed tags inside of an object tag, which * are handled in the previous method. * * @param string embed tag that will be parsed and replaced * @param array configuration array for userFunc. See parseVideoTags method for details on what kind of conf we're expecting. * @return string returns the string that will replace the entire * **/ function user_parseEmbedVideos($content,$conf) { return $this->parseVideoTag($content,$conf); } /** * Looks at an embed or object tag and determines whether or not an allowed url (of a video sharing site) is present. If so, it looks for * the ID of the video following a regular expression tied to the video type / url. If it finds one, it replaces the object / embed tag * with a custom typoscript tag, which will be parsed by a separate parsefunc when the content is rendered on the frontend. * * @param string embed or object tag that will be parsed and replaced * @param array configuration array for this userfunction. * @return string returns the string that will replace the entire $content value passed to this function, typically a custom tag. **/ function parseVideoTag($content,$conf) { $out = ''; if(is_array($conf['tags.'])) { foreach($conf['tags.'] as $tagName => $tagConf) { $tagName = substr($tagName,0,-1); $domain = $tagConf['domain']; $pattern = $tagConf['pattern']; if($domain && $pattern) { if(stripos($content,$domain)) { $matches = array(); if(preg_match($pattern,$content,$matches)) { $out = '<'.$tagName.'>'.$matches[1].''; break; } } } } } return $out; } /** * Called by parseFunc (in lib.parseFunc_feInput) to strip out bad URL attribute values from FE input * * @param string embed tag that will be parsed and replaced * @param array configuration array for parsefunc. See parseVideoTags method for details on what kind of conf we're expecting. * @return string returns the string that will replace the entire * **/ function user_cleanUrlAttr($content,$conf) { // Lower case the value $lcValue = strtolower($content); // An array of string values that the attribute MUST begin with // to be allowed. $allowedInitArr = array( 'http://', 'https://', 'uploads/' ); foreach($allowedInitArr as $string) { if(strpos($lcValue,$string) === 0) { return $content; } } return ''; } } ?> ############################################ 2. lib.parseFunc_feInput ############################################ ### USE ONLY BEFORE PUTTING USER SUBMITTED CONTENT INTO THE DATABASE # Generic parseFunc configuration for cleaning up user-submitted data before putting it in the database lib.parseFunc_feInput { makelinks = 0 // note that it seems like we're allowing obejct / embed tags here -- but they always go through our userFunc which will remove any that do not meet our special // requirements. allowTags = font,b,i,u,a,img,br,hr,center,pre,sub,sup,p,strong,em,li,ul,ol,blockquote,strike,span,h1,h2,h3,h4,h5,h6,youtube,myspace,object,embed denyTags = * externalBlocks = object,embed externalBlocks { object { stdWrap.preUserFunc = user_parseFuncFE_userFuncs->user_parseObjectVideos stdWrap.preUserFunc { tags { youtube { domain = www.youtube.com pattern = /user_parseEmbedVideos stdWrap.preUserFunc { tags < lib.parseFunc_feInput.externalBlocks.object.stdWrap.preUserFunc.tags } } } nonTypoTagStdWrap { HTMLparser = 1 HTMLparser { allowTags = font,b,i,u,a,img,br,hr,center,pre,sub,sup,p,strong,em,li,ul,ol,blockquote,strike,span,h1,h2,h3,h4,h5,h6,youtube,myspace, link denyTags = * keepNonMatchedTags = 1 htmlSpecialChars = 2 noAttrib = b,i,u,br,hr,center,pre,sub,sup,strong,em,li,ul,ol,blockquote,strike,youtube,myspace xhtml_cleaning = 1 // in this section, we carefully determine what's allowed as attributes in our allowed tags. We also make sure that any URLs go through a function // that sanitizes them in order to avoid javascript injection attacks. tags { default { allowedAttribs = class } font { allowedAttribs = face,color,size } a { allowedAttribs = href,title fixAttrib.href.userFunc = user_parseFuncFE_userFuncs->user_cleanUrlAttr } img { allowedAttribs = class,src,width,height,alt,title,align fixAttrib.src.userFunc = user_parseFuncFE_userFuncs->user_cleanUrlAttr } b < .default b { remap = strong } i < .default i { remap = em } p < .default p { allowedAttribs = align } span < .default h1 < .default h2 < .default h3 < .default h4 < .default h5 < .default h6 < .default } } } } ############################################ 3. lib.parseFunc_outputFeInput ############################################ ### USE ONY BEFORE OUTPUTTING INPUT THAT USED ABOVE PARSEFUNC CODE BEFORE BEING SAVED! -- generally based on lib.parsefunc_RTE lib.parseFunc_outputFeInput < lib.parseFunc_feInput lib.parseFunc_outputFeInput { makelinks = 1 makelinks { http { keep = path extTarget = _blank } mailto { keep = path } } tags { link = TEXT link { current = 1 typolink { parameter.data = parameters : allParams extTarget = _blank target = } parseFunc.constants = 1 } // note -- we're putting the output object / embed html on one line to avoid having it wrapped with p tags. If anyone has a fix for this, I'd like to see it. youtube = TEXT youtube { value = insertData = 1 } myspace = TEXT myspace { value = insertData = 1 } } // need to unset the src and href checking that happens when content is saved to the db. nonTypoTagStdWrap.HTMLparser.tags.a.fixAttrib.href.userFunc > nonTypoTagStdWrap.HTMLparser.tags.img.fixAttrib.src.userFunc > nonTypoTagStdWrap { HTMLparser = 1 HTMLparser { keepNonMatchedTags = 1 htmlSpecialChars = 2 } encapsLines { encapsTagList = p,pre,h1,h2,h3,h4,h5,h6,blockquote,li,ul,ol,object,embed,param nonWrappedTag = P innerStdWrap_all.ifBlank = addAttributes { P { class = class.setOnly = blank } } } } externalBlocks = blockquote,ol,ul externalBlock { blockquote { stripNL = 1 callRecursive = 1 callRecursive { tagStdWrap { HTMLparser = 1 } } } ol { stripNL = 1 stdWrap.parseFunc < lib.parseFunc } ul { stripNL = 1 stdWrap.parsefunc < lib.parseFunc } } }