LineCounter.class.php
Aus Programmers Guide
(Unterschied zwischen Versionen)
Roy (Diskussion | Beiträge) |
Roy (Diskussion | Beiträge) |
||
Zeile 6: | Zeile 6: | ||
//http://code.google.com/p/phpcyclo/source/browse/trunk/+phpcyclo+--username+bolter.fire/lint_php_lib.php?spec=svn2&r=2 | //http://code.google.com/p/phpcyclo/source/browse/trunk/+phpcyclo+--username+bolter.fire/lint_php_lib.php?spec=svn2&r=2 | ||
//http://github.com/pceres | //http://github.com/pceres | ||
- | define(MCCABE, | + | define(MCCABE,true); |
+ | |||
if(MCCABE){ | if(MCCABE){ | ||
require_once('lint_php_lib.php'); | require_once('lint_php_lib.php'); | ||
Zeile 76: | Zeile 77: | ||
private $ccWert; | private $ccWert; | ||
private $ccFunction; | private $ccFunction; | ||
+ | private $filePointer; | ||
private $fileTypeArray = array(); | private $fileTypeArray = array(); | ||
Zeile 189: | Zeile 191: | ||
- | + | /** | |
+ | * determineCC() determine the cyclomatic complexity of the given file | ||
+ | * | ||
+ | * @access: private | ||
+ | * @param Str $file | ||
+ | * | ||
+ | * @return NONE | ||
+ | */ | ||
private function determineCC($file){ | private function determineCC($file){ | ||
//Wir oeffenen ein zweites mal die Datei, koennte optimiert werden | //Wir oeffenen ein zweites mal die Datei, koennte optimiert werden | ||
- | $ | + | $filePointer = file_get_contents($file); |
- | + | ||
- | + | //wenn die Datei leer ist muehen wir uns nicht weiter | |
- | + | if($filePointer != ''){ | |
+ | $result = lint($filePointer,0); | ||
+ | foreach ($result[0]['lista_functions'] as $value){ | ||
+ | if($value['function'] != ""){ | ||
+ | $this->CC [basename($file)] [$value['function']] = $value['mc_count']; | ||
+ | } | ||
} | } | ||
- | } | + | } |
} | } | ||
Version vom 15:12, 10. Mai 2010
LineCounter.class.php
<?php //to get McCabes cyclomatic complexity of the Source-Code //http://code.google.com/p/phpcyclo/source/browse/trunk/+phpcyclo+--username+bolter.fire/lint_php_lib.php?spec=svn2&r=2 //http://github.com/pceres define(MCCABE,true); if(MCCABE){ require_once('lint_php_lib.php'); } /* CLASS LineCounter * * This class counts the lines of code (LOC) in an existing Project-Folder. * * ############################# * USAGE: * * $count = new LineCounter(); * $count->setFolder('/var/www/search/'); * $count->setFileTypes('php,txt'); * OR * $count = new LineCounter('/var/www/','php,txt'); * * $count->scanDirectory(); * echo $count->getLines()." total Lines<br>"; * echo $count->getSize()." byte<br>"; * echo $count->getFiles()." Files<br>"; * echo $count->getCommentLines()." CommentLine<br>"; * echo $count->getEmptyLines()." EmtyLine<br>"; * $count->displayExactOutput(); * * ############################ * METHODS: * __construct([string $folder, string $fileTypes]) * public void setFolder(string $folder) * public void setFileTypes(string $fileTypes) * * public void scanDirectory(void) * * public int getLines(void) * public int getSize(void) * public int getFiles(void) * public int getCommentLines(void) * public int getEmptyLines(void) * * public void displayExactOutput(void) * * void countLines * void lineScan * void throwNotScannedException * * * * * @author Roy Bohn <roybohn11@web.de> -> www.roy-bohn.de * @date 2010-05-10 */ class LineCounter{ // declare class variables private $fileName; private $folder; private $file; private $fileType; private $fileHandle; private $dirIterator; private $line; private $val; private $value; private $actVal; private $percentComments; private $cc; private $ccWert; private $ccFunction; private $filePointer; private $fileTypeArray = array(); private $latestValues = array(); private $result = array(); /** * Constructor - Is called when the class is instanced * * @access: public * @param Str $folder * @param Str $fileTypes * * @return NONE */ public function __construct($folder='.',$fileTypes='php'){ //Deklarieren und Initialisieren der Variablen $this->lines = 0; //globaler Zeilenzaehler $this->commentLines = 0; //globaler Kommentarzaehler $this->emptyLines = 0; //globaler Leerzeilenzaehler $this->outputArray = array(); //fuer die Statistikausgabe $this->fileTypes = explode(",",$fileTypes); //inkludierte Dateitypen $this->files = 0; //globaler Dateienzaehler $this->size = 0; //globaler Dateigroessenzaehler $this->folder = $folder; //Der Pfad $this->isScanned = false; //fuer die Fehlerbehandlung scan-Indikator if(MCCABE) $this->CC = array(); //Array fuer McCabes cyclomatic complexity } /** * scanDirectory() Scanning the given Directory recursive and filter the FileTypes * * @access: public * * @return NONE */ public function scanDirectory(){ //DirIterator setzen $dirIterator = new RecursiveDirectoryIterator($this->folder); //Ueber das DIR Iterieren foreach (new RecursiveIteratorIterator($dirIterator) as $fileName => $file) { //fuer den Regex das Array mit | zusammenfuehern $fileTypes = implode("|",$this->fileTypes); //per Regex die Dateien filtern if(preg_match("/^.+\.(" . $fileTypes . ")$/i",$fileName)){ $this->size += $file->getSize(); $this->countLines(basename($fileName), $file); if(MCCABE) $this->determineCC($fileName); $this->files++; } } //die Variable dient nur der Fehlerbehandlung weiter unten $this->isScanned=true; }//END:scanDirectory() /** * countLines() Counts the occurent Lines for each file * * @access: private * @param Str $fileName * @param Str $file * * @return NONE */ private function countLines($fileName,$file){ //Letzten Stand festhalten, damit wir die aktiven Werte clever bestimmen koennen $latestValues = array($this->commentLines,$this->emptyLines,$this->lines); //Datei lesen if ($fileHandle = fopen($file, 'r')) { while (!feof($fileHandle)) { if ($line = fgets($fileHandle)) { $this->lineScan($line); } } fclose($fileHandle); } //Das Array fuer die Detailierte Ausgabe fuellen array_push($this->outputArray, array($fileName,$this->commentLines-$latestValues[0],$this->emptyLines-$latestValues[1],$this->lines-$latestValues[2])); }//END:countLines() /** * lineScan() categorize the given Line * * @access: private * @param Str $line * * @return NONE */ private function lineScan($line){ //der Regex passt auf Zeilen die folgendermaßen beginnen: // '/*' '*' '*/' '//' if(preg_match('/^\/\/|^\/\*|^\*|^\*\//',trim($line))){ $this->commentLines++; } //wenn der Regex keine geschriebene Zeile erkennt deklarieren wir als leer if(!preg_match('/./',trim($line))){ $this->emptyLines++; } //Zeilen hochzaehlen $this->lines++; }//END:lineScan(); /** * determineCC() determine the cyclomatic complexity of the given file * * @access: private * @param Str $file * * @return NONE */ private function determineCC($file){ //Wir oeffenen ein zweites mal die Datei, koennte optimiert werden $filePointer = file_get_contents($file); //wenn die Datei leer ist muehen wir uns nicht weiter if($filePointer != ''){ $result = lint($filePointer,0); foreach ($result[0]['lista_functions'] as $value){ if($value['function'] != ""){ $this->CC [basename($file)] [$value['function']] = $value['mc_count']; } } } } /** * throwNotScannedException() Throw an Exception * * @access: private * @throws Exception * @return NONE */ private function throwNotScannedException(){ throw new Exception("Es wurde noch nicht gescannt bitte: LineCounter::scanDirectory() aufrufen!"); } /* ### ### ### ### ### ### Getters and Setters ### ### ### ### ##*/ /** * getLines() get the whole Lines * * @access: public * * @return Int $lineCounter */ public function getLines(){ if($this->isScanned) return $this->lines; else $this->throwNotScannedException(); } /** * getFiles() get the whole Files * * @access: public * * @return Int $fileCounter */ public function getFiles(){ if($this->isScanned) return $this->files; else $this->throwNotScannedException(); } /** * getSize() get the calculated filesize * * @access: public * * @return Int $fileSize */ public function getSize(){ if($this->isScanned) return $this->size; else $this->throwNotScannedException(); } /** * getCommentLines() get the whole Commentlines * * @access: public * * @return Int $commentedLines */ public function getCommentLines(){ if($this->isScanned) return $this->commentLines; else $this->throwNotScannedException(); } /** * getEmptyLines() get the whole empty Lines * * @access: public * * @return Int $emptyLines */ public function getEmptyLines(){ if($this->isScanned) return $this->emptyLines; else $this->throwNotScannedException(); } /** * getExactOutput() get an array including statistics * * @access: public * * @return Array $statisticArray */ public function getExactOutput(){ if($this->isScanned) return $this->outputArray; else $this->throwNotScannedException(); } /** * displayExactOutput() show statistics * * @access: public * @throws Exception * * @return NONE */ public function displayExactOutput(){ if($this->isScanned){ echo "<table border=\"1\">"; echo "<tr><th>Dateiname</th><th>Kommentare</th><th>Leerzeilen</th><th>Gesamtzeilen</th><th>Lines of Code (LOC)</th><th>% Kommentare</th>"; if(MCCABE) echo "<th>McCabes cc >10</th>"; echo "</tr>"; foreach($this->getExactOutput() as $val){ $LOC = $val[3] - $val[2] - $val[1]; if($val[3]!=0){//wir duefen ja nicht durch 0 dividieren $percentComments=round($val[1]/$val[3]*100); } //Man sagt, dass 30% Kommentare in den Quelltext gehoeren if($percentComments <= 30){ echo "<tr style=\"background-color:#FFDDDD\">"; }else{ echo "<tr style=\"background-color:lightgreen\">"; } foreach($val as $actVal){ echo "<td>$actVal</td>"; } //Gesamtzeilen - Kommentarzeilen - Leerzeilen echo "<td style=\"color:red;font-weight:bold;\">".($LOC)."</td>"; echo "<td>$percentComments</td>"; if(MCCABE){ echo "<td>"; $cc = $this->CC [$val[0]]; if(isset($cc)){ foreach($cc as $ccFunction=>$ccWert){ if($ccWert>=10){ echo $ccFunction." : <b>".$ccWert."</b><br>"; }else{ //echo $ccFunction." : ".$ccWert."<br>"; } } }else{ echo "null"; } echo "</td>"; } echo "</tr>"; } echo "</table>"; }else $this->throwNotScannedException(); }//END:displayExactOutput(); /** * getCC() get the cyclomatic complexity * * @access: public * * @return Arr $cyclomaticComplexity */ public function getCC(){ return $this->CC; } /** * setFolder() set the folder to scan * * @access: public * @param Str $folder * * @return NONE */ public function setFolder($folder){ //Fehlerbehandlung if($folder == '' || !isset($folder)){ throw new Exception("Keinen Pfad uebergeben!"); }elseif(!is_dir($folder)){ throw new Exception("'$folder' ist kein Verzeichnis!"); }elseif(!is_readable($folder)){ throw new Exception("Ich kann '$folder' nicht lesen, bitte ueberpruefen Sie die Rechte!"); }else{ //alles okay $this->folder = $folder; } }//END:setFolder /** * setFileTypes() set the filetypes to include * * @access: public * @param Str $fileType * * @return NONE */ public function setFileTypes($fileType){ //Fehlerbehandlung if($fileType == '' || !isset($fileType)){ throw new Exception("Nichts uebergeben"); }elseif(preg_match('/,/',$fileType)){ //es ist eine Komma separierte Liste $fileTypeArray = explode(",",$fileType); $this->fileTypes = $fileTypeArray; }else{ $this->fileTypes = array($fileType); } } }//end LineCounter class ?>