<?php
/**
* @Name: phpMyReflector1.0.php
* @Version: 1.0.1
* @License: No License - Free to use / modify
* @Date: 13-06-2008
* @Url: http://phpmyreflector.abisvmm.nl
*/
/**
* @Usage:
* ----------------------------------------------------------------
* ----------------------------------------------------------------
*/
class phpMyReflector
{
/* Properties */
/**
* @Name: files
* @Author: Martijn Beulens <hide@address.com>
* @Access: private
* @Since: version 10.00001
* @Comment: Array of php classes to reflect
*/
private $files;
/**
* @Name: rp
* @Author: Martijn Beulens <hide@address.com>
* @Access: private
* @Since: version 10.00001
* @Comment: Reflector pointer
*/
private $rp;
/**
* @Name: structure
* @Author: Martijn Beulens <hide@address.com>
* @Access: private
* @Since: version 10.00001
* @Comment: Reflection structure
*/
private $structure;
//--------------------------------------------------------------------------------
/**
* @Name: __construct
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Constructor
*/
public function __construct()
{
//Set defaults
$this->files = array();
}
//--------------------------------------------------------------------------------
/**
* @Name: addFile
* @Author: Martijn Beulens <hide@address.com>
* @Param: (string) fileName
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: addFile
*/
public function addFile($fileName)
{
//Test if file exists
if(!file_exists($fileName))
return false;
//Append file
$this->files[] = $fileName;
return true;
}
//--------------------------------------------------------------------------------
/**
* @Name: reflect
* @Author: Martijn Beulens <hide@address.com>
* @Param: (string) className
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: reflect
*/
public function reflect($className,$showParent=false,$showComments=false)
{
try
{
//Include files
foreach($this->files as $fileName)
include_once($fileName);
//Test if class exists
if( !class_exists($className) && !interface_exists($className) )
throw new Exception(sprintf('Unable to find class or interface "%s"',$className));
//Var
$reflectionStructure = array();
//Open reflection
$this->rp = new ReflectionClass($className);
//Populate structure
$this->populateStructure($showParent,$showComments);
//Print header
echo $this->parseClassHeader();
//Print properties
echo $this->parseClassProperties();
//Print methods
echo $this->parseClassMethods();
}
catch(Exception $ex)
{
echo "<h2>Error</h2>";
echo "<p>".$ex->getMessage()."</p>";
}
}
//--------------------------------------------------------------------------------
/**
* @Name: reflect2Page
* @Author: Martijn Beulens <hide@address.com>
* @Param: (string) className
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: reflect2Page
*/
public function reflect2Page($className,$showParent=false,$showComments=false)
{
//Print html header
echo $this->getHtmlHeader();
//Reflect
$this->reflect($className,$showParent,$showComments);
//Print html footer
echo $this->getHtmlFooter();
}
//--------------------------------------------------------------------------------
/**
* @Name: getHtmlHeader
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Gets html header
*/
public function getHtmlHeader()
{
//Var
$html = '';
//Build
$html .= "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
$html .= "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";
$html .= "<head>\n";
$html .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
$html .= "<title>Refelc</title>\n";
$html .= $this->getCssStyles();
$html .= "</head>\n";
$html .= "<body>\n";
//Return
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: getHtmlFooter
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: void
* @Access: public
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Gets html footer
*/
public function getHtmlFooter()
{
//Var
$html = '';
//Build
$html .= "</body>\n";
$html .= "</html>\n";
//Return
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: getCssStyles
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: (string) html
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: getCssStyles
*/
public function getCssStyles()
{
//Var
$html = "<style type=\"text/css\">\n";
//Build styles
$html .= "html,body { font-family: \"Trebuchet MS\",Arial,Verdana, Helvetica, sans-serif, }\n";
$html .= "table.view { background-color: ThreeDShadow; margin-bottom: 10px; }\n";
$html .= "table.view th { text-align: left; background-color: ThreeDFace; color: #000000; }\n";
$html .= "table.view td { text-align: left; background-color: #FFFFFF; padding: 2px 6px 2px 6px;}\n";
$html .= ".s_className { font-weight: bold; color: #0000FF; }\n";
$html .= ".s_interface { font-weight: bold; color: #FF00FF; }\n";
$html .= ".s_abstract { font-weight: bold; color: #006600; }\n";
$html .= ".s_extends { font-weight: bold; color: #006633; }\n";
$html .= ".s_implements { font-weight: bold; color: #006633; }\n";
$html .= ".s_parentProperty { color: #999999; }\n";
$html .= ".s_property { color: #000099; }\n";
$html .= ".s_comment { color: #FF9900; }\n";
$html .= ".s_parentMethod { color: #999999; }\n";
$html .= ".s_method { color: #000099; }\n";
$html .= ".s_parameter { color: #0099FF; font-weight: bold; }\n";
$html .= ".s_accessStyle { color: #006600; }\n";
$html .= ".s_accessStyleBoldItalic { font-style: italic; font-weight: bold; color: #006600; }\n";
$html .= ".s_accessStyleItalic { font-style: italic; color: #006600; }\n";
$html .= "\n";
$html .= "</style>\n";
//Return
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: populateStructure
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: void
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Creates structure array with reflector components
*/
private function populateStructure($showParent,$showComments)
{
//Reset
$this->structure = array();
//Populate
$this->structure['showParent'] = $showParent;
$this->structure['showComments'] = $showComments;
$this->structure['className'] = $this->rp->getName();
$this->structure['parentClass'] = $this->rp->getParentClass();
$this->structure['interfaces'] = $this->rp->getInterfaces();
$this->structure['properties'] = $this->rp->getProperties();
$this->structure['methods'] = $this->rp->getMethods();
$this->structure['isAbstract'] = $this->rp->isAbstract();
$this->structure['isInterface'] = $this->rp->isInterface();
}
//--------------------------------------------------------------------------------
/**
* @Name: parseClassHeader
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: (string) html
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Parses the class header
*/
private function parseClassHeader()
{
//Var
$html = '';
//Comment
$html .= "\n<!-- Class Header -->\n";
$html .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"1\" class=\"view\">";
$html .= "<tr>\n<th colspan=\"10\">Class</th>\n</tr>\n";
$html .= "<tr>\n";
$html .= "<td>\n";
//Start print
$html .= "<span class=\"s_className\">\n";
//Test abstract
if($this->structure['isAbstract'])
$html .= "<span class=\"s_abstract\">abstract</span> ";
//Test interface
if($this->structure['isInterface'])
$html .= "<span class=\"s_interface\">interface</span> ";
//Print classname
$html .= $this->structure['className'];
//Extend
if(isset($this->structure['parentClass']->name))
{
$html .= "<span class=\"s_extends\"> extends</span> ";
$html .= "<span class=\"s_className\"> ".$this->structure['parentClass']->name."</span> ";
}
//Interfaces
if(!empty($this->structure['interfaces']))
{
$html .= "<span class=\"s_implements\"> implements</span> ";
$interfaceArray = array();
foreach($this->structure['interfaces'] as $interface)
$interfaceArray[] = $interface->getName();
$html .= "<span class=\"s_interface\"> ".implode(',',$interfaceArray)."</span> ";
}
//End
$html .= "</span>\n";
$html .= "</td>\n";
$html .= "</tr>\n";
$html .= "</table>\n";
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: parseClassProperties
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: (string) html
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Parses the class properties
*/
private function parseClassProperties()
{
//Var
$html = '';
//Test
if(!empty($this->structure['properties']))
{
//Comment
$html .= "\n<!-- Class Properties -->\n";
//Table start
$html .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"1\" class=\"view\">\n";
//Properties
$html .= "<tr>\n<th colspan=\"4\">Properties</th>\n</tr>\n";
$html .= "<tr>\n";
$html .= "<th>Class</th>\n";
$html .= "<th>Access</th>\n";
$html .= "<th>Name</th>\n";
if($this->structure['showComments'])
$html .= "<th>Comment</th>\n";
$html .= "</tr>\n";
//Properties
foreach($this->structure['properties'] as $property)
{
//Map declaring class
$DeclaringClass = $property->getDeclaringClass();
//Determin if propertie is from current class
$show = false;
$PropertyClass = "s_property";
if($this->structure['showParent'])
$show = true;
if(strtolower($this->structure['className'])==strtolower($DeclaringClass->getName()))
$show = true;
else
$PropertyClass = "s_parentProperty";
//$show = true;
if($show)
{
$html .= "<tr>\n";
$html .= "<td>";
$html .= $DeclaringClass->getName();
$html .= "</td>\n";
$html .= "<td>";
$html .= $this->showAccess($property);
$html .= "</td>\n";
$html .= "<td class=\"".$PropertyClass."\">";
$html .= $property->getName();
$html .= "</td>\n";
if($this->structure['showComments'])
{
$html .= "<td class=\"s_comment\">";
$html .= $this->escapeComments($property->getDocComment());
$html .= "</td>\n";
}
$html .= "</tr>\n";
}
} //End foreach($Properties as $Property)
$html .= "</table>\n";
} //End if(!empty($properties))
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: parseClassMethods
* @Author: Martijn Beulens <hide@address.com>
* @Param: void
* @Return: (string) html
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Parses the class methods
*/
private function parseClassMethods()
{
//Var
$html = '';
//Comment
$html .= "\n<!-- Class Methods -->\n";
//Table start
$html .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"1\" class=\"view\">";
//Methods
$html .= "<tr>\n<th colspan=\"10\">Methods</th>\n</tr>\n";
//Header
$html .= "<tr>\n";
$html .= "<th>Class</th>\n";
$html .= "<th>Access</th>\n";
$html .= "<th>Name</th>\n";
$html .= "<th>Parameters</th>\n";
if($this->structure['showComments'])
$html .= "<th>Comment</th>\n";
$html .= "</tr>\n";
//Loop Methods
foreach ($this->structure['methods'] as $Method)
{
//Map declaring class
$DeclaringClass = $Method->getDeclaringClass();
//Map parameters
$ParameterArray = array();
foreach($Method->getParameters() as $Parameter)
$ParameterArray[] = '$'.$Parameter->name.'';
//Color
$MethodClass = "s_method";
$show = false;
if($this->structure['showParent'])
$show = true;
if(strtolower($this->structure['className'])==strtolower($DeclaringClass->getName()))
$show = true;
else
$MethodClass = "s_parentMethod";
if($show)
{
$html .= "<tr>\n";
$html .= "<td>\n";
$html .= $DeclaringClass->getName();
$html .= "</td>\n";
$html .= "<td>\n";
$html .= $this->showAccess($Method);
$html .= "</td>\n";
$html .= "<td class=\"".$MethodClass."\">\n";
$html .= $Method->getName();
$html .= "</td>\n";
$html .= "<td class=\"s_parameter\">\n";
$html .= implode(', ',$ParameterArray);
$html .= "</td>\n";
if($this->structure['showComments'])
{
$html .= "<td class=\"s_comment\">\n";
$html .= $this->escapeComments($Method->getDocComment());
$html .= "</td>\n";
}
$html .= "</tr>\n";
}
}
//Table end
$html .= "</table>\n";
return $html;
}
//--------------------------------------------------------------------------------
/**
* @Name: escapeComments
* @Author: Martijn Beulens <hide@address.com>
* @Param: (string) comments
* @Return: (string) escaped comments
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Escapes the comments
*/
private function escapeComments($comment)
{
//Var
$returnString = str_replace(array("\n","\r"),array('',''),$comment);
$pattern = "/\/\*\*(.*)\*\//";
//Match
preg_match_all($pattern,$returnString,$matches);
//Test
if(!empty($matches[1][0]))
$returnString = trim($matches[1][0]);
return $returnString;
}
//--------------------------------------------------------------------------------
/**
* @Name: showAccess
* @Author: Martijn Beulens <hide@address.com>
* @Param: (object) property / method
* @Return: (string) styled access
* @Access: private
* @Exception: no
* @Since: version Sun 13 apr 2008
* @Comment: Shows type of access
*/
private function showAccess($Method)
{
$access = "";
$accessstyle = "s_accessStyle";
switch(true)
{
case $Method->isPublic();
$access = "public";
break;
case $Method->isPrivate();
$access = "private";
$accessstyle = "s_accessStyleBoldItalic";
break;
case $Method->isProtected();
$access = "protected";
$accessstyle = "s_accessStyleItalic";
break;
case $Method->isAbstract();
$access = "abstract";
break;
case $Method->isFinal();
$access = "final";
break;
case $Method->isConstructor();
$access = "constructor";
break;
case $Method->isDestructor();
$access = "destructor";
break;
default:
$access = "unknown";
break;
}
return sprintf("<span class=\"%s\">%s</span>",$accessstyle,$access);
}
//--------------------------------------------------------------------------------
} //End class
?>