<?php
/**
* @package PhpOpenDocumentReports
* @author Eric Letard
* @copyright GPL License 2009
* @license http://www.gnu.org/copyleft/gpl.html GPL License
* @version 0.3
*/
/**
* class PODRTagFilter
*
* - Cleans tags with <? ?> ( in particular xml declaration tag)
* - php tags html encoded are "restored"
* - content of php tags may be html encoded, so it cleans all.
*
* Adds functionnality inspired by JodReports
* - input fields, see JODReports for more info
* - script function ( with language="SavantScript"), see JODReports for more info
* @link http://jodreports.sourceforge.net JodReports
* @package PhpOpenDocumentReports
* @author Eric Letard
* @copyright GPL License 2009
* @license http://www.gnu.org/copyleft/gpl.html GPL License
* @version 0.3
*/
class PODRTagFilter {
/**
*
* @param <string> $buffer original content.xml
* @return <string> updated output content.xml to use to parse
*/
public static function filter(PODRFileString $data) {
$bufferparsed=$data->getContent();
/*Cleans tags with <? ?> ( in particular xml declaration tag)*/
$bufferparsed=preg_replace("@\<\?(?!php)([^<]*)\?>@sm", "[--?TAG--]\\1[!--?TAG--]", $bufferparsed);
/*In case of HTML encoded entities ?!*/
$bufferparsed=preg_replace("@<\?php([^<]*)\?>@sm", "<?php\\1?>", $bufferparsed);
/*html entities between the php tags ( happens when code is typed in OOo*/
$bufferparsed=preg_replace_callback("@<\?php([^<]*)\?>@sm", array("self","cleanPhpRegex"), $bufferparsed);
/*on gere les champs de fonction*/
$bufferparsed=preg_replace_callback("@\<text:text-input text:description=\"([^\"]*)\">[^>]*>@sm", array("self","cleanPhpRegex"), $bufferparsed);
/*Si on a pas mis de valeur, on a une balise auto fermante <text:text-input text:description="[..]" />*/
$bufferparsed=preg_replace_callback("@\<text:text-input text:description=\"([^\"]*)\"/>@sm", array("self","cleanPhpRegex"), $bufferparsed);
$taglength=strlen("<text:script script:language=\"SavantScript\">");
$pos=0;
while(($pos=stripos($bufferparsed,"<text:script script:language=\"SavantScript\">",$pos))!==false) {
$endpos=stripos($bufferparsed,"</text:script>",$pos+1);
$before=substr($bufferparsed,0,$pos);
$string=substr($bufferparsed,$pos+$taglength,$endpos-($pos+$taglength));
$after=substr($bufferparsed,$endpos+strlen("</text:script>"));
$bufferparsed=self::processScriptDirectives($before,$string,$after);
}
$data->setContent($bufferparsed);
return $data;
}
/**
* restores some tags (<? ?>)
* @param <string> $bufferParsed parsed content
* @return <string> content.xml to save
*/
public static function filterOut(PODRFileString $data) {
/* Restore tags with <? ?> ( in particular xml declaration tag)*/
$bufferParsed=preg_replace("@\\[--\?TAG--\]([^<]*)\[\!--\?TAG--\]@sm", "<?\\1?>", $data->getContent());
$data->setContent($bufferParsed);
return $data;
}
/**
* callback function for regex
* @see cleanPhp()
* @param <array> $data
* @return <string> cleanedPHP
*/
protected static function cleanPhpRegex($data) {
return self::cleanPhp($data[1]);
}
/**
* strips HTML entities and adds php tags
* @param <string> $data without php tags
* @return <string> <? html_cleared_data ?>
*/
protected static function cleanPhp($data) {
$data=str_replace("'","\"",$data);
return "<?php ".html_entity_decode($data,ENT_QUOTES)."?>";
}
/**
* Parses the script to update the buffer
* @param <string> $before text before tag
* @param <string> $string content of the tag
* @param <string> $after text after the tag
* @return <string> all text
*/
protected static function processScriptDirectives($before,$string,$after) {
$scriptReplacement = "";
$scriptParts=self::parseScriptParts($string);
foreach($scriptParts as $part) {
if($part["location"]=="") {
if(trim($part["script"])!=="")
$scriptReplacement.=self::cleanPhp($part["script"]);
}
else {
$afterEndTag=false;
$tagName=$part['location'];
if(substr($tagName,0,1)=="/") {
$afterEndTag=true;
$tagName=substr($tagName,1);
}
self::insertAtTag($tagName,$afterEndTag,$before,$after,$part["script"]);
}
}
return $before.$scriptReplacement.$after;
}
/**
* Get location and content of each part of the script
* @param <string> $string script
* @return <array> parts of the script
*/
protected static function parseScriptParts($string) {
$string=html_entity_decode($string,ENT_QUOTES);
$lines=explode("\n",$string);
$parts[0]=array("location"=>"","script"=>"");
$nbparts=0;
foreach($lines as $line) {
if(substr($line,0,1)=="@") {
$nbparts++;
$parts[$nbparts]=array("location"=>substr($line,1),"script"=>"");
}
else {
$parts[$nbparts]['script'].=$line;
}
}
return $parts;
}
/**
* inserts the script hooked on a tag
* @param <string> $tagName tag to look for
* @param <string> $afterEndTag before the opening tag or after the closing tag
* @param <string> &$before text before script
* @param <string> &$after text after script
* @param <string> $script script to insert
*/
protected static function insertAtTag($tagName,$afterEndTag,&$before,&$after,$script) {
$pos=0;
if($afterEndTag) {
if(($pos=stripos($after,$tagName,$pos))!==false) {
$pos=$pos+strlen($tagName)+1;
$beforeinsert=substr($after,0,$pos);
$afterinsert=substr($after,$pos);
$after=$beforeinsert.self::cleanPhp($script).$afterinsert;
}
else
throw new Exception("tag $tagName not found");
}
else {
if(($pos=strripos($before,$tagName))!==false) {
$pos=$pos-1;
$beforeinsert=substr($before,0,$pos);
$afterinsert=substr($before,$pos);
$before=$beforeinsert.self::cleanPhp($script).$afterinsert;
}
else
throw new Exception("tag $tagName not found");
}
}
}
?>