Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • Inspector
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alpha\Util\Code\Metric;
  4: 
  5: use File_Find;
  6: 
  7: /**
  8:  * Utility class for calcualting some software metrics related to a project.
  9:  *
 10:  * @since 1.0
 11:  *
 12:  * @author John Collins <dev@alphaframework.org>
 13:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 14:  * @copyright Copyright (c) 2015, John Collins (founder of Alpha Framework).
 15:  * All rights reserved.
 16:  *
 17:  * <pre>
 18:  * Redistribution and use in source and binary forms, with or
 19:  * without modification, are permitted provided that the
 20:  * following conditions are met:
 21:  *
 22:  * * Redistributions of source code must retain the above
 23:  *   copyright notice, this list of conditions and the
 24:  *   following disclaimer.
 25:  * * Redistributions in binary form must reproduce the above
 26:  *   copyright notice, this list of conditions and the
 27:  *   following disclaimer in the documentation and/or other
 28:  *   materials provided with the distribution.
 29:  * * Neither the name of the Alpha Framework nor the names
 30:  *   of its contributors may be used to endorse or promote
 31:  *   products derived from this software without specific
 32:  *   prior written permission.
 33:  *
 34:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 35:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 36:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 37:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 39:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 41:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 42:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 43:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 44:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 45:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 46:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 47:  * </pre>
 48:  */
 49: class Inspector
 50: {
 51:     /**
 52:      * The directory to begin the calculations from.
 53:      *
 54:      * @var string
 55:      *
 56:      * @since 1.0
 57:      */
 58:     private $rootDir;
 59: 
 60:     /**
 61:      * The file extensions of the file types to include in the calculations.
 62:      *
 63:      * @var array
 64:      *
 65:      * @since 1.0
 66:      */
 67:     private $includeFileTypes = array('.php', '.html', '.phtml', '.inc', '.js', '.css', '.xml');
 68: 
 69:     /**
 70:      * Any sub-directories which you might want to exclude from the calculations.
 71:      *
 72:      * @var array
 73:      *
 74:      * @since 1.0
 75:      */
 76:     private $excludeSubDirectories = array('cache', 'lib', 'docs', 'attachments', 'dist', 'vendor');
 77: 
 78:     /**
 79:      * The Total Lines of Code (TLOC) for the project.
 80:      *
 81:      * @var int
 82:      *
 83:      * @since 1.0
 84:      */
 85:     private $TLOC = 0;
 86: 
 87:     /**
 88:      * The Total Lines of Code (TLOC) for the project, less comments defined in $comments.
 89:      *
 90:      * @var int
 91:      *
 92:      * @since 1.0
 93:      */
 94:     private $TLOCLessComments = 0;
 95: 
 96:     /**
 97:      * The count of the source code files in the project.
 98:      *
 99:      * @var int
100:      *
101:      * @since 1.0
102:      */
103:     private $fileCount = 0;
104: 
105:     /**
106:      * An array of fileName => lines of code to be populated by this class.
107:      *
108:      * @var array
109:      *
110:      * @since 1.0
111:      */
112:     private $filesLOCResult = array();
113: 
114:     /**
115:      * An array of fileName => lines of code to be populated by this class,
116:      * excluding comment lines defined in the $comments array.
117:      *
118:      * @var array
119:      *
120:      * @since 1.0
121:      */
122:     private $filesLOCNoCommentsResult = array();
123: 
124:     /**
125:      * An array of the source code file names in the project.
126:      *
127:      * @var array
128:      *
129:      * @since 1.0
130:      */
131:     private $files = array();
132: 
133:     /**
134:      * An array of the directories in the project.
135:      *
136:      * @var array
137:      *
138:      * @since 1.0
139:      */
140:     private $directories = array();
141: 
142:     /**
143:      * An array of the first characters of a comment line in source code.
144:      *
145:      * @var array
146:      *
147:      * @since 1.0
148:      */
149:     private $comments = array('/', '*', '#');
150: 
151:     /**
152:      * Constructor, default $rootDir is .
153:      *
154:      * @param string $rootDir
155:      *
156:      * @since 1.0
157:      */
158:     public function __construct($rootDir = '.')
159:     {
160:         $this->rootDir = $rootDir;
161:         // populate the file and directories arrays using the File_Find class
162:         $finder = new File_Find();
163:         list($this->directories, $this->files) = $finder->maptree($rootDir);
164:     }
165: 
166:     /**
167:      * Calculates the Lines of Code (LOC).
168:      *
169:      * @since 1.0
170:      */
171:     public function calculateLOC()
172:     {
173:         foreach ($this->files as $file) {
174:             $file_type = mb_substr($file, mb_strrpos($file, '.'));
175:             if (in_array($file_type, $this->includeFileTypes)) {
176:                 $exclude = false;
177:                 foreach ($this->excludeSubDirectories as $dir) {
178:                     if (preg_match('/'.$dir.'/i', $file)) {
179:                         $exclude = true;
180:                     }
181:                 }
182: 
183:                 if (!$exclude) {
184:                     $current_file = file($file);
185: 
186:                     $LOC = count($current_file);
187:                     $this->filesLOCResult[$file] = $LOC;
188:                     $LOC_less_comments = $this->disregardCommentsLOC($file);
189:                     $this->filesLOCNoCommentsResult[$file] = $LOC_less_comments;
190: 
191:                     $this->TLOC += $LOC;
192:                     $this->TLOCLessComments += $LOC_less_comments;
193:                     ++$this->fileCount;
194:                 }
195:             }
196:         }
197:     }
198: 
199:     /**
200:      * Generates a HTML table containing the metrics results.
201:      *
202:      * @return string
203:      *
204:      * @since 1.0
205:      */
206:     public function resultsToHTML()
207:     {
208:         $count = 1;
209: 
210:         $html = '<table class="table table-striped table-hover"><tr>';
211:         $html .= '<th style="width:10%;">File #:</th>';
212:         $html .= '<th style="width:50%;">File name:</th>';
213:         $html .= '<th style="width:20%;">Lines of Code (LOC):</th>';
214:         $html .= '<th style="width:20%;">Lines of Code (less comments):</th>';
215:         $html .= '</tr>';
216:         foreach (array_keys($this->filesLOCResult) as $result) {
217:             $html .= "<tr><td>$count</td><td>$result</td><td>".$this->filesLOCResult[$result].'</td><td>'.$this->filesLOCNoCommentsResult[$result].'</td></tr>';
218:             ++$count;
219:         }
220:         $html .= '</table>';
221: 
222:         $html .= '<p>Total files: '.number_format(count($this->files)).'</p>';
223:         $html .= '<p>Total source code files: '.number_format($this->fileCount).'</p>';
224:         $html .= '<p>Total Lines of Code (TLOC): '.number_format($this->TLOC).'</p>';
225:         $html .= '<p>Total Lines of Code (TLOC), less comments: '.number_format($this->TLOCLessComments).'</p>';
226: 
227:         return $html;
228:     }
229: 
230:     /**
231:      * Filters comments from LOC metric.
232:      *
233:      * @param string $sourceFile
234:      *
235:      * @return int
236:      *
237:      * @since 1.0
238:      */
239:     private function disregardCommentsLOC($sourceFile)
240:     {
241:         $file = file($sourceFile);
242: 
243:         $LOC = 0;
244: 
245:         foreach ($file as $line) {
246:             $exclude = false;
247:             $line = ltrim($line);
248: 
249:             if (empty($line)) {
250:                 $exclude = true;
251:             } else {
252:                 foreach ($this->comments as $comment) {
253:                     if (mb_substr($line, 0, 1) == $comment) {
254:                         $exclude = true;
255:                     }
256:                 }
257:             }
258: 
259:             if (!$exclude) {
260:                 ++$LOC;
261:             }
262:         }
263: 
264:         return $LOC;
265:     }
266: }
267: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0