LineCounter.class.php
Aus Programmers Guide
(Unterschied zwischen Versionen)
Roy (Diskussion | Beiträge) |
Roy (Diskussion | Beiträge) |
||
(Der Versionsvergleich bezieht 1 dazwischenliegende Version mit ein.) | |||
Zeile 35: | Zeile 35: | ||
* METHODS: | * METHODS: | ||
* __construct([string $folder, string $fileTypes]) | * __construct([string $folder, string $fileTypes]) | ||
+ | * | ||
* public void setFolder(string $folder) | * public void setFolder(string $folder) | ||
* public void setFileTypes(string $fileTypes) | * public void setFileTypes(string $fileTypes) | ||
- | * | + | * public void setMcCabe(boolean $mcCabe) |
* public void scanDirectory(void) | * public void scanDirectory(void) | ||
* | * | ||
Zeile 103: | Zeile 104: | ||
$this->folder = $folder; //Der Pfad | $this->folder = $folder; //Der Pfad | ||
$this->isScanned = false; //fuer die Fehlerbehandlung scan-Indikator | $this->isScanned = false; //fuer die Fehlerbehandlung scan-Indikator | ||
- | + | $this->CC = array(); //Array fuer McCabes cyclomatic complexity | |
- | + | ||
+ | if(MCCABE){ | ||
+ | $this->mcCabe = true; | ||
+ | }else{ | ||
+ | $this->mcCabe = false; | ||
+ | } | ||
} | } | ||
Zeile 129: | Zeile 135: | ||
$this->size += $file->getSize(); | $this->size += $file->getSize(); | ||
$this->countLines(basename($fileName), $file); | $this->countLines(basename($fileName), $file); | ||
- | if( | + | if($this->mcCabe) |
$this->determineCC($fileName); | $this->determineCC($fileName); | ||
$this->files++; | $this->files++; | ||
Zeile 326: | Zeile 332: | ||
echo "<table border=\"1\">"; | 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>"; | echo "<tr><th>Dateiname</th><th>Kommentare</th><th>Leerzeilen</th><th>Gesamtzeilen</th><th>Lines of Code (LOC)</th><th>% Kommentare</th>"; | ||
- | if( | + | if($this->mcCabe) |
echo "<th>McCabes cc >10</th>"; | echo "<th>McCabes cc >10</th>"; | ||
echo "</tr>"; | echo "</tr>"; | ||
foreach($this->getExactOutput() as $val){ | foreach($this->getExactOutput() as $val){ | ||
+ | //Gesamtzeilen - Kommentarzeilen - Leerzeilen | ||
$LOC = $val[3] - $val[2] - $val[1]; | $LOC = $val[3] - $val[2] - $val[1]; | ||
if($val[3]!=0){//wir duefen ja nicht durch 0 dividieren | if($val[3]!=0){//wir duefen ja nicht durch 0 dividieren | ||
Zeile 344: | Zeile 351: | ||
echo "<td>$actVal</td>"; | echo "<td>$actVal</td>"; | ||
} | } | ||
- | |||
echo "<td style=\"color:red;font-weight:bold;\">".($LOC)."</td>"; | echo "<td style=\"color:red;font-weight:bold;\">".($LOC)."</td>"; | ||
echo "<td>$percentComments</td>"; | echo "<td>$percentComments</td>"; | ||
- | if( | + | if($this->mcCabe){ |
echo "<td>"; | echo "<td>"; | ||
$cc = $this->CC [$val[0]]; | $cc = $this->CC [$val[0]]; | ||
Zeile 410: | Zeile 416: | ||
* | * | ||
* @access: public | * @access: public | ||
+ | * @throws Exception | ||
* @param Str $fileType | * @param Str $fileType | ||
* | * | ||
Zeile 426: | Zeile 433: | ||
} | } | ||
} | } | ||
+ | |||
+ | /** | ||
+ | * setMcCabe() to turn McCabe off - this saves time | ||
+ | * | ||
+ | * @access: public | ||
+ | * @throws Exception | ||
+ | * @param bool $mcCabe | ||
+ | * | ||
+ | * @return NONE | ||
+ | */ | ||
+ | public function setMcCabe($mcCabe){ | ||
+ | if(!MCCABE){ | ||
+ | throw new Exception("Bitte MCCABE in der Datei LineCounter.class.php auf true setzen!"); | ||
+ | } | ||
+ | if(is_bool($mcCabe)){ | ||
+ | $this->mcCabe=$mcCabe; | ||
+ | }else{ | ||
+ | throw new Exception("Bitte nur boolsche Werte uebergeben"); | ||
+ | } | ||
+ | } | ||
+ | |||
}//end LineCounter class | }//end LineCounter class | ||
?> | ?> | ||
- | </source> | + | </source> |
+ | |||
+ | [[Category:Klassen]][[Category:PHP]][[Category:Snippet]] |
Aktuelle Version vom 06:18, 19. 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 setMcCabe(boolean $mcCabe) * 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 $this->CC = array(); //Array fuer McCabes cyclomatic complexity if(MCCABE){ $this->mcCabe = true; }else{ $this->mcCabe = false; } } /** * 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($this->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($this->mcCabe) echo "<th>McCabes cc >10</th>"; echo "</tr>"; foreach($this->getExactOutput() as $val){ //Gesamtzeilen - Kommentarzeilen - Leerzeilen $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>"; } echo "<td style=\"color:red;font-weight:bold;\">".($LOC)."</td>"; echo "<td>$percentComments</td>"; if($this->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 * @throws Exception * @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); } } /** * setMcCabe() to turn McCabe off - this saves time * * @access: public * @throws Exception * @param bool $mcCabe * * @return NONE */ public function setMcCabe($mcCabe){ if(!MCCABE){ throw new Exception("Bitte MCCABE in der Datei LineCounter.class.php auf true setzen!"); } if(is_bool($mcCabe)){ $this->mcCabe=$mcCabe; }else{ throw new Exception("Bitte nur boolsche Werte uebergeben"); } } }//end LineCounter class ?>