<?php
/**
* @package PhpOpenDocumentReports
* @author Eric Letard
* @copyright GPL License 2009
* @license http://www.gnu.org/copyleft/gpl.html GPL License
* @version 0.3
*/
include_once("PODRODT.php");
include_once("PODRJOD.php");
include_once("PODRTagFilter.php");
/**
* Main templating tool (based on Savant).
* Can be used only as a template engine, or can be used as a powerfull templating and conversion tool
*
* @link https://sourceforge.net/projects/podr
* @package PhpOpenDocumentReports
* @author Eric Letard
* @copyright GPL License 2009
* @license http://www.gnu.org/copyleft/gpl.html GPL License
* @version 0.3
*/
class PODREngine {
const SAVEMODE_FILE="Save";
const SAVEMODE_HTTP="HTTP";
const SAVEMODE_DISPLAY="Display";
protected $__properties=array(
"InputFileName"=>"./test.html",
"OutputMode"=>"Save",
"OutputFileName"=>"./test-out.html",
"TempDir"=>null,
);
protected $_filters=array(
"load"=>array(
array("PODRODT","load"),
array("PODRTagFilter","filter"),
),
"fetch"=>array(
array("PODRTagFilter","filterOut")
),
"save"=>array(
array("PODRODT","save"),
array("PODRJOD","convertFile"),
),
);
/**
* Define properties :
* InputFileName = path to file name
* OutputMode = "Save"/"HTTP"/"Display"
* OutputFileName = path to outputfile / filename of sended file
* TempDir = directory to use for temp files
* @param array $props
*/
public function __construct($props) {
$this->__properties=array_merge($this->__properties,$props);
}
/**
* get a property
* @param string $key
* @param mixed $defaultValue
* @return string value
*/
public function getConfig($key,$defaultValue) {
return (isset($this->__properties[$key]))?$this->__properties[$key]:$defaultValue;
}
/**
* define a property
* @param string $key
* @param mixed $value
*/
public function setConfig($key,$value) {
$this->__properties[$key]=$value;
}
/**
* add at the begining of the chain of filters
* @param string $event
* @param mixed $callback
* @return boolean true if success
*/
public function prependFilter($event,$callback) {
if(isset($this->_filters[$event]))
return array_unshift($this->_filters[$event], $callback);
return false;
}
/**
* add at the end of the chain of filters
* @param string $event
* @param mixed $callback
* @return boolean true if success
*/
public function appendFilter($event,$callback) {
if(isset($this->_filters[$event]))
return $this->_filters[$event][]= $callback;
return false;
}
/**
* execute filters for an event
* @param string $event
* @param PODRFileString $data
* @return PODRFileString
*/
protected function filter($event,PODRFileString $data) {
if(isset($this->_filters[$event])) {
foreach($this->_filters[$event] as $callback) {
$data=call_user_func($callback,$data);
}
}
return $data;
}
/**
* loads inputfile and execute filters
* @return filename
*/
public function load() {
if(($template=realpath($this->getConfig("InputFileName", "")))!==false) {
$this->setConfig("InputFileName", $template);
$template_o=$this->filter("load",new PODRFileString(null,$template,$this));
$template=$template_o->getFileName();
}
else
throw new PODRException("InputFileName incorrect : can't access the file.");
return $template;
}
/**
* fetches template and execute filters on output
* @param <type> $filename
* @return PODRFileString result
*/
public function fetch($filename) {
ob_start();
include $filename;
$filename= null;
$result_o=$this->filter("fetch",new PODRFileString(ob_get_clean(),null,$this));
return $result_o;
}
/**
* For compatibility purpose with Savant.
*/
public function eprint($value) {
echo htmlspecialchars($value);
}
/**
* saves generated data in a file and executes filter
* @return PODRFileString outputFile
*/
public function save()
{
return $this->filter("save",$this->fetch($this->load()));
}
/**
* OutputMode = Display => shows the fetched content
* Save => saves outputFile in "OutputFileName"
* HTTP => sends file named "OutputFileName" to browser
*/
public function output() {
$mode=$this->getConfig("OutputMode", "Save");
switch ($mode) {
case self::SAVEMODE_DISPLAY:
echo $this->fetch($this->load())->getContent();
break;
case self::SAVEMODE_HTTP:
$outputfile=$this->save()->getFileName();
if (headers_sent($filename, $linenum)) {
throw new PhpOpenDocumentException("headers already sent ($filename at $linenum)");
}
header('Content-type: '.(($this->getConfig("OutputMimeType", "")!=="")?$this->getConfig("OutputMimeType", ""):$this->getMimeType($this->getConfig("OutputFileName", ""))));
header('Content-Disposition: attachment; filename="'.$this->getConfig("OutputFileName", "").'"');
readfile($outputfile);
unlink($outputfile);
break;
default:
$outputfile=$this->save()->getFileName();
copy($outputfile,$this->getConfig("OutputFileName", ""));
unlink($outputfile);
break;
}
}
public function saveAsFile($filename_out) {
$this->setConfig("OutputFileName", $filename_out);
$this->setConfig("OutputMode",SELF::SAVEMODE_FILE);
$this->output();
}
public function sendHTTP($filename_out,$mimetype="") {
$this->setConfig("OutputFileName", $filename_out);
$this->setConfig("OutputMimeType", $mimetype);
$this->setConfig("OutputMode",SELF::SAVEMODE_HTTP);
$this->output();
}
public static function getExtension($filename) {
return substr(strrchr($filename, '.'), 1);
}
/**
* To be completed
* Common mimetypes
* @param string $filename
* @return string mimetype
*/
protected function getMimeType($filename) {
$ext=$this->getExtension($filename);
$contentType="";
switch($ext) {
case "pdf":
$contentType="application/pdf";
break;
case "doc":
$contentType="application/msword";
break;
case "xls":
$contentType="application/vnd.ms-excel";
break;
case "pps":
case "ppt":
$contentType="application/vnd.ms-powerpoint";
break;
case "rtf":
$contentType="text/rtf";
break;
case "odt":
$contentType="application/vnd.oasis.opendocument.text";
break;
case "htm":
case "html":
$contentType="text/html";
break;
}
return $contentType;
}
}
/**
* This class contains wether a filename or data
* It provides two accessors which takes in charge the saving in a file or the reading from a file.
* This class is mainly used for communication between filters.
* Only one of the two vars must be set ( to have always the same data)
*/
class PODRFileString {
protected $content=null;
protected $filename=null;
protected $context=null;
public function __construct($content,$filename,&$context) {
$this->context=$context;
if($content!==null)
$this->content=$content;
else
$this->filename=$filename;
}
public function getFileName() {
if($this->content!==null) {
$this->filename=tempnam($this->context->getConfig("TempDir", null),"");
file_put_contents($this->filename, $this->content);
$this->content=null;
}
return $this->filename;
}
public function setFilename($value)
{
$this->filename=$value;
$this->content=null;
}
public function getContent() {
if($this->filename!==null) {
$this->content=file_get_contents($this->filename);
unlink($this->filename);
$this->filename=null;
}
return $this->content;
}
public function setContent($value)
{
$this->filename=null;
$this->content=$value;
}
public function getContext() {
return $this->context;
}
}
/**
* Standard Exception class
*/
class PODRException extends Exception
{}
?>