<?
/**
* Width of the page used, in this case A4 size in centimetres
*/
define ("SIZEWIDTHCM",19);
/**
* Height of the page used, in this case A4 size in centimetres
*/
define ("SIZEHEIGHTCM",27);
/**
* Left Margin
*/
define ("BEGINXSVG",10);
/**
* Top Margin
*/
define ("BEGINYSVG",30);
/**
* Characters to be displayed in a line
*/
define ("MAXCHARACTERS",30);
/**
* Returns the microseconds since 0:00:00 January 1, 1970 GMT,
*/
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
/**
* This class is used to represent the information using the svf format
*/
class CSVGEngine
{
/**
* Width of the page
*/
var $m_nWidthSVG =SIZEWIDTHCM;
/**
* Height of the page
*/
var $m_nHeightSVG =SIZEHEIGHTCM;
/**
* Actual CoordX
*/
var $m_nCoordXSVG =BEGINXSVG;
/**
* Actual CoordY
*/
var $m_nCoordYSVG =BEGINYSVG;
/**
* The begining of the last row
*/
var $m_nCoordYSVGAnt;
/**
* Maximun size of the last row
*/
var $m_nSpaceTotal =0;
/**
* Number of pages been generated
*/
var $m_nPagesSVG =1;
/**
* File used to save the svg
*/
var $m_fileSVG;
/**
* Flag file ok
*/
var $m_bFileSVG;
/**
* Path of the directory for the svg files
*/
var $m_strDirectory ="";
/**
* Name of the file, the svgs will be saved using $m_strDirectory\\$m_strFile.$m_nPagesSVg.svg
* example: c:\\temp\\test.1.svg
*/
var $m_strFile ="";
/**
* Constructor of the class
*/
function CSVGEngine($strDirectory,$strFile)
{
$this->m_strDirectory =$strDirectory;
$this->m_strFile =$strFile;
$this->m_nPagesSVG =1;
}
/**
* This method will be invoked when a new svg file has to be created, for example when a page is full
*/
function OpenSVG()
{
// form the path of the new file
$strPathTemp =sprintf("%s%s.%d.svg",$this->m_strDirectory,$this->m_strFile,$this->m_nPagesSVG);
$this->m_fileSVG = @fopen($strPathTemp,"w");
if ($this->m_fileSVG)
{
$this->m_bFileSVG =true;
// Write the svg headers
$this->HeaderSVG();
}
else
$this->m_bFileSVG =false;
// Everything is okey?
return $this->m_bFileSVG;
}
/**
* Calculate if in the actual page is enough space, if not creates a new page after closing the actual page
*/
function IsSpaceYSVG($nDesplY)
{
// If we are very close to the end of the page, we close this page, and create a new one
if (($this->m_nCoordYSVG + $nDesplY) > (0.95 *$this->m_nHeightSVG*100))
{
// close this pages
$this->CloseSVG();
// initialize all the auxiliar variables
$this->m_nCoordYSVG = BEGINYSVG;
$this->m_nCoordXSVG = BEGINXSVG;
$this->m_nSpaceTotal =0.0;
unset($this->m_nCoordYSVGAnt);
$this->m_nPagesSVG = $this->m_nPagesSVG + 1;
// create the new page
$this->OpenSVG();
// false, we have created a new page
return false;
}
// ok,
return true;
}
/**
* Move the actual coordY to coordY + nDesplzY
* if we are to close to the end of the page, close it and create a new one
*/
function MoveCoordYSVG($nDesplY)
{
if (($this->m_nCoordYSVG + $nDesplY) > (0.95 *$this->m_nHeightSVG*100))
{
$this->CloseSVG();
$this->m_nCoordYSVG = BEGINYSVG;
$this->m_nCoordXSVG = BEGINXSVG;
$this->m_nSpaceTotal =0.0;
unset($this->m_nCoordYSVGAnt);
$this->m_nPagesSVG = $this->m_nPagesSVG + 1;
$this->OpenSVG();
}
else
$this->m_nCoordYSVG = $this->m_nCoordYSVG + $nDesplY;
}
/**
* Write to the file the standard svg headers, if you want use another measure units
* you have to change them here
*/
function HeaderSVG()
{
$strHeaderSVG ="<?xml version=\"1.0\" standalone=\"no\"?>";
$strHeaderSVG .="<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ";
$strHeaderSVG .="\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">";
$strTemp =sprintf("<svg width=\"%dcm\" height=\"%dcm\" viewBox=\"0 0 %d %d\" ",
$this->m_nWidthSVG,$this->m_nHeightSVG,
$this->m_nWidthSVG*100,$this->m_nHeightSVG*100);
$strHeaderSVG .=$strTemp;
$strHeaderSVG .="xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n";
if ($this->m_bFileSVG)
fwrite($this->m_fileSVG,$strHeaderSVG);
}
/**
* Write to the file the info about a new test
* The parameters are the name of the test, and the time has begun
*/
function BeginTestSVG($strTest,$timeBegin)
{
$strTemp ="";
$strBeginTest =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"35\" fill=\"black\" text-anchor=\"start\">\n",
$this->m_nCoordXSVG,$this->m_nCoordYSVG);
$strTemp =sprintf("BEGIN %s AT %02d:%02d:%02d",$strTest,$timeBegin["hours"],$timeBegin["minutes"],$timeBegin["seconds"]);
$strBeginTest .=$strTemp;
$strBeginTest .="</text>\n";
$this->MoveCoordYSVG(10);
// Write to the file
if ($this->m_bFileSVG)
{
fwrite($this->m_fileSVG,$strBeginTest);
// Draw a line down the title
$strTemp =sprintf("<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"/>",0,$this->m_nCoordYSVG,$this->m_nWidthSVG*100,$this->m_nCoordYSVG);
fwrite($this->m_fileSVG,$strTemp);
}
// Move to the next position
$this->MoveCoordYSVG(30);
}
/**
* Generate the code to write a new svg text
*/
function WriteTextSVG($strText)
{
$strTemp =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"30\" fill=\"black\" text-anchor=\"start\">\n",
$this->m_nCoordXSVG,$this->m_nCoordYSVG);
$strTemp .=$strText;
$strTemp .="</text>\n";
return $strTemp;
}
/**
* This is the main function, it draws the information about the variable been debugged
* $strCode -> title of the step
* $strNameObj -> name of the object
* $strClass -> name of the class of the object
* $dSecs -> seconds since the last call to debug
*/
function WriteDebugSVG($strCode,$strNameObj,$strClass,$arrVars,$dSecs)
{
// Vertical distance between the lines
$nSpaceVar=30;
if (is_array($arrVars))
$nCount =count($arrVars);
else
$nCount =0;
// if we are too close to the right, we get down to the next line
if ($this->m_nCoordXSVG > (80*$this->m_nWidthSVG))
{
$this->m_nCoordXSVG =BEGINXSVG;
$this->m_nCoordYSVG =$this->m_nCoordYSVGAnt;
$this->MoveCoordYSVG($this->m_nSpaceTotal+$nSpaceVar);
$this->m_nSpaceTotal =0;
unset($this->m_nCoordYSVGAnt);
}
// calculate the vertical space we need to draw all the information
$nSpaceTotal =($nCount + 3) *($nSpaceVar);
// if this space is the biggest we keep it
if ($this->m_nSpaceTotal < $nSpaceTotal)
{
// if the space is too big, we create a new page
$this->IsSpaceYSVG($nSpaceTotal);
// we keep the new value
$this->m_nSpaceTotal =$nSpaceTotal;
}
// if this is not the first column, we recover the begining position y
// for this row
if (isset($this->m_nCoordYSVGAnt))
$this->m_nCoordYSVG =$this->m_nCoordYSVGAnt;
else
$this->m_nCoordYSVGAnt=$this->m_nCoordYSVG;
// we write the name of the step and the seconds since the last call to debug
$strSecs = sprintf("%.6f",$dSecs);
$strTemp =$this->WriteTextSVG($strCode ."(". $strSecs .")");
$this->MoveCoordYSVG($nSpaceVar);
$strTemp .=$this->WriteTextSVG($strNameObj ."(" .$strClass .")");
$this->MoveCoordYSVG($nSpaceVar+10);
// if we have information about the variables of the object, we write the info
if (is_array($arrVars))
{
$nMaxStrlen =0;
reset($arrVars);
while (list($strVar, $strValue) = each($arrVars))
{
$strVarValue =$strVar ." : ". $strValue;
if (strlen($strVarValue) > MAXCHARACTERS)
$strVarValue =substr($strVarValue,0,MAXCHARACTERS) . "...";
$strTemp .=$this->WriteTextSVG($strVarValue);
$this->MoveCoordYSVG($nSpaceVar);
if (strlen($strVarValue) > $nMaxStrlen)
$nMaxStrlen =strlen($strVarValue);
}
}
// the page will be divided into three columns
$this->m_nCoordXSVG = $this->m_nCoordXSVG + 0.33 * $this->m_nWidthSVG*100;
// if we have a valid file, we write the information
if ($this->m_bFileSVG)
fwrite($this->m_fileSVG,$strTemp);
}
/**
* The test is finished, we write the information and the time
*/
function EndTestSVG($strTest,$timeClose)
{
$this->m_nCoordXSVG =BEGINXSVG;
//$this->MoveCoordYSVG(20);
if ($this->m_bFileSVG)
{
$strTemp =sprintf("<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"/>",0,$this->m_nCoordYSVG,$this->m_nWidthSVG*100,$this->m_nCoordYSVG);
fwrite($this->m_fileSVG,$strTemp);
}
$this->MoveCoordYSVG(30);
$strTemp ="";
$strCloseTest =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"35\" fill=\"black\" text-anchor=\"start\">\n",
$this->m_nCoordXSVG,$this->m_nCoordYSVG);
$strTemp =sprintf("CLOSE %s AT %02d:%02d:%02d",$strTest,$timeClose["hours"],$timeClose["minutes"],$timeClose["seconds"]);
$strCloseTest .=$strTemp;
$strCloseTest .="</text>\n";
if ($this->m_bFileSVG)
{
fwrite($this->m_fileSVG,$strCloseTest);
}
}
/**
* Close the actual svg file, and write the last of svg end
*/
function CloseSVG()
{
if ($this->m_bFileSVG)
{
fwrite($this->m_fileSVG,"</svg>");
fclose($this->m_fileSVG);
}
}
/**
* To navigate easily we generate a html file which open the svg,
* and write links to the prev and to next files
*/
function GenHtmlFiles()
{
for ($i=1;$i<=$this->m_nPagesSVG;$i++)
{
$strTemp ="";
$strPathTemp ="";
$strPathTemp =sprintf("%s%s.%d.html",$this->m_strDirectory,$this->m_strFile,$i);
$fileHTML = @fopen($strPathTemp,"w");
if (!$fileHTML)
return;
$strTemp ="<html><head><title>CONTENTS</title>\n";
fwrite($fileHTML,$strTemp);
$strTemp =sprintf("</head><body><embed src=\"%s.%d.svg\" style=\"width: %dcm; height: %dcm\">\n",
$this->m_strFile,$i,$this->m_nWidthSVG,$this->m_nHeightSVG);
fwrite($fileHTML,$strTemp);
if ($this->m_nPagesSVG != 1)
{
$strTemp ="<p align=\"center\"><i><b>\n";
fwrite($fileHTML,$strTemp);
if ($i > 1)
{
$strTemp =sprintf("<a href=\"%s.%d.html\"><FONT face=\"Courier New\" size=2>Prev</font></a> \n",
$this->m_strFile,$i-1);
fwrite($fileHTML,$strTemp);
}
if ($i < $this->m_nPagesSVG)
{
$strTemp =sprintf("<a href=\"%s.%d.html\"><FONT face=\"Courier New\" size=2>Next</font></a>\n",
$this->m_strFile,$i+1);
fwrite($fileHTML,$strTemp);
}
if ($this->m_nPagesSVG != 1)
{
$strTemp ="</i></b></p>\n";
fwrite($fileHTML,$strTemp);
}
}
$strTemp ="</body></html>\n";
fwrite($fileHTML,$strTemp);
}
}
}
/**
* Main class for the user
*/
class CSVGDebug
{
/**
* Path to directory used to save the file
*/
var $m_strDirectory;
/**
* Name of the test
*/
var $m_strTest;
/**
* Time begining the test
*/
var $m_dateBegin;
/**
* Time of the debug event
*/
var $m_timeDebug;
/**
* Time finishing the test
*/
var $m_dateClose;
/**
* SVG Engine to generate the svg files
*/
var $m_SVGEngine;
/**
* Constructor of the class, save the information and creates the svg engine
*/
function CSVGDebug($strDirectory,$strTest)
{
$this->m_strDirectory =$strDirectory;
if ($strTest == "")
$strTest ="test";
$this->m_strTest =$strTest;
$this->m_SVGEngine = new CSVGEngine($this->m_strDirectory,$this->m_strTest);
}
/**
* Begining of the test
*/
function Open()
{
$this->m_dateBegin =getdate();
$this->m_timeDebug =getmicrotime();
// Open the svg file, if everything is ok, generate the svg begining
if ($this->m_SVGEngine->OpenSVG())
{
$this->m_SVGEngine->BeginTestSVG($this->m_strTest,$this->m_dateBegin);
}
}
/**
* Save the information about the variable
*/
function Debug($obj,$strCode)
{
$timeNow=getmicrotime();
$dSecs =$timeNow - $this->m_timeDebug;
$this->m_timeDebug =$timeNow;
$strClassName =get_class($obj);
// if the object is really an object
if (gettype($obj) == "object")
{
// we look if there a special way to evaluate this class
// if the class of the object is Test, the method has to be "EvalTest"
$strEvalClass ="Eval".$strClassName;
if (method_exists($this,$strEvalClass))
{
// For every variable of the object, we validate if we have to show it
$arrVars =get_object_vars($obj);
$arrNewVars = array();
reset($arrVars);
while (list($strVar, $strValue) = each($arrVars))
{
if ($this->$strEvalClass($strVar))
{
$arrNewVars[$strVar] =$strValue;
}
}
// we write the specific information for this class
$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,get_class($obj),$arrNewVars,$dSecs);
}
else
// we write all the information of the class
$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,get_class($obj),get_object_vars($obj),$dSecs);
}
else
{
// the object is not an object, we only write its value
$arrVars = array();
$arrVars["value"] =$obj;
$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,gettype($obj),$arrVars,$dSecs);
}
}
/**
* Specific class information, for the class CSVGEngine we only want to show the value of the variable "m_strDirectory"
*/
function EvalCSVGEngine($strVar)
{
if ($strVar == "m_strDirectory")
return true;
if ($strVar == "m_fileSVG")
return true;
if ($strVar == "m_nPagesSVG")
return true;
return false;
}
/**
* Close the actual test
*/
function Close()
{
$this->m_timeClose =getdate();
$this->m_SVGEngine->EndTestSVG($this->m_strTest,$this->m_timeClose);
$this->m_SVGEngine->CloseSVG();
$this->m_SVGEngine->GenHtmlFiles();
}
}
?>