* @copyright 2011 Thomas Ernest * @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License * @link http://pear.php.net/package/PHP_CodeSniffer */ namespace CodeIgniter\Sniffs\NamingConventions; use PHP_CodeSniffer\Sniffs\AbstractScopeSniff; use PHP_CodeSniffer\Files\File; /** * CodeIgniter_Sniffs_NamingConventions_ConstructorNameSniff. * * Favor PHP 4 constructor syntax, which uses "function ClassName()". * Avoid PHP 5 constructor syntax, which uses "function __construct()". * * @todo Try to avoid overly long and verbose names. * * @category PHP * @package PHP_CodeSniffer * @author Thomas Ernest * @copyright 2010 Thomas Ernest * @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License * @link http://pear.php.net/package/PHP_CodeSniffer */ class ConstructorNameSniff extends AbstractScopeSniff { public $php5Constructors = '1'; /** * Constructs the test with the tokens it wishes to listen for. * * @return void */ public function __construct() { parent::__construct(array(T_CLASS, T_INTERFACE), array(T_FUNCTION), true); }//end __construct() /** * Processes this test when one of its tokens is encountered. * * @param File $phpcsFile The current file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * @param int $currScope A pointer to the start of the scope. * * @return void */ protected function processTokenWithinScope( File $phpcsFile, $stackPtr, $currScope ) { $methodName = $phpcsFile->getDeclarationName($stackPtr); $className = $phpcsFile->getDeclarationName($currScope); $isPhp4Constructor = strcasecmp($methodName, $className) === 0; $isPhp5Constructor = strcasecmp($methodName, '__construct') === 0; if ($this->php5Constructors != '0') { if ($isPhp4Constructor) { $error = "PHP4 style constructors are not allowed; use \"__construct\" instead"; $phpcsFile->addError($error, $stackPtr); } } else { if ($isPhp5Constructor) { $error = "PHP5 style constructors are not allowed; use \"$className\" instead"; $phpcsFile->addError($error, $stackPtr); } } if ( ! $isPhp4Constructor && ! $isPhp5Constructor ) { return; } $tokens = $phpcsFile->getTokens(); $parentClassName = $phpcsFile->findExtendedClassName($currScope); $wrongConstructor = ''; // prepares the error message and wrong constructor if ($this->php5Constructors != '0') { $error = 'PHP4 style calls to parent constructors are not allowed.'; $error = "$error Please use \"parent::__construct\" instead."; if (false !== $parentClassName) { $wrongConstructor = $parentClassName; } // Else $wrongConstructor will be empty // and the test expression will always be false. // It doesn't check that no parent method should be called // when no parent class is defined. } else { $error = 'PHP5 style calls to parent constructors are not allowed.'; if (false !== $parentClassName) { $error = "$error Please use \"parent::$parentClassName\" instead."; } $wrongConstructor = '__construct'; } // looks for the use of a wrong constructor. $endFunctionIndex = $tokens[$stackPtr]['scope_closer']; $doubleColonIndex = $phpcsFile->findNext( array(T_DOUBLE_COLON), $stackPtr, $endFunctionIndex ); while ($doubleColonIndex) { if ($tokens[($doubleColonIndex + 1)]['code'] === T_STRING && $tokens[($doubleColonIndex + 1)]['content'] === $wrongConstructor ) { $phpcsFile->addError($error, ($doubleColonIndex + 1)); } $doubleColonIndex = $phpcsFile->findNext( array(T_DOUBLE_COLON), $doubleColonIndex + 1, $endFunctionIndex ); } }//end processTokenWithinScope() protected function processTokenOutsideScope(File $phpcsFile, $stackPtr) { // TODO: Implement processTokenOutsideScope() method. } }//end class ?>