This commit is contained in:
Paminger
2016-03-20 12:53:17 +01:00
parent 0c3c47f848
commit 9689fd5a01
137 changed files with 8480 additions and 405 deletions
@@ -0,0 +1,98 @@
<?php
/**
* PSR1_Sniffs_Methods_CamelCapsMethodNameSniff.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
if (class_exists('Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff', true) === false) {
throw new PHP_CodeSniffer_Exception('Class Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff not found');
}
/**
* PSR1_Sniffs_Methods_CamelCapsMethodNameSniff.
*
* Ensures method names are defined using camel case.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class FHComplete_Sniffs_NamingConventions_CamelCapsMethodNameSniff extends Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff
{
/**
* Processes the tokens within the scope.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
* @param int $stackPtr The position where this token was
* found.
* @param int $currScope The position of the current scope.
*
* @return void
*/
protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
{
$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName === null
|| substr($methodName,-4) === '_get'
|| substr($methodName,-5) === '_post'
|| substr($methodName,-4) === '_put'
|| substr($methodName,-6) === '_patch'
|| substr($methodName,-7) === '_delete'
)
// Ignore closures.
return;
// Ignore magic methods.
if (preg_match('|^__|', $methodName) !== 0) {
$magicPart = strtolower(substr($methodName, 2));
if (isset($this->magicMethods[$magicPart]) === true
|| isset($this->methodsDoubleUnderscore[$magicPart]) === true
) {
return;
}
}
$testName = ltrim($methodName, '_');
if ($testName !== '' && PHP_CodeSniffer::isCamelCaps($testName, false, true, false) === false) {
$error = 'Method name "%s" is not in camel caps format';
$className = $phpcsFile->getDeclarationName($currScope);
$errorData = array($className.'::'.$methodName);
$phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
$phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no');
} else {
$phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
}
}//end processTokenWithinScope()
/**
* Processes the tokens outside the scope.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
* @param int $stackPtr The position where this token was
* found.
*
* @return void
*/
protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
}//end processTokenOutsideScope()
}//end class
@@ -0,0 +1,223 @@
<?php
/**
* FHComplete_Sniffs_NamingConventions_UpperCaseConstantNameSniff.
*
* PHP version 5
*
* Ensures that constant names are all uppercase.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: 1.5.0RC3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class FHComplete_Sniffs_NamingConventions_UpperCaseConstantNameSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_STRING);
}
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the current token in the
* stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$constName = $tokens[$stackPtr]['content'];
// If this token is in a heredoc, ignore it.
if ($phpcsFile->hasCondition($stackPtr, T_START_HEREDOC) === true) {
return;
}
// Special case for PHPUnit.
if ($constName === 'PHPUnit_MAIN_METHOD') {
return;
}
// If the next non-whitespace token after this token
// is not an opening parenthesis then it is not a function call.
$openBracket = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
$functionKeyword = $phpcsFile->findPrevious(
array(
T_WHITESPACE,
T_COMMA,
T_COMMENT,
T_STRING,
T_NS_SEPARATOR,
),
($stackPtr - 1),
null,
true
);
$declarations = array(
T_FUNCTION,
T_CLASS,
T_INTERFACE,
T_TRAIT,
T_IMPLEMENTS,
T_EXTENDS,
T_INSTANCEOF,
T_NEW,
T_NAMESPACE,
T_USE,
T_AS,
T_GOTO,
T_INSTEADOF,
T_PROTECTED,
T_PRIVATE,
T_PUBLIC
);
if (in_array($tokens[$functionKeyword]['code'], $declarations) === true) {
// This is just a declaration; no constants here.
return;
}
if ($tokens[$functionKeyword]['code'] === T_CONST) {
// This is a class constant.
if (strtoupper($constName) !== $constName) {
$error = 'Class constants must be uppercase; expected %s but found %s';
$data = array(
strtoupper($constName),
$constName,
);
$phpcsFile->addError($error, $stackPtr, 'ClassConstantNotUpperCase', $data);
}
return;
}
// Is this a class name?
$nextPtr = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$nextPtr]['code'] === T_DOUBLE_COLON) {
return;
}
// Is this a namespace name?
if ($tokens[$nextPtr]['code'] === T_NS_SEPARATOR) {
return;
}
// Is this an insteadof name?
if ($tokens[$nextPtr]['code'] === T_INSTEADOF) {
return;
}
// Is this an as name?
if ($tokens[$nextPtr]['code'] === T_AS) {
return;
}
// Is this a type hint?
if ($tokens[$nextPtr]['code'] === T_VARIABLE
|| $phpcsFile->isReference($nextPtr) === true
) {
return;
}
// Is this a member var name?
$prevPtr = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
if ($tokens[$prevPtr]['code'] === T_OBJECT_OPERATOR) {
return;
}
// Is this a variable name, in the form ${varname} ?
if ($tokens[$prevPtr]['code'] === T_OPEN_CURLY_BRACKET) {
$nextPtr = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$nextPtr]['code'] === T_CLOSE_CURLY_BRACKET) {
return;
}
}
// Is this a namespace name?
if ($tokens[$prevPtr]['code'] === T_NS_SEPARATOR) {
return;
}
// Is this an instance of declare()
$prevPtrDeclare = $phpcsFile->findPrevious(
array(T_WHITESPACE, T_OPEN_PARENTHESIS),
($stackPtr - 1),
null,
true
);
if ($tokens[$prevPtrDeclare]['code'] === T_DECLARE) {
return;
}
// Is this a goto label target?
if ($tokens[$nextPtr]['code'] === T_COLON) {
if (in_array($tokens[$prevPtr]['code'], array(T_SEMICOLON, T_OPEN_CURLY_BRACKET, T_COLON), true)) {
return;
}
}
// This is a real constant.
if (strtoupper($constName) !== $constName) {
$error = 'Constants must be uppercase; expected %s but found %s';
$data = array(
strtoupper($constName),
$constName,
);
$phpcsFile->addError($error, $stackPtr, 'ConstantNotUpperCase', $data);
}
} elseif (strtolower($constName) === 'define' || strtolower($constName) === 'constant') {
/*
This may be a "define" or "constant" function call.
*/
// Make sure this is not a method call.
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR
|| $tokens[$prev]['code'] === T_DOUBLE_COLON
) {
return;
}
// The next non-whitespace token must be the constant name.
$constPtr = $phpcsFile->findNext(T_WHITESPACE, ($openBracket + 1), null, true);
if ($tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
return;
}
$constName = $tokens[$constPtr]['content'];
// Check for constants like self::CONSTANT.
$prefix = '';
$splitPos = strpos($constName, '::');
if ($splitPos !== false) {
$prefix = substr($constName, 0, ($splitPos + 2));
$constName = substr($constName, ($splitPos + 2));
}
if (strtoupper($constName) !== $constName) {
$error = 'Constants must be uppercase; expected %s but found %s';
$data = array(
$prefix . strtoupper($constName),
$prefix . $constName,
);
$phpcsFile->addError($error, $stackPtr, 'ConstantNotUpperCase', $data);
}
}
}
}
@@ -0,0 +1,47 @@
<?php
/**
* PHP Version 5
*
* FHComplete
*/
/**
* Ensures curly brackets are on the same line as the Class declaration
*
*/
class FHComplete_Sniffs_NamingConventions_ValidClassBracketsSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_CLASS);
}
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the current token in the stack passed in $tokens.
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$found = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr);
if ($tokens[$found - 1]['code'] != T_WHITESPACE) {
$error = 'Expected 1 space after class declaration, found 0';
$phpcsFile->addError($error, $found - 1, 'InvalidSpacing', array());
return;
}
if (strlen($tokens[$found - 1]['content']) > 1 || $tokens[$found - 2]['code'] == T_WHITESPACE) {
$error = 'Expected 1 space after class declaration, found ' . strlen($tokens[$found - 1]['content']);
$phpcsFile->addError($error, $found - 1, 'InvalidSpacing', array());
}
}
}
@@ -0,0 +1,138 @@
<?php
/**
* PHP Version 5
*
* FHComplete
*/
/**
* Ensures method names are correct depending on whether they are public
* or private, and that functions are named correctly.
*
*/
class FHComplete_Sniffs_NamingConventions_ValidFunctionNameSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff {
/**
* A list of all PHP magic methods.
*
* @var array
*/
protected $_magicMethods = array(
'construct',
'destruct',
'call',
'callStatic',
'debugInfo',
'get',
'set',
'isset',
'unset',
'sleep',
'wakeup',
'toString',
'set_state',
'clone',
'invoke',
);
/**
* Constructs a PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff.
*/
public function __construct() {
parent::__construct(array(T_CLASS, T_INTERFACE), array(T_FUNCTION), true);
}
/**
* Processes the tokens within the scope.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
* @param integer $stackPtr The position where this token was found.
* @param integer $currScope The position of the current scope.
* @return void
*/
protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) {
$methodName = $phpcsFile->getDeclarationName($stackPtr);
if ($methodName === null) {
// Ignore closures.
return;
}
$className = $phpcsFile->getDeclarationName($currScope);
$errorData = array($className . '::' . $methodName);
// PHP4 constructors are allowed to break our rules.
if ($methodName === $className) {
return;
}
// PHP4 destructors are allowed to break our rules.
if ($methodName === '_' . $className) {
return;
}
// Ignore magic methods
if (preg_match('/^__(' . implode('|', $this->_magicMethods) . ')$/', $methodName)) {
return;
}
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
if ($methodProps['scope_specified'] === false) {
// Let another sniffer take care of that
return;
}
$isPublic = $methodProps['scope'] === 'public';
$isProtected = $methodProps['scope'] === 'protected';
$isPrivate = $methodProps['scope'] === 'private';
$scope = $methodProps['scope'];
if ($isPublic === true) {
if ($methodName[0] === '_') {
$error = 'Public method name "%s" must not be prefixed with underscore';
$phpcsFile->addError($error, $stackPtr, 'PublicWithUnderscore', $errorData);
return;
}
// Underscored public methods in controller are allowed to break our rules.
if (substr($className, -10) === 'Controller') {
return;
}
// Underscored public methods in shells are allowed to break our rules.
if (substr($className, -5) === 'Shell') {
return;
}
// Underscored public methods in tasks are allowed to break our rules.
if (substr($className, -4) === 'Task') {
return;
}
} elseif ($isPrivate === true) {
if (substr($methodName, 0, 2) !== '__') {
$error = 'Private method name "%s" must be prefixed with 2 underscores';
$phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData);
return;
} else {
$filename = $phpcsFile->getFilename();
if (strpos($filename, '/lib/Cake/') === true) {
$warning = 'Private method name "%s" in FHComplete core is discouraged';
$phpcsFile->addWarning($warning, $stackPtr, 'PrivateMethodInCore', $errorData);
}
}
} else {
if ($methodName[0] !== '_' || substr($methodName, 0, 2) === '__') {
$error = 'Protected method name "%s" must be prefixed with one underscore';
$phpcsFile->addError($error, $stackPtr, 'ProtectedNoUnderscore', $errorData);
return;
}
}
}
/**
* Processes the tokens outside the scope.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being processed.
* @param integer $stackPtr The position where this token was found.
* @return void
*/
protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
}
}
@@ -0,0 +1,48 @@
<?php
/**
* PHP Version 5
*
* FHComplete
*/
/**
* Ensures trait names are correct depending on the folder of the file.
*
*/
class FHComplete_Sniffs_NamingConventions_ValidTraitNameSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* If the constant is not defined, ignore because probably the PHP version
* is under 5.4.0 and don't have traits in use
*
* @return array
*/
public function register()
{
if (!defined('T_TRAIT')) {
return array();
}
return array(T_TRAIT);
}
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the current token in the stack passed in $tokens.
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$traitName = $tokens[$stackPtr + 2]['content'];
if (substr($traitName, -5) !== 'Trait') {
$error = 'Traits must have a "Trait" suffix.';
$phpcsFile->addError($error, $stackPtr, 'InvalidTraitName', array());
}
}
}
@@ -0,0 +1,171 @@
<?php
/**
* PHP Version 5
*
* FHComplete
*/
if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) {
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found');
}
/**
* Checks the naming of variables and member variables.
*
*/
class FHComplete_Sniffs_NamingConventions_ValidVariableNameSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff {
/**
* Processes this test, when one of its tokens is encountered.
*
* Processes variables, we skip processing object properties because
* they could come from things like PDO which doesn't follow the normal
* conventions and causes additional failures.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the current token in the
* stack passed in $tokens.
* @return void
*/
protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
$tokens = $phpcsFile->getTokens();
$varName = ltrim($tokens[$stackPtr]['content'], '$');
$phpReservedVars = array(
'_SERVER',
'_GET',
'_POST',
'_REQUEST',
'_SESSION',
'_ENV',
'_COOKIE',
'_FILES',
'GLOBALS',
);
// If it's a php reserved var, then its ok.
if (in_array($varName, $phpReservedVars) === true) {
return;
}
// There is no way for us to know if the var is public or private,
// so we have to ignore a leading underscore if there is one and just
// check the main part of the variable name.
$originalVarName = $varName;
if (substr($varName, 0, 1) === '_') {
$objOperator = $phpcsFile->findPrevious(array(T_WHITESPACE), ($stackPtr - 1), null, true);
if ($tokens[$objOperator]['code'] === T_DOUBLE_COLON) {
// The variable lives within a class, and is referenced like
// this: MyClass::$_variable, so we don't know its scope.
$inClass = true;
} else {
$inClass = $phpcsFile->hasCondition($stackPtr, array(T_TRAIT, T_CLASS, T_INTERFACE));
}
if ($inClass === true) {
$varName = ltrim($varName, '_');
}
}
// $title_for_layout is allowed on controllers
$fileName = basename($phpcsFile->getFilename(), '.php');
if ((substr($fileName, -10) === 'Controller') && ($varName == 'title_for_layout')) {
return;
}
if ($this->_isValidVar($varName) === false) {
$error = 'Variable "%s" is not in valid camel caps format';
$data = array($originalVarName);
$phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data);
}
}
/**
* Processes class member variables.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the current token in the
* stack passed in $tokens.
* @return void
*/
protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
}
/**
* Processes the variable found within a double quoted string.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param integer $stackPtr The position of the double quoted string.
* @return void
*/
protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr) {
$tokens = $phpcsFile->getTokens();
$phpReservedVars = array(
'_SERVER',
'_GET',
'_POST',
'_REQUEST',
'_SESSION',
'_ENV',
'_COOKIE',
'_FILES',
'GLOBALS',
);
if (preg_match_all('|[^\\\]\$([a-zA-Z0-9_]+)|', $tokens[$stackPtr]['content'], $matches) !== 0) {
foreach ($matches[1] as $varName) {
// If it's a php reserved var, then its ok.
if (in_array($varName, $phpReservedVars) === true) {
continue;
}
// There is no way for us to know if the var is public or private,
// so we have to ignore a leading underscore if there is one and just
// check the main part of the variable name.
$originalVarName = $varName;
if (substr($varName, 0, 1) === '_') {
if ($phpcsFile->hasCondition($stackPtr, array(T_CLASS, T_INTERFACE)) === true) {
$varName = substr($varName, 1);
}
}
if ($this->_isValidVar($varName) === false) {
$error = 'Variable "%s" is not in valid camel caps format';
$data = array($originalVarName);
$phpcsFile->addError($error, $stackPtr, 'StringVarNotCamelCaps', $data);
}
}
}
}
/**
* Check that a variable is a valid shape.
*
* Variables in FHComplete can either be $fooBar, $FooBar, $_fooBar, or $_FooBar.
*
* @param string $string The variable to check.
* @param boolea $public Whether or not the variable is public.
* @return boolean
*/
protected function _isValidVar($string, $public = true) {
$firstChar = '[a-zA-Z]';
if (!$public) {
$firstChar = '[_]{1,2}' . $firstChar;
}
if (preg_match("|^$firstChar|", $string) === 0) {
return false;
}
$firstStringCount = 1;
if (preg_match("|^__|", $string)) {
$firstStringCount = 2;
}
// Check that the name only contains legal characters.
$legalChars = 'a-zA-Z0-9';
if (preg_match("|[^$legalChars]|", substr($string, $firstStringCount)) > 0) {
return false;
}
return true;
}
}