Initial Commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* MySource_Sniffs_CSS_BrowserSpecificStylesSniff.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* MySource_Sniffs_CSS_BrowserSpecificStylesSniff.
|
||||
*
|
||||
* Ensure that browser-specific styles are not used.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_CSS_BrowserSpecificStylesSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedTokenizers = array('CSS');
|
||||
|
||||
/**
|
||||
* A list of specific stylsheet suffixes we allow.
|
||||
*
|
||||
* These stylsheets contain browser specific styles
|
||||
* so this sniff ignore them files in the form:
|
||||
* *_moz.css and *_ie7.css etc.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $specificStylesheets = array(
|
||||
'moz',
|
||||
'ie',
|
||||
'ie7',
|
||||
'ie8',
|
||||
'webkit',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the token types that this sniff is interested in.
|
||||
*
|
||||
* @return array(int)
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_STYLE);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes the tokens that this sniff is interested in.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
|
||||
* @param int $stackPtr The position in the stack where
|
||||
* the token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
// Ignore files with browser-specific suffixes.
|
||||
$filename = $phpcsFile->getFilename();
|
||||
$breakChar = strrpos($filename, '_');
|
||||
if ($breakChar !== false && substr($filename, -4) === '.css') {
|
||||
$specific = substr($filename, ($breakChar + 1), -4);
|
||||
if (in_array($specific, $this->specificStylesheets) === true) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
$content = $tokens[$stackPtr]['content'];
|
||||
|
||||
if ($content{0} === '-') {
|
||||
$error = 'Browser-specific styles are not allowed';
|
||||
$phpcsFile->addError($error, $stackPtr, 'ForbiddenStyle');
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that all action classes throw ChannelExceptions only.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that all action classes throw ChannelExceptions only.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Channels_ChannelExceptionSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_THROW);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $stackPtr The position of the current token in
|
||||
* the stack passed in $tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
$fileName = strtolower($phpcsFile->getFilename());
|
||||
$matches = array();
|
||||
if (preg_match('|/systems/(.*)/([^/]+)?actions.inc$|', $fileName, $matches) === 0) {
|
||||
// This is not an actions.inc file.
|
||||
return;
|
||||
}
|
||||
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
$exception = $phpcsFile->findNext(array(T_STRING, T_VARIABLE), ($stackPtr + 1));
|
||||
$exceptionName = $tokens[$exception]['content'];
|
||||
|
||||
if ($exceptionName !== 'ChannelException') {
|
||||
$data = array($exceptionName);
|
||||
$error = 'Channel actions can only throw ChannelException; found "%s"';
|
||||
$phpcsFile->addError($error, $exception, 'WrongExceptionType', $data);
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that self is not used to call public method in action classes.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that self is not used to call public method in action classes.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Channels_DisallowSelfActionsSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_CLASS);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
// We are not interested in abstract classes.
|
||||
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
|
||||
if ($prev !== false && $tokens[$prev]['code'] === T_ABSTRACT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We are only interested in Action classes.
|
||||
$classNameToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
|
||||
$className = $tokens[$classNameToken]['content'];
|
||||
if (substr($className, -7) !== 'Actions') {
|
||||
return;
|
||||
}
|
||||
|
||||
$foundFunctions = array();
|
||||
$foundCalls = array();
|
||||
|
||||
// Find all static method calls in the form self::method() in the class.
|
||||
$classEnd = $tokens[$stackPtr]['scope_closer'];
|
||||
for ($i = ($classNameToken + 1); $i < $classEnd; $i++) {
|
||||
if ($tokens[$i]['code'] !== T_DOUBLE_COLON) {
|
||||
if ($tokens[$i]['code'] === T_FUNCTION) {
|
||||
// Cache the function information.
|
||||
$funcName = $phpcsFile->findNext(T_STRING, ($i + 1));
|
||||
$funcScope = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, ($i - 1));
|
||||
|
||||
$foundFunctions[$tokens[$funcName]['content']] = strtolower($tokens[$funcScope]['content']);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($i - 1), null, true);
|
||||
if ($tokens[$prevToken]['content'] !== 'self') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$funcNameToken = $phpcsFile->findNext(T_WHITESPACE, ($i + 1), null, true);
|
||||
if ($tokens[$funcNameToken]['code'] === T_VARIABLE) {
|
||||
// We are only interested in function calls.
|
||||
continue;
|
||||
}
|
||||
|
||||
$funcName = $tokens[$funcNameToken]['content'];
|
||||
|
||||
// We've found the function, now we need to find it and see if it is
|
||||
// public, private or protected. If it starts with an underscore we
|
||||
// can assume it is private.
|
||||
if ($funcName{0} === '_') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$foundCalls[$i] = $funcName;
|
||||
}//end for
|
||||
|
||||
$errorClassName = substr($className, 0, -7);
|
||||
|
||||
foreach ($foundCalls as $token => $funcName) {
|
||||
if (isset($foundFunctions[$funcName]) === false) {
|
||||
// Function was not in this class, might have come from the parent.
|
||||
// Either way, we can't really check this.
|
||||
continue;
|
||||
} else if ($foundFunctions[$funcName] === 'public') {
|
||||
$error = 'Static calls to public methods in Action classes must not use the self keyword; use %s::%s() instead';
|
||||
$data = array(
|
||||
$errorClassName,
|
||||
$funcName,
|
||||
);
|
||||
$phpcsFile->addError($error, $token, 'Found', $data);
|
||||
}
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,329 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that systems, asset types and libs are included before they are used.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
|
||||
$error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that systems, asset types and libs are included before they are used.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Channels_IncludeSystemSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of classes that don't need to be included.
|
||||
*
|
||||
* @var array(string)
|
||||
*/
|
||||
private $_ignore = array(
|
||||
'self',
|
||||
'parent',
|
||||
'channels',
|
||||
'basesystem',
|
||||
'dal',
|
||||
'init',
|
||||
'pdo',
|
||||
'util',
|
||||
'ziparchive',
|
||||
'phpunit_framework_assert',
|
||||
'abstractmysourceunittest',
|
||||
'abstractdatacleanunittest',
|
||||
'exception',
|
||||
'abstractwidgetwidgettype',
|
||||
'domdocument',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a Squiz_Sniffs_Scope_MethodScopeSniff.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(array(T_FUNCTION), array(T_DOUBLE_COLON, T_EXTENDS), true);
|
||||
|
||||
}//end __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Processes the function tokens within the class.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
|
||||
* @param integer $stackPtr The position where the token was found.
|
||||
* @param integer $currScope The current scope opener token.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processTokenWithinScope(
|
||||
PHP_CodeSniffer_File $phpcsFile,
|
||||
$stackPtr,
|
||||
$currScope
|
||||
) {
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
// Determine the name of the class that the static function
|
||||
// is being called on.
|
||||
$classNameToken = $phpcsFile->findPrevious(
|
||||
T_WHITESPACE,
|
||||
($stackPtr - 1),
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
$className = $tokens[$classNameToken]['content'];
|
||||
if (in_array(strtolower($className), $this->_ignore) === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$includedClasses = array();
|
||||
|
||||
$fileName = strtolower($phpcsFile->getFilename());
|
||||
$matches = array();
|
||||
if (preg_match('|/systems/(.*)/([^/]+)?actions.inc$|', $fileName, $matches) !== 0) {
|
||||
// This is an actions file, which means we don't
|
||||
// have to include the system in which it exists.
|
||||
$includedClasses[] = $matches[2];
|
||||
|
||||
// Or a system it implements.
|
||||
$class = $phpcsFile->getCondition($stackPtr, T_CLASS);
|
||||
$implements = $phpcsFile->findNext(T_IMPLEMENTS, $class, ($class + 10));
|
||||
if ($implements !== false) {
|
||||
$implementsClass = $phpcsFile->findNext(T_STRING, $implements);
|
||||
$implementsClassName = strtolower($tokens[$implementsClass]['content']);
|
||||
if (substr($implementsClassName, -7) === 'actions') {
|
||||
$includedClasses[] = substr($implementsClassName, 0, -7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go searching for includeSystem and includeAsset calls within this
|
||||
// function, or the inclusion of .inc files, which
|
||||
// would be library files.
|
||||
for ($i = ($currScope + 1); $i < $stackPtr; $i++) {
|
||||
$name = $this->getIncludedClassFromToken($phpcsFile, $tokens, $i);
|
||||
if ($name !== false) {
|
||||
$includedClasses[] = $name;
|
||||
// Special case for Widgets cause they are, well, special.
|
||||
} else if (strtolower($tokens[$i]['content']) === 'includewidget') {
|
||||
$typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($i + 1));
|
||||
$typeName = trim($tokens[$typeName]['content'], " '");
|
||||
$includedClasses[] = strtolower($typeName).'widgettype';
|
||||
}
|
||||
}
|
||||
|
||||
// Now go searching for includeSystem, includeAsset or require/include
|
||||
// calls outside our scope. If we are in a class, look outside the
|
||||
// class. If we are not, look outside the function.
|
||||
$condPtr = $currScope;
|
||||
if ($phpcsFile->hasCondition($stackPtr, T_CLASS) === true) {
|
||||
foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condType) {
|
||||
if ($condType === T_CLASS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $condPtr; $i++) {
|
||||
// Skip other scopes.
|
||||
if (isset($tokens[$i]['scope_closer']) === true) {
|
||||
$i = $tokens[$i]['scope_closer'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $this->getIncludedClassFromToken($phpcsFile, $tokens, $i);
|
||||
if ($name !== false) {
|
||||
$includedClasses[] = $name;
|
||||
}
|
||||
}//end for
|
||||
|
||||
// If we are in a testing class, we might have also included
|
||||
// some systems and classes in our setUp() method.
|
||||
$setupFunction = null;
|
||||
if ($phpcsFile->hasCondition($stackPtr, T_CLASS) === true) {
|
||||
foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condType) {
|
||||
if ($condType === T_CLASS) {
|
||||
// Is this is a testing class?
|
||||
$name = $phpcsFile->findNext(T_STRING, $condPtr);
|
||||
$name = $tokens[$name]['content'];
|
||||
if (substr($name, -8) === 'UnitTest') {
|
||||
// Look for a method called setUp().
|
||||
$end = $tokens[$condPtr]['scope_closer'];
|
||||
$function = $phpcsFile->findNext(T_FUNCTION, ($condPtr + 1), $end);
|
||||
while ($function !== false) {
|
||||
$name = $phpcsFile->findNext(T_STRING, $function);
|
||||
if ($tokens[$name]['content'] === 'setUp') {
|
||||
$setupFunction = $function;
|
||||
break;
|
||||
}
|
||||
|
||||
$function = $phpcsFile->findNext(T_FUNCTION, ($function + 1), $end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end foreach
|
||||
}//end if
|
||||
|
||||
if ($setupFunction !== null) {
|
||||
$start = ($tokens[$setupFunction]['scope_opener'] + 1);
|
||||
$end = $tokens[$setupFunction]['scope_closer'];
|
||||
for ($i = $start; $i < $end; $i++) {
|
||||
$name = $this->getIncludedClassFromToken($phpcsFile, $tokens, $i);
|
||||
if ($name !== false) {
|
||||
$includedClasses[] = $name;
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
|
||||
if (in_array(strtolower($className), $includedClasses) === false) {
|
||||
$error = 'Static method called on non-included class or system "%s"; include system with Channels::includeSystem() or include class with require_once';
|
||||
$data = array($className);
|
||||
$phpcsFile->addError($error, $stackPtr, 'NotIncludedCall', $data);
|
||||
}
|
||||
|
||||
}//end processTokenWithinScope()
|
||||
|
||||
|
||||
/**
|
||||
* Processes a token within the scope that this test is listening to.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
|
||||
* @param int $stackPtr The position in the stack where
|
||||
* this token was found.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processTokenOutsideScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
||||
{
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
if ($tokens[$stackPtr]['code'] === T_EXTENDS) {
|
||||
// Find the class name.
|
||||
$classNameToken = $phpcsFile->findNext(T_STRING, ($stackPtr + 1));
|
||||
$className = $tokens[$classNameToken]['content'];
|
||||
} else {
|
||||
// Determine the name of the class that the static function
|
||||
// is being called on.
|
||||
$classNameToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
|
||||
$className = $tokens[$classNameToken]['content'];
|
||||
}
|
||||
|
||||
// Some systems are always available.
|
||||
if (in_array(strtolower($className), $this->_ignore) === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$includedClasses = array();
|
||||
|
||||
$fileName = strtolower($phpcsFile->getFilename());
|
||||
$matches = array();
|
||||
if (preg_match('|/systems/([^/]+)/([^/]+)?actions.inc$|', $fileName, $matches) !== 0) {
|
||||
// This is an actions file, which means we don't
|
||||
// have to include the system in which it exists
|
||||
// We know the system from the path.
|
||||
$includedClasses[] = $matches[1];
|
||||
}
|
||||
|
||||
// Go searching for includeSystem, includeAsset or require/include
|
||||
// calls outside our scope.
|
||||
for ($i = 0; $i < $stackPtr; $i++) {
|
||||
// Skip classes and functions as will we never get
|
||||
// into their scopes when including this file, although
|
||||
// we have a chance of getting into IF's, WHILE's etc.
|
||||
$ignoreTokens = array(
|
||||
T_CLASS,
|
||||
T_INTERFACE,
|
||||
T_FUNCTION,
|
||||
);
|
||||
|
||||
if (in_array($tokens[$i]['code'], $ignoreTokens) === true
|
||||
&& isset($tokens[$i]['scope_closer']) === true
|
||||
) {
|
||||
$i = $tokens[$i]['scope_closer'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $this->getIncludedClassFromToken($phpcsFile, $tokens, $i);
|
||||
if ($name !== false) {
|
||||
$includedClasses[] = $name;
|
||||
// Special case for Widgets cause they are, well, special.
|
||||
} else if (strtolower($tokens[$i]['content']) === 'includewidget') {
|
||||
$typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($i + 1));
|
||||
$typeName = trim($tokens[$typeName]['content'], " '");
|
||||
$includedClasses[] = strtolower($typeName).'widgettype';
|
||||
}
|
||||
}//end for
|
||||
|
||||
if (in_array(strtolower($className), $includedClasses) === false) {
|
||||
if ($tokens[$stackPtr]['code'] === T_EXTENDS) {
|
||||
$error = 'Class extends non-included class or system "%s"; include system with Channels::includeSystem() or include class with require_once';
|
||||
$data = array($className);
|
||||
$phpcsFile->addError($error, $stackPtr, 'NotIncludedExtends', $data);
|
||||
} else {
|
||||
$error = 'Static method called on non-included class or system "%s"; include system with Channels::includeSystem() or include class with require_once';
|
||||
$data = array($className);
|
||||
$phpcsFile->addError($error, $stackPtr, 'NotIncludedCall', $data);
|
||||
}
|
||||
}
|
||||
|
||||
}//end processTokenOutsideScope()
|
||||
|
||||
|
||||
/**
|
||||
* Determines the included class name from given token.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
|
||||
* @param array $tokens The array of file tokens.
|
||||
* @param int $stackPtr The position in the tokens array of the
|
||||
* potentially included class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIncludedClassFromToken(
|
||||
PHP_CodeSniffer_File $phpcsFile,
|
||||
array $tokens,
|
||||
$stackPtr
|
||||
) {
|
||||
if (strtolower($tokens[$stackPtr]['content']) === 'includesystem') {
|
||||
$systemName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($stackPtr + 1));
|
||||
$systemName = trim($tokens[$systemName]['content'], " '");
|
||||
return strtolower($systemName);
|
||||
} else if (strtolower($tokens[$stackPtr]['content']) === 'includeasset') {
|
||||
$typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($stackPtr + 1));
|
||||
$typeName = trim($tokens[$typeName]['content'], " '");
|
||||
return strtolower($typeName).'assettype';
|
||||
} else if (in_array($tokens[$stackPtr]['code'], PHP_CodeSniffer_Tokens::$includeTokens) === true) {
|
||||
$filePath = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, ($stackPtr + 1));
|
||||
$filePath = $tokens[$filePath]['content'];
|
||||
$filePath = trim($filePath, " '");
|
||||
$filePath = basename($filePath, '.inc');
|
||||
return strtolower($filePath);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}//end getIncludedClassFromToken()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that systems, asset types and libs are included before they are used.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that systems and asset types are used if they are included.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Channels_UnusedSystemSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_DOUBLE_COLON);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
// Check if this is a call to includeSystem, includeAsset or includeWidget.
|
||||
$methodName = strtolower($tokens[($stackPtr + 1)]['content']);
|
||||
if (in_array($methodName, array('includesystem', 'includeasset', 'includewidget')) === true) {
|
||||
$systemName = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 3), null, true);
|
||||
if ($systemName === false || $tokens[$systemName]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
|
||||
// Must be using a variable instead of a specific system name.
|
||||
// We can't accurately check that.
|
||||
return;
|
||||
}
|
||||
|
||||
$systemName = trim($tokens[$systemName]['content'], " '");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($methodName === 'includeasset') {
|
||||
$systemName .= 'assettype';
|
||||
} else if ($methodName === 'includewidget') {
|
||||
$systemName .= 'widgettype';
|
||||
}
|
||||
|
||||
$systemName = strtolower($systemName);
|
||||
|
||||
// Now check if this system is used anywhere in this scope.
|
||||
$level = $tokens[$stackPtr]['level'];
|
||||
for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
|
||||
if ($tokens[$i]['level'] < $level) {
|
||||
// We have gone out of scope.
|
||||
// If the original include was inside an IF statement that
|
||||
// is checking if the system exists, check the outer scope
|
||||
// as well.
|
||||
if ($tokens[$stackPtr]['level'] === $level) {
|
||||
// We are still in the base level, so this is the first
|
||||
// time we have got here.
|
||||
$conditions = array_keys($tokens[$stackPtr]['conditions']);
|
||||
if (empty($conditions) === false) {
|
||||
$cond = array_pop($conditions);
|
||||
if ($tokens[$cond]['code'] === T_IF) {
|
||||
$i = $tokens[$cond]['scope_closer'];
|
||||
$level--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}//end if
|
||||
|
||||
$validTokens = array(
|
||||
T_DOUBLE_COLON,
|
||||
T_EXTENDS,
|
||||
T_IMPLEMENTS,
|
||||
);
|
||||
|
||||
if (in_array($tokens[$i]['code'], $validTokens) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($tokens[$i]['code']) {
|
||||
case T_DOUBLE_COLON:
|
||||
$usedName = strtolower($tokens[($i - 1)]['content']);
|
||||
if ($usedName === $systemName) {
|
||||
// The included system was used, so it is fine.
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case T_EXTENDS:
|
||||
$classNameToken = $phpcsFile->findNext(T_STRING, ($i + 1));
|
||||
$className = strtolower($tokens[$classNameToken]['content']);
|
||||
if ($className === $systemName) {
|
||||
// The included system was used, so it is fine.
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case T_IMPLEMENTS:
|
||||
$endImplements = $phpcsFile->findNext(array(T_EXTENDS, T_OPEN_CURLY_BRACKET), ($i + 1));
|
||||
for ($x = ($i + 1); $x < $endImplements; $x++) {
|
||||
if ($tokens[$x]['code'] === T_STRING) {
|
||||
$className = strtolower($tokens[$x]['content']);
|
||||
if ($className === $systemName) {
|
||||
// The included system was used, so it is fine.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}//end switch
|
||||
}//end for
|
||||
|
||||
// If we get to here, the system was not use.
|
||||
$error = 'Included system "%s" is never used';
|
||||
$data = array($systemName);
|
||||
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses and verifies the doc comments for functions.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @author Marc McIntyre <mmcintyre@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
if (class_exists('Squiz_Sniffs_Commenting_FunctionCommentSniff', true) === false) {
|
||||
$error = 'Class Squiz_Sniffs_Commenting_FunctionCommentSniff not found';
|
||||
throw new PHP_CodeSniffer_Exception($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and verifies the doc comments for functions.
|
||||
*
|
||||
* Same as the Squiz standard, but adds support for API tags.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Commenting_FunctionCommentSniff extends Squiz_Sniffs_Commenting_FunctionCommentSniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Process a list of unknown tags.
|
||||
*
|
||||
* @param int $commentStart The position in the stack where the comment started.
|
||||
* @param int $commentEnd The position in the stack where the comment ended.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processUnknownTags($commentStart, $commentEnd)
|
||||
{
|
||||
$unknownTags = $this->commentParser->getUnknown();
|
||||
$words = $this->commentParser->getWords();
|
||||
$hasApiTag = false;
|
||||
$apiLength = 3;
|
||||
foreach ($unknownTags as $errorTag) {
|
||||
$pos = $errorTag['pos'];
|
||||
if ($errorTag['tag'] === 'api') {
|
||||
if ($hasApiTag === true) {
|
||||
// We've come across an API tag already, which means
|
||||
// we were not the first tag in the API list.
|
||||
$error = 'The @api tag must come first in the @api tag list in a function comment';
|
||||
$this->currentFile->addError($error, ($commentStart + $errorTag['line']), 'ApiNotFirst');
|
||||
}
|
||||
|
||||
$hasApiTag = true;
|
||||
|
||||
// There needs to be a blank line before the @api tag.
|
||||
// So expect a single space before the tag, then 2 newlines before
|
||||
// that, then some content.
|
||||
if (trim($words[($pos - 2)]) !== ''
|
||||
|| strpos($words[($pos - 2)], $this->currentFile->eolChar) === false
|
||||
|| strpos($words[($pos - 3)], $this->currentFile->eolChar) === false
|
||||
|| trim($words[($pos - 4)]) === ''
|
||||
) {
|
||||
$error = 'There must be one blank line before the @api tag in a function comment';
|
||||
$this->currentFile->addError($error, ($commentStart + $errorTag['line']), 'ApiSpacing');
|
||||
}
|
||||
} else if (substr($errorTag['tag'], 0, 4) === 'api-') {
|
||||
$hasApiTag = true;
|
||||
|
||||
$tagLength = strlen($errorTag['tag']);
|
||||
if ($tagLength > $apiLength) {
|
||||
$apiLength = $tagLength;
|
||||
}
|
||||
|
||||
if (trim($words[($pos - 2)]) !== ''
|
||||
|| strpos($words[($pos - 2)], $this->currentFile->eolChar) === false
|
||||
|| trim($words[($pos - 3)]) === ''
|
||||
) {
|
||||
$error = 'There must be no blank line before the @%s tag in a function comment';
|
||||
$data = array($errorTag['tag']);
|
||||
$this->currentFile->addError($error, ($commentStart + $errorTag['line']), 'ApiTagSpacing', $data);
|
||||
}
|
||||
} else {
|
||||
$error = '@%s tag is not allowed in function comment';
|
||||
$data = array($errorTag['tag']);
|
||||
$this->currentFile->addWarning($error, ($commentStart + $errorTag['line']), 'TagNotAllowed', $data);
|
||||
}//end if
|
||||
}//end foreach
|
||||
|
||||
if ($hasApiTag === true) {
|
||||
// API tags must be the last tags in a function comment.
|
||||
$order = $this->commentParser->getTagOrders();
|
||||
$lastTag = array_pop($order);
|
||||
if ($lastTag !== 'api'
|
||||
&& substr($lastTag, 0, 4) !== 'api-'
|
||||
) {
|
||||
$error = 'The @api tags must be the last tags in a function comment';
|
||||
$this->currentFile->addError($error, $commentEnd, 'ApiNotLast');
|
||||
}
|
||||
|
||||
// Check API tag indenting.
|
||||
foreach ($unknownTags as $errorTag) {
|
||||
if ($errorTag['tag'] === 'api'
|
||||
|| substr($errorTag['tag'], 0, 4) === 'api-'
|
||||
) {
|
||||
$expected = ($apiLength - strlen($errorTag['tag']) + 1);
|
||||
$found = strlen($words[($errorTag['pos'] + 1)]);
|
||||
if ($found !== $expected) {
|
||||
$error = '@%s tag indented incorrectly; expected %s spaces but found %s';
|
||||
$data = array(
|
||||
$errorTag['tag'],
|
||||
$expected,
|
||||
$found,
|
||||
);
|
||||
$this->currentFile->addError($error, ($commentStart + $errorTag['line']), 'ApiTagIndent', $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end if
|
||||
|
||||
}//end processUnknownTags()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Warns about the use of debug code.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Warns about the use of debug code.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Debug_DebugCodeSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_DOUBLE_COLON);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
$className = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
|
||||
if (strtolower($tokens[$className]['content']) === 'debug') {
|
||||
$method = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
|
||||
$error = 'Call to debug function Debug::%s() must be removed';
|
||||
$data = array($tokens[$method]['content']);
|
||||
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that console is not used for function or var names.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that console is not used for function or var names.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Debug_FirebugConsoleSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedTokenizers = array('JS');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(
|
||||
T_STRING,
|
||||
T_PROPERTY,
|
||||
T_LABEL,
|
||||
T_OBJECT,
|
||||
);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
if (strtolower($tokens[$stackPtr]['content']) === 'console') {
|
||||
$error = 'Variables, functions and labels must not be named "console"; name may conflict with Firebug internal variable';
|
||||
$phpcsFile->addError($error, $stackPtr, 'ConflictFound');
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures this is not assigned to any other var but self.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures this is not assigned to any other var but self.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Objects_AssignThisSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedTokenizers = array('JS');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_THIS);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
// Ignore this.something and other uses of "this" that are not
|
||||
// direct assignments.
|
||||
$next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
|
||||
if ($tokens[$next]['code'] !== T_SEMICOLON) {
|
||||
if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Something must be assigned to "this".
|
||||
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
|
||||
if ($tokens[$prev]['code'] !== T_EQUAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A variable needs to be assigned to "this".
|
||||
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($prev - 1), null, true);
|
||||
if ($tokens[$prev]['code'] !== T_STRING) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We can only assign "this" to a var called "self".
|
||||
if ($tokens[$prev]['content'] !== 'self' && $tokens[$prev]['content'] !== '_self') {
|
||||
$error = 'Keyword "this" can only be assigned to a variable called "self" or "_self"';
|
||||
$phpcsFile->addError($error, $prev, 'NotSelf');
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures the create() method of widget types properly uses callbacks.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures the create() method of widget types properly uses callbacks.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Objects_CreateWidgetTypeCallbackSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedTokenizers = array('JS');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_OBJECT);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
$className = $tokens[$stackPtr]['content'];
|
||||
if (substr(strtolower($className), -10) !== 'widgettype') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for a create method.
|
||||
$start = ($tokens[$stackPtr]['scope_opener'] + 1);
|
||||
$end = ($tokens[$stackPtr]['scope_closer'] - 1);
|
||||
$create = $phpcsFile->findNext(T_PROPERTY, $start, $end, null, 'create');
|
||||
if ($create === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$function = $phpcsFile->findNext(array(T_WHITESPACE, T_COLON), ($create + 1), null, true);
|
||||
if ($tokens[$function]['code'] !== T_FUNCTION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$start = ($tokens[$function]['scope_opener'] + 1);
|
||||
$end = ($tokens[$function]['scope_closer'] - 1);
|
||||
|
||||
// Check that the first argument is called "callback".
|
||||
$arg = $phpcsFile->findNext(T_WHITESPACE, ($tokens[$function]['parenthesis_opener'] + 1), null, true);
|
||||
if ($tokens[$arg]['content'] !== 'callback') {
|
||||
$error = 'The first argument of the create() method of a widget type must be called "callback"';
|
||||
$phpcsFile->addError($error, $arg, 'FirstArgNotCallback');
|
||||
}
|
||||
|
||||
/*
|
||||
Look for return statements within the function. They cannot return
|
||||
anything and must be preceeded by the callback.call() line. The
|
||||
callback itself must contain "self" or "this" as the first argument
|
||||
and there needs to be a call to the callback function somewhere
|
||||
in the create method. All calls to the callback function must be
|
||||
followed by a return statement or the end of the method.
|
||||
*/
|
||||
|
||||
$foundCallback = false;
|
||||
$passedCallback = false;
|
||||
$nestedFunction = null;
|
||||
for ($i = $start; $i <= $end; $i++) {
|
||||
// Keep track of nested functions.
|
||||
if ($nestedFunction !== null) {
|
||||
if ($i === $nestedFunction) {
|
||||
$nestedFunction = null;
|
||||
continue;
|
||||
}
|
||||
} else if ($tokens[$i]['code'] === T_FUNCTION
|
||||
&& isset($tokens[$i]['scope_closer']) === true
|
||||
) {
|
||||
$nestedFunction = $tokens[$i]['scope_closer'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($nestedFunction === null && $tokens[$i]['code'] === T_RETURN) {
|
||||
// Make sure return statements are not returning anything.
|
||||
if ($tokens[($i + 1)]['code'] !== T_SEMICOLON) {
|
||||
$error = 'The create() method of a widget type must not return a value';
|
||||
$phpcsFile->addError($error, $i, 'ReturnValue');
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if ($tokens[$i]['code'] !== T_STRING
|
||||
|| $tokens[$i]['content'] !== 'callback'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the form "callback.call(" then it is a call
|
||||
// to the callback function.
|
||||
if ($tokens[($i + 1)]['code'] !== T_OBJECT_OPERATOR
|
||||
|| $tokens[($i + 2)]['content'] !== 'call'
|
||||
|| $tokens[($i + 3)]['code'] !== T_OPEN_PARENTHESIS
|
||||
) {
|
||||
// One last chance; this might be the callback function
|
||||
// being passed to another function, like this
|
||||
// "this.init(something, callback, something)".
|
||||
if (isset($tokens[$i]['nested_parenthesis']) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Just make sure those brackets dont belong to anyone,
|
||||
// like an IF or FOR statement.
|
||||
foreach ($tokens[$i]['nested_parenthesis'] as $bracket) {
|
||||
if (isset($tokens[$bracket]['parenthesis_owner']) === true) {
|
||||
continue(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we use this endBracket down further when checking
|
||||
// for a RETURN statement.
|
||||
$endBracket = end($tokens[$i]['nested_parenthesis']);
|
||||
$bracket = key($tokens[$i]['nested_parenthesis']);
|
||||
|
||||
$prev = $phpcsFile->findPrevious(
|
||||
PHP_CodeSniffer_Tokens::$emptyTokens,
|
||||
($bracket - 1),
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ($tokens[$prev]['code'] !== T_STRING) {
|
||||
// This is not a function passing the callback.
|
||||
continue;
|
||||
}
|
||||
|
||||
$passedCallback = true;
|
||||
}//end if
|
||||
|
||||
$foundCallback = true;
|
||||
|
||||
if ($passedCallback === false) {
|
||||
// The first argument must be "this" or "self".
|
||||
$arg = $phpcsFile->findNext(T_WHITESPACE, ($i + 4), null, true);
|
||||
if ($tokens[$arg]['content'] !== 'this'
|
||||
&& $tokens[$arg]['content'] !== 'self'
|
||||
) {
|
||||
$error = 'The first argument passed to the callback function must be "this" or "self"';
|
||||
$phpcsFile->addError($error, $arg, 'FirstArgNotSelf');
|
||||
}
|
||||
}
|
||||
|
||||
// Now it must be followed by a return statement or the end of the function.
|
||||
if ($passedCallback === false) {
|
||||
$endBracket = $tokens[($i + 3)]['parenthesis_closer'];
|
||||
}
|
||||
|
||||
for ($next = $endBracket; $next <= $end; $next++) {
|
||||
// Skip whitespace so we find the next content after the call.
|
||||
if (in_array($tokens[$next]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip closing braces like END IF because it is not executable code.
|
||||
if ($tokens[$next]['code'] === T_CLOSE_CURLY_BRACKET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't care about anything on the current line, like a
|
||||
// semicolon. It doesn't matter if there are other statements on the
|
||||
// line because another sniff will check for those.
|
||||
if ($tokens[$next]['line'] === $tokens[$endBracket]['line']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($next !== $tokens[$function]['scope_closer']
|
||||
&& $tokens[$next]['code'] !== T_RETURN
|
||||
) {
|
||||
$error = 'The call to the callback function must be followed by a return statement if it is not the last statement in the create() method';
|
||||
$phpcsFile->addError($error, $i, 'NoReturn');
|
||||
}
|
||||
}//end for
|
||||
|
||||
if ($foundCallback === false) {
|
||||
$error = 'The create() method of a widget type must call the callback function';
|
||||
$phpcsFile->addError($error, $create, 'CallbackNotCalled');
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that widgets are not manually created.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that widgets are not manually created.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Objects_DisallowNewWidgetSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_NEW);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this test, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
$className = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
|
||||
if ($tokens[$className]['code'] !== T_STRING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (substr(strtolower($tokens[$className]['content']), -10) === 'widgettype') {
|
||||
$widgetType = substr($tokens[$className]['content'], 0, -10);
|
||||
$error = 'Manual creation of widget objects is banned; use Widget::getWidget(\'%s\'); instead';
|
||||
$data = array($widgetType);
|
||||
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that eval() is not used to create objects.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that eval() is not used to create objects.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_PHP_EvalObjectFactorySniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_EVAL);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
/*
|
||||
We need to find all strings that will be in the eval
|
||||
to determine if the "new" keyword is being used.
|
||||
*/
|
||||
|
||||
$openBracket = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($stackPtr + 1));
|
||||
$closeBracket = $tokens[$openBracket]['parenthesis_closer'];
|
||||
|
||||
$strings = array();
|
||||
$vars = array();
|
||||
|
||||
for ($i = ($openBracket + 1); $i < $closeBracket; $i++) {
|
||||
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$stringTokens) === true) {
|
||||
$strings[$i] = $tokens[$i]['content'];
|
||||
} else if ($tokens[$i]['code'] === T_VARIABLE) {
|
||||
$vars[$i] = $tokens[$i]['content'];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We now have some variables that we need to expand into
|
||||
the strings that were assigned to them, if any.
|
||||
*/
|
||||
|
||||
foreach ($vars as $varPtr => $varName) {
|
||||
while (($prev = $phpcsFile->findPrevious(T_VARIABLE, ($varPtr - 1))) !== false) {
|
||||
// Make sure this is an assignment of the variable. That means
|
||||
// it will be the first thing on the line.
|
||||
$prevContent = $phpcsFile->findPrevious(T_WHITESPACE, ($prev - 1), null, true);
|
||||
if ($tokens[$prevContent]['line'] === $tokens[$prev]['line']) {
|
||||
$varPtr = $prevContent;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($tokens[$prev]['content'] !== $varName) {
|
||||
// This variable has a different name.
|
||||
$varPtr = $prevContent;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We found one.
|
||||
break;
|
||||
}//end while
|
||||
|
||||
if ($prev !== false) {
|
||||
// Find all strings on the line.
|
||||
$lineEnd = $phpcsFile->findNext(T_SEMICOLON, ($prev + 1));
|
||||
for ($i = ($prev + 1); $i < $lineEnd; $i++) {
|
||||
if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$stringTokens) === true) {
|
||||
$strings[$i] = $tokens[$i]['content'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end foreach
|
||||
|
||||
foreach ($strings as $string) {
|
||||
// If the string has "new" in it, it is not allowed.
|
||||
// We don't bother checking if the word "new" is echo'd
|
||||
// because that is unlikely to happen. We assume the use
|
||||
// of "new" is for object instantiation.
|
||||
if (strstr($string, ' new ') !== false) {
|
||||
$error = 'Do not use eval() to create objects dynamically; use reflection instead';
|
||||
$phpcsFile->addWarning($error, $stackPtr, 'Found');
|
||||
}
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that getRequestData() is used to access super globals.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that getRequestData() is used to access super globals.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_PHP_GetRequestDataSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_VARIABLE);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
$varName = $tokens[$stackPtr]['content'];
|
||||
if ($varName !== '$_REQUEST'
|
||||
&& $varName !== '$_GET'
|
||||
&& $varName !== '$_POST'
|
||||
&& $varName !== '$_FILES'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The only place these super globals can be accessed directly is
|
||||
// in the getRequestData() method of the Security class.
|
||||
$inClass = false;
|
||||
foreach ($tokens[$stackPtr]['conditions'] as $i => $type) {
|
||||
if ($tokens[$i]['code'] === T_CLASS) {
|
||||
$className = $phpcsFile->findNext(T_STRING, $i);
|
||||
$className = $tokens[$className]['content'];
|
||||
if (strtolower($className) === 'security') {
|
||||
$inClass = true;
|
||||
} else {
|
||||
// We don't have nested classes.
|
||||
break;
|
||||
}
|
||||
} else if ($inClass === true && $tokens[$i]['code'] === T_FUNCTION) {
|
||||
$funcName = $phpcsFile->findNext(T_STRING, $i);
|
||||
$funcName = $tokens[$funcName]['content'];
|
||||
if (strtolower($funcName) === 'getrequestdata') {
|
||||
// This is valid.
|
||||
return;
|
||||
} else {
|
||||
// We don't have nested functions.
|
||||
break;
|
||||
}
|
||||
}//end if
|
||||
}//end foreach
|
||||
|
||||
// If we get to here, the super global was used incorrectly.
|
||||
// First find out how it is being used.
|
||||
$globalName = strtolower(substr($varName, 2));
|
||||
$usedVar = '';
|
||||
|
||||
$openBracket = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
|
||||
if ($tokens[$openBracket]['code'] === T_OPEN_SQUARE_BRACKET) {
|
||||
$closeBracket = $tokens[$openBracket]['bracket_closer'];
|
||||
$usedVar = $phpcsFile->getTokensAsString(($openBracket + 1), ($closeBracket - $openBracket - 1));
|
||||
}
|
||||
|
||||
$type = 'SuperglobalAccessed';
|
||||
$error = 'The %s super global must not be accessed directly; use Security::getRequestData(';
|
||||
$data = array($varName);
|
||||
if ($usedVar !== '') {
|
||||
$type .= 'WithVar';
|
||||
$error .= '%s, \'%s\'';
|
||||
$data[] = $usedVar;
|
||||
$data[] = $globalName;
|
||||
}
|
||||
|
||||
$error .= ') instead';
|
||||
$phpcsFile->addError($error, $stackPtr, $type, $data);
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Warns when function values are returned directly.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Warns when function values are returned directly.
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_PHP_ReturnFunctionValueSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_RETURN);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* Processes this sniff, when one of its tokens is encountered.
|
||||
*
|
||||
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
||||
* @param int $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();
|
||||
|
||||
$functionName = $phpcsFile->findNext(T_STRING, ($stackPtr + 1), null, false, null, true);
|
||||
|
||||
while ($functionName !== false) {
|
||||
// Check if this is really a function.
|
||||
$bracket = $phpcsFile->findNext(T_WHITESPACE, ($functionName + 1), null, true);
|
||||
if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) {
|
||||
// Not a function call.
|
||||
$functionName = $phpcsFile->findNext(T_STRING, ($functionName + 1), null, false, null, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
$error = 'The result of a function call should be assigned to a variable before being returned';
|
||||
$phpcsFile->addWarning($error, $stackPtr, 'NotAssigned');
|
||||
break;
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* Ensures that strings are not joined using array.join().
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensures that strings are not joined using array.join().
|
||||
*
|
||||
* @category PHP
|
||||
* @package PHP_CodeSniffer_MySource
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
|
||||
* @version Release: 1.3.3
|
||||
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||||
*/
|
||||
class MySource_Sniffs_Strings_JoinStringsSniff implements PHP_CodeSniffer_Sniff
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of tokenizers this sniff supports.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $supportedTokenizers = array('JS');
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of tokens this test wants to listen for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
return array(T_STRING);
|
||||
|
||||
}//end register()
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
if ($tokens[$stackPtr]['content'] !== 'join') {
|
||||
return;
|
||||
}
|
||||
|
||||
$prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
|
||||
if ($tokens[$prev]['code'] !== T_OBJECT_OPERATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($prev - 1), null, true);
|
||||
if ($tokens[$prev]['code'] === T_CLOSE_SQUARE_BRACKET) {
|
||||
$opener = $tokens[$prev]['bracket_opener'];
|
||||
if ($tokens[($opener - 1)]['code'] !== T_STRING) {
|
||||
// This means the array is declared inline, like x = [a,b,c].join()
|
||||
// and not elsewhere, like x = y[a].join()
|
||||
// The first is not allowed while the second is.
|
||||
$error = 'Joining strings using inline arrays is not allowed; use the + operator instead';
|
||||
$phpcsFile->addError($error, $stackPtr, 'ArrayNotAllowed');
|
||||
}
|
||||
}
|
||||
|
||||
}//end process()
|
||||
|
||||
|
||||
}//end class
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="MySource">
|
||||
<description>The MySource coding standard builds on the Squiz coding standard. Currently used for MySource Mini development.</description>
|
||||
|
||||
<exclude-pattern>*/Tests/*</exclude-pattern>
|
||||
<exclude-pattern>*/Oven/*</exclude-pattern>
|
||||
<exclude-pattern>*/data/*</exclude-pattern>
|
||||
<exclude-pattern>DALConf.inc</exclude-pattern>
|
||||
|
||||
<!-- Include the whole Squiz standard except FunctionComment, which we override -->
|
||||
<rule ref="Squiz">
|
||||
<exclude name="Squiz.Commenting.FunctionComment"/>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
Reference in New Issue
Block a user