<?php /** * Documentation of a class * * @author axel */ class classinfos { var $sClassname=''; var $oRefClass=false; var $sGoTop='<a href="#">top</a><br><br>'; var $sHtmlFooter='<div id="footer">Simple class documentation - © <a href="http://www.axel-hahn.de/">www.axel-hahn.de</a></div>'; /** * init function; it sets defaults. * @return bool (dummy) */ public function __construct($sClassname){ if($sClassname) $this->setClassname($sClassname); } public function setClassname($sClassname){ $this->oRefClass=false; $this->sClassname=$sClassname; $this->oRefClass=new ReflectionClass($this->sClassname); } /** * get comment of an object * @param object $o * @return string (html code) */ private function getComment($o){ $sReturn=$o->getDocComment(); if (!$sReturn) return ''; // all @-Tags $aTags=array( "abstract","access", "author", "category", "copyright", "deprecated", "example", "final", "filesource", "global", "ignore", "internal", "license", "link", "method", "name", "package", "param", "property", "return", "see", "since", "static", "staticvar", "subpackage", "todo", "tutorial", "uses", "var", "version" ); /* $aTagsFollowedByKeyword=array( "access", "global", "method", "param", "property", "return", "see", "since", "static", "staticvar", "subpackage", "todo", "tutorial", "uses", "var" ); * */ $sReturn=preg_replace('@[\ \t][\ \t]*@', ' ', $sReturn); // remove multiple spaces $sReturn=preg_replace('@^\/\*\*@', '', $sReturn); // remove first comment line $sReturn=preg_replace('@.*\*\/@', '', $sReturn); // remove last comment line $sReturn=preg_replace('@ \* @', '', $sReturn); // remove " * " $sReturn=preg_replace('@\n@', '<br>', $sReturn); $sReturn=preg_replace('@^\<br\>@', '', $sReturn); /* foreach(array("param", "return", "var") as $sKey){ $sReturn=preg_replace('/\@'.$sKey.' ([a-zA-Z\|]*)\ (.*)\<br\>/U', '@'.$sKey.' <span style="font-weight: bold; color:#000;">$1</span> <span style="font-weight: bold;">$2</span><br>', $sReturn); } */ $sReturn=preg_replace('/(\@.*)$/s', '<span class="phpdoc">$1</span>', $sReturn); foreach($aTags as $sKey){ $sReturn=preg_replace('/\@('.$sKey.')/U', '<span class="doctag">@'.$sKey.'</span>', $sReturn); } return $sReturn; // return $sReturn='<div class="comment">'. $sReturn . '</div>'; } public function renderProperties($sMode){ if(!$this->oRefClass) return false; $sHtml=''; $sHtml.='<div class="properties">'; if ($sMode=="html"){ $sHtml.='<h2 id="properties">Properties</h2>'; } else { $sHtml.=' <a href="#" class="propertyswitch" onclick="$(\'.propertyswitch\').toggle(); $(\'.property\').hide(); return false;">Properties verstecken</a> <a href="#" class="propertyswitch" onclick="$(\'.propertyswitch\').toggle(); $(\'.property\').show(); return false;" style="display: none">Properties anzeigen</a> | <a href="#" class="publicpropertyswitch" onclick="$(\'.publicpropertyswitch\').toggle(); $(\'.property.private\').hide(); return false;" style="display: none">private verstecken</a> <a href="#" class="publicpropertyswitch" onclick="$(\'.publicpropertyswitch\').toggle(); $(\'.property.private\').show(); return false;">private anzeigen</a> <br><br>'; } $oDefaulProps=$this->oRefClass->getDefaultProperties(); // foreach($this->oRefClass->getProperties(ReflectionProperty::IS_PROTECTED) as $o){ foreach($this->oRefClass->getProperties() as $o){ $sType=''; if($o->isPublic()) $sType.='public'; if($o->isPrivate()) $sType.='private'; if($o->isProtected()) $sType.='protected'; if($o->isStatic()) $sType.='static'; $sHtml.='<div class="property '.$sType.'">'; $sHtml.='<span class="propertytype">'.$sType.'</span><span class="propertyname"> $'.$o->getName().'</span>'; $sHtml.='<span class="propertyvalue"> = '; if ($oDefaulProps[$o->getName()]) $sHtml.=$oDefaulProps[$o->getName()]; else $sHtml.='false'; $sHtml.='</span>'; $sHtml.=$this->getComment($o); $sHtml.='</div>'; } $sHtml.='</div>'; return $sHtml; } public function renderMethods($sMode){ if(!$this->oRefClass) return false; $sHtml=''; $sHtml.='<div class="methods">'; if ($sMode=="html"){ $sHtml.='<h2 id="methods">Methods</h2>'; } else { $sHtml.=' <a href="#" class="methodswitch" onclick="$(\'.methodswitch\').toggle(); $(\'.method\').hide(); return false;">Methoden verstecken</a> <a href="#" class="methodswitch" onclick="$(\'.methodswitch\').toggle(); $(\'.method\').show(); return false;" style="display: none">Methoden anzeigen</a> | <a href="#" class="publicmethodswitch" onclick="$(\'.publicmethodswitch\').toggle(); $(\'.method.private\').hide(); return false;" style="display: none">private verstecken</a> <a href="#" class="publicmethodswitch" onclick="$(\'.publicmethodswitch\').toggle(); $(\'.method.private\').show(); return false;">private anzeigen</a> <br><br>'; } $sHtml.='<table>'; foreach($this->oRefClass->getMethods() as $o){ $sMethodname=$o->name; $sType=''; if($o->isPublic()) $sType.='public'; if($o->isPrivate()) $sType.='private'; if($o->isProtected()) $sType.='protected'; if($o->isStatic()) $sType.='static'; if($o->isAbstract()) $sType.='abstract'; if($o->isFinal()) $sType.='final'; /* $sHtml.='<div class="method '.$sType.'">'; $sHtml.=$sType . ' <span class="methodname">' .$sMethodname . "</span>("; $oMethod = $this->oRefClass->getMethod($sMethodname); $sHtml.='<span class="parameters">' ; $iCount=0; $iRequired=$oMethod->getNumberOfRequiredParameters(); foreach($oMethod->getParameters() as $oParam){ $iCount++; $sHtml.='<span class="'; $sHtml.=$iCount<=$iRequired ? "required":"optional"; $sHtml.='">'. preg_replace('@Parameter\ \#.*\[\ (.*)\ \]@', '$1', $oParam->__toString()).'</span>,'; } $sHtml=preg_replace('@,$@', "", $sHtml); $sHtml.="</span>)"; if ($iRequired){ if ($iCount==$iRequired) $sHtml.=' ... all param(s) required'; else $sHtml.=' ... '.$iRequired . ' of '.$iCount.' param(s) required'; } $sHtml.=$this->getComment($oMethod); $sHtml.='</div>'; */ $sHtml.='<tr class="method '.$sType.'">'; $sHtml.='<td><span class="methodname">' .$sMethodname . '</span></td>' . '<td>'.$sType . ' </td>' . '<td><span class="methodname">' .$sMethodname . '</span>('; $oMethod = $this->oRefClass->getMethod($sMethodname); $sHtml.='<span class="parameters">' ; $iCount=0; $iRequired=$oMethod->getNumberOfRequiredParameters(); foreach($oMethod->getParameters() as $oParam){ $iCount++; $sHtml.='<span class="'; $sHtml.=$iCount<=$iRequired ? "required":"optional"; $sHtml.='">'. preg_replace('@Parameter\ \#.*\[\ (.*)\ \]@', '$1', $oParam->__toString()).'</span>,'; } $sHtml=preg_replace('@,$@', "", $sHtml); $sHtml.="</span>)"; if ($iRequired){ if ($iCount==$iRequired) $sHtml.=' ... all param(s) required'; else $sHtml.=' ... '.$iRequired . ' of '.$iCount.' param(s) required'; } // $sHtml.='</td><td>'; $sHtml.=$this->getComment($oMethod); $sHtml.='<br></td></tr>'; } $sHtml.='</table>'; $sHtml.='</div>'; return $sHtml; } function renderSource($sMode){ $source_code=file_get_contents($this->oRefClass->getFileName()); $sHtml='<div class="sourcecode">'; if ($sMode=="html"){ $sHtml.='<h2 id="source">Source</h2>'; } else{ $sHtml.=' <a href="#" class="sourceswitch" onclick="$(\'.sourceswitch\').toggle(); $(\'.source\').hide(); return false;">Sourcecode verstecken</a> <a href="#" class="sourceswitch" onclick="$(\'.sourceswitch\').toggle(); $(\'.source\').show(); return false;" style="display: none">Sourcecode anzeigen</a><br> <br>'; } $sHtml.='<pre class="source">' . highlight_string($source_code, true) .'</pre></div>'; return $sHtml; /* $source_code = explode("\n", str_replace(array("\r\n", "\r"), "\n", $source_code)); $line_count = 1; foreach ($source_code as $code_line) { $formatted_code .= '<tr><td>'.$line_count.'</td>'; $line_count++; if (ereg('<\?(php)?[^[:graph:]]', $code_line)) $formatted_code .= '<td>'. str_replace(array('<code>', '</code>'), '', highlight_string($code_line, true)).'</td></tr>'; else $formatted_code .= '<td>'.ereg_replace('(<\?php )+', '', str_replace(array('<code>', '</code>'), '', highlight_string('<?php '.$code_line, true))).'</td></tr>'; } return '<table style="font: 1em Consolas, \'andale mono\', \'monotype.com\', \'lucida console\', monospace;">'.$formatted_code.'</table>'; */ } public function render($sMode=false){ $sHtml=''; if(!$this->oRefClass) return false; if ($sMode=="html") $sHtml.=' <html> <head> <title>PHP class '.$this->sClassname.'</title> </head> <style> body{font-family: Arial,Helvetica,Verdana,sans-serif; background: #fafafa; color: #444;} a{color:#348; text-decoration: none;} a:hover{text-decoration: underline;} h1{color:#88c; border-bottom: 3px solid #ddf;} h2{color:#44a; border-bottom: 3px solid #ddf;} #footer{border-top: 3px solid #eee; background:#f4f4f4; margin-top:20px; padding: 5px; text-align: center;} </style> <body> <h1>Simple class documentation - '.$this->sClassname.'</h1> local links: <a href="#methods">Methods</a> :: <a href="#properties">Properties</a> :: <a href="#source">Source</a><br> <br> '; $sHtml.=' <style> .protected, .private, .public, .static, .abstract, .final{padding-left: 34px; } .classinfo .protected {background: url(/axel/images/nuvola/16x16/actions/kgpg.png) no-repeat 10px 10px; } .classinfo .private {background: rgba(255,220,220,0.3) url(/axel/images/nuvola/16x16/actions/kgpg_key1.png) no-repeat 10px 10px; display:none; } .classinfo .public {background: rgba(220,255,220,0.3) url(/axel/images/nuvola/16x16/actions/ledlightgreen.png) no-repeat 10px 10px; } .classinfo .static {background: url(/axel/images/nuvola/16x16/actions/ledyellow.png) no-repeat 10px 10px;} .classinfo .abstract {background: url(/axel/images/nuvola/16x16/actions/ledpurple.png) no-repeat 10px 10px;} .classinfo .final {background: url(/axel/images/nuvola/16x16/actions/ledred.png) no-repeat 10px 10px;} .classinfo{border: 0px solid #aac; padding: 5px;} .classinfo .classname{font-weight: bold; font-size: 130%;} .classinfo .methods, .classinfo .properties, .classinfo .sourcecode{margin-left: 20px; border: 0px solid #ccc; margin-top: 20px; } .classinfo .property, .classinfo .method, .classinfo .source{margin-left: 30px; margin-top: 10px; border-top: 0px dotted #ccc; padding-top: 10px;} .classinfo .methodname{font-weight: bold;} .classinfo .propertyname{font-weight: bold;} .classinfo .propertyvalue{font-style: italic; color:#aaa;} .classinfo .parameters{font-style: italic; color:#aaa;} .classinfo .parameters .required {background:rgba(255,210,210,1);color:#666;} .classinfo .comment{margin: 10px 0 0 0px; padding: 10px; background-color:rgba(255,255,255,0.4);} .classinfo .comment .phpdoc{font-style: italic; color:#8aa; font-weight: normal;} .classinfo .comment .phpdoc .doctag{color:#a8a; font-weight: normal;} .classinfo .sourcecode .source{border: 1px solid #eee; padding: 10px;} </style> '; $sHtml.='<div class="classinfo">'; $sHtml.='<div class="classname">Class: '.$this->sClassname.'</div>'; /* foreach (array("public","private","protected", "static", "abstract", "final") as $sType){ print '<input type="checkbox" onclick="$(\'.'.$sType.'\').toggle();"'; if ($sType=="public") print " checked "; print '> '. $sType . ' ... '; } */ if (!$sMode) $sHtml.=' <style> .classinfo .comment{display:none;} </style> <!-- Ansicht: <ul class="naviH" > <li class="active"><a href="#" class="viewswitch" onclick="$(\'.naviH >li\').removeClass(\'active\'); $(this.parentNode).addClass(\'active\'); $(\'.comment\').hide(); return false;">einfach</a> <li><a href="#" class="viewswitch" onclick="$(\'.naviH >li\').removeClass(\'active\'); $(this.parentNode).addClass(\'active\'); $(\'.comment\').show(); return false;">erweitert</a> </ul> --> </span> <br>'; $sHtml.=$this->renderMethods($sMode); if ($sMode=="html") $sHtml.=$this->sGoTop; $sHtml.=$this->renderProperties($sMode); if ($sMode=="html") $sHtml.=$this->sGoTop; if ($sMode=="html") $sHtml.=$this->renderSource($sMode); if ($sMode=="html") $sHtml.=$this->sGoTop; if ($sMode=="html") $sHtml.=$this->sHtmlFooter; $sHtml.='</div>'; // print "DocComment:<br>".$this->$oRefClass->getDocComment(); // $this->renderMethods(); if ($sMode=="html") $sHtml.=' </body> </html>'; // echo $sHtml; return $sHtml; } }