Location: PHPKode > scripts > phpMyReflector > phpmyreflector/phpmyreflector1.0.php
<?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


?>
Return current item: phpMyReflector