classTransform{/** XSLT processor */
static $proc;/** Current XSL DOM doc */
static $xsl;/** Current XML DOM doc */
static $xml;/** If a transformation have be done (not from cache) */
public static $done;/** Last message */
public static $message;
static functionxsl($src,$xsl,$destFile,$params=array(),$deps=array(),$force=false){// reset log
self::$message=null;self::$done=false;// if no dest dir, try to make it, let error go out
if($destFile){if(!is_dir(dirname($destFile)))mkdir(dirname($destFile),0775,true);if(is_writable($destFile));// file exists and writable, OK
elseif(!is_writable(dirname($destFile)))returntouch($destFile);// file not exists and dir not writable, pb
}// check if someone is working on this file
$lockFile=$destFile.".lock";if(!is_writable($destFile)&&file_exists($lockFile)&&is_writable($lockFile))unlink($lockFile);// delete lockFile if rights problem
if(file_exists($lockFile)){date_default_timezone_set("Europe/Paris");print"\n<!-- $lockFile, transformation started ".date("Y-m-d H:i:sP",filemtime($lockFile))." -->";return;}if($destFile&&file_exists($destFile))$destMtime=filemtime($destFile);else$destMtime=0;// if source is a file, add it to dependencies
if(file_exists($src))$deps[]=$src;// if no deps, force transform
if(!count($deps))$force=true;// loop on deps to see if transform is needed
else{// an XSL may be grapped from the http
if(is_file($xsl))$deps[]=$xsl;foreach($depsas$file){// laisser sortir l'erreur si une dépendance n'existe pas ?
if($destMtime<filemtime($file)){$force=true;break;}}if(!$force)return$destFile;}// transform will be done, nothing coming from cache, say it to the world
self::$done=true;// load xml_file
if(file_exists($src))self::$xml->load($src,LIBXML_NOERROR|LIBXML_NOWARNING);// xml string ?
elseself::$xml->loadXML($src);// argument more than one line, seems to not be a filepath
if(strpos($xsl,"\n")!==false)self::$xsl->loadXML($xsl);elseself::$xsl->load($xsl);// Si en contexte diple, réécrire les liens relatif d'import xsl
if(class_exists("Diple")){// modifier seulement l'uri de base de l'xsl est trop risqué en cas d'autres imports relatifs
// self::$xsl->documentURI=Diple::$dipleDir.'transform/sous/';
foreach(self::$xsl->getElementsByTagName("import")as$node){$node->setAttribute('href',preg_replace('@^(../)*diple/@',strtr(Diple::$dipleDir,array('\\'=>"/")),$node->getAttribute('href')));}}self::$proc->importStyleSheet(self::$xsl);// transpose params
if(isset($params)&&count($params))foreach($paramsas$key => $value)self::$proc->setParameter('',$key,$value);$result=$destFile;// change current directory do not affect link resolution for <xsl:document href="">
// changing error_handler allow redirection of <xsl:message>, default behavior is output lines to workaround apache timeout
$oldError=set_error_handler(array(__CLASS__,"xsl_message"),E_WARNING);// try commandline if src is big to avoid time limit ?
// if no dest file provide, return the result as a string
if(!$destFile)$result=self::$proc->transformToXML(self::$xml);// transform to destFile
else{@touch($lockFile);@chmod($lockFile,0666);self::$proc->transformToUri(self::$xml,$destFile);chmod($destFile,0664);// let group delete what php has done
if(file_exists($lockFile))unlink($lockFile);}if(self::$message)print"\n-->";restore_error_handler();return$result;}
static functionxsl_message($errno,$errstr,$errfile,$errline,$errcontext){if(!self::$message)print"\n<!--";self::$message=preg_replace("/XSLTProcessor::transformToUri[^:]*:/","",$errstr);print"\n".self::$message;}}Transform::$proc=newXSLTProcessor();// politique de sécurité pour <xsl:document>
//if (version_compare(PHP_VERSION,'5.4',"<")) $oldval = ini_set("xsl.security_prefs",0);
//else $oldval = Transform::$proc->setSecurityPreferences(0);
Transform::$proc->registerPHPFunctions();Transform::$xsl=newDOMDocument();Transform::$xml=newDOMDocument();?>