1<?php 2/** 3 * Class Declaration Test. 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_CodeSniffer 9 * @author Greg Sherwood <gsherwood@squiz.net> 10 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 11 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 12 * @link http://pear.php.net/package/PHP_CodeSniffer 13 */ 14 15/** 16 * Class Declaration Test. 17 * 18 * Checks the declaration of the class is correct. 19 * 20 * @category PHP 21 * @package PHP_CodeSniffer 22 * @author Greg Sherwood <gsherwood@squiz.net> 23 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 24 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 25 * @version Release: @package_version@ 26 * @link http://pear.php.net/package/PHP_CodeSniffer 27 */ 28class PSR1_Sniffs_Classes_ClassDeclarationSniff implements PHP_CodeSniffer_Sniff 29{ 30 /** 31 * The current PHP version. 32 * 33 * @var integer 34 */ 35 private $_phpVersion = null; 36 37 38 /** 39 * Returns an array of tokens this test wants to listen for. 40 * 41 * @return array 42 */ 43 public function register() 44 { 45 return array( 46 T_CLASS, 47 T_INTERFACE, 48 T_TRAIT, 49 ); 50 51 }//end register() 52 53 54 /** 55 * Processes this test, when one of its tokens is encountered. 56 * 57 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 58 * @param integer $stackPtr The position of the current token in 59 * the token stack. 60 * 61 * @return void 62 */ 63 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 64 { 65 if ($this->_phpVersion === null) { 66 $this->_phpVersion = PHP_CodeSniffer::getConfigData('php_version'); 67 if ($this->_phpVersion === null) { 68 $this->_phpVersion = PHP_VERSION_ID; 69 } 70 } 71 72 $tokens = $phpcsFile->getTokens(); 73 if (isset($tokens[$stackPtr]['scope_closer']) === false) { 74 return; 75 } 76 77 $errorData = array(strtolower($tokens[$stackPtr]['content'])); 78 79 $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), ($tokens[$stackPtr]['scope_closer'] + 1)); 80 if ($nextClass !== false) { 81 $error = 'Each %s must be in a file by itself'; 82 $phpcsFile->addError($error, $nextClass, 'MultipleClasses', $errorData); 83 $phpcsFile->recordMetric($stackPtr, 'One class per file', 'no'); 84 } else { 85 $phpcsFile->recordMetric($stackPtr, 'One class per file', 'yes'); 86 } 87 88 if ($this->_phpVersion >= 50300) { 89 $namespace = $phpcsFile->findNext(array(T_NAMESPACE, T_CLASS, T_INTERFACE, T_TRAIT), 0); 90 if ($tokens[$namespace]['code'] !== T_NAMESPACE) { 91 $error = 'Each %s must be in a namespace of at least one level (a top-level vendor name)'; 92 $phpcsFile->addError($error, $stackPtr, 'MissingNamespace', $errorData); 93 $phpcsFile->recordMetric($stackPtr, 'Class defined in namespace', 'no'); 94 } else { 95 $phpcsFile->recordMetric($stackPtr, 'Class defined in namespace', 'yes'); 96 } 97 } 98 99 }//end process() 100 101 102}//end class 103