예제 #1
0
 /**
  * Processes single-line calls.
  *
  * @param PHP_CodeSniffer_File $phpcsFile   The file being scanned.
  * @param int                  $stackPtr    The position of the current token
  *                                          in the stack passed in $tokens.
  * @param int                  $openBracket The position of the opening bracket
  *                                          in the stack passed in $tokens.
  * @param array                $tokens      The stack of tokens that make up
  *                                          the file.
  *
  * @return void
  */
 public function isMultiLineCall(File $phpcsFile, $stackPtr, $openBracket, $tokens)
 {
     // If the first argument is on a new line, this is a multi-line
     // function call, even if there is only one argument.
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $openBracket + 1, null, true);
     if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
         return true;
     }
     $closeBracket = $tokens[$openBracket]['parenthesis_closer'];
     $end = $phpcsFile->findEndOfStatement($openBracket + 1);
     while ($tokens[$end]['code'] === T_COMMA) {
         // If the next bit of code is not on the same line, this is a
         // multi-line function call.
         $next = $phpcsFile->findNext(Tokens::$emptyTokens, $end + 1, $closeBracket, true);
         if ($next === false) {
             return false;
         }
         if ($tokens[$next]['line'] !== $tokens[$end]['line']) {
             return true;
         }
         $end = $phpcsFile->findEndOfStatement($next);
     }
     // We've reached the last argument, so see if the next content
     // (should be the close bracket) is also on the same line.
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $end + 1, $closeBracket, true);
     if ($next !== false && $tokens[$next]['line'] !== $tokens[$end]['line']) {
         return true;
     }
     return false;
 }
예제 #2
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $firstContent = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     // If the first non-whitespace token is not an opening parenthesis, then we are not concerned.
     if ($tokens[$firstContent]['code'] !== T_OPEN_PARENTHESIS) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     $end = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), $stackPtr, null, false);
     // If the token before the semi-colon is not a closing parenthesis, then we are not concerned.
     $prev = $phpcsFile->findPrevious(T_WHITESPACE, $end - 1, null, true);
     if ($tokens[$prev]['code'] !== T_CLOSE_PARENTHESIS) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     // If the parenthesis don't match, then we are not concerned.
     if ($tokens[$firstContent]['parenthesis_closer'] !== $prev) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'yes');
     if ($phpcsFile->findNext(Tokens::$operators, $stackPtr, $end, false) === false) {
         // There are no arithmetic operators in this.
         $error = 'Echoed strings should not be bracketed';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'HasBracket');
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             $phpcsFile->fixer->replaceToken($firstContent, '');
             $phpcsFile->fixer->replaceToken($end - 1, '');
             $phpcsFile->fixer->endChangeset();
         }
     }
 }
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Check if the next non whitespace token is a string.
     $index = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$index]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
         return;
     }
     // Make sure it is the only thing in the square brackets.
     $next = $phpcsFile->findNext(T_WHITESPACE, $index + 1, null, true);
     if ($tokens[$next]['code'] !== T_CLOSE_SQUARE_BRACKET) {
         return;
     }
     // Allow indexes that have dots in them because we can't write
     // them in dot notation.
     $content = trim($tokens[$index]['content'], '"\' ');
     if (strpos($content, '.') !== false) {
         return;
     }
     // Also ignore reserved words.
     if ($content === 'super') {
         return;
     }
     // Token before the opening square bracket cannot be a var name.
     $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
     if ($tokens[$prev]['code'] === T_STRING) {
         $error = 'Object indexes must be written in dot notation';
         $phpcsFile->addError($error, $prev, 'Found');
     }
 }
예제 #4
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The current file being processed.
  * @param int                  $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         $error = 'Possible parse error: %s missing opening or closing brace';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data);
         return;
     }
     // Determine the name of the class or interface. Note that we cannot
     // simply look for the first T_STRING because a class name
     // starting with the number will be multiple tokens.
     $opener = $tokens[$stackPtr]['scope_opener'];
     $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true);
     $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener);
     if ($nameEnd === false) {
         $name = $tokens[$nameStart]['content'];
     } else {
         $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart));
     }
     // Check for camel caps format.
     $valid = Common::isCamelCaps($name, true, true, false);
     if ($valid === false) {
         $type = ucfirst($tokens[$stackPtr]['content']);
         $error = '%s name "%s" is not in camel caps format';
         $data = array($type, $name);
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data);
         $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'no');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'CamelCase class name', 'yes');
     }
 }
예제 #5
0
 /**
  * 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
  */
 protected function processVariable(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $varName = ltrim($tokens[$stackPtr]['content'], '$');
     $phpReservedVars = array('_SERVER', '_GET', '_POST', '_REQUEST', '_SESSION', '_ENV', '_COOKIE', '_FILES', 'GLOBALS', 'http_response_header', 'HTTP_RAW_POST_DATA', 'php_errormsg');
     // If it's a php reserved var, then its ok.
     if (in_array($varName, $phpReservedVars) === true) {
         return;
     }
     $objOperator = $phpcsFile->findNext(array(T_WHITESPACE), $stackPtr + 1, null, true);
     if ($tokens[$objOperator]['code'] === T_OBJECT_OPERATOR) {
         // Check to see if we are using a variable from an object.
         $var = $phpcsFile->findNext(array(T_WHITESPACE), $objOperator + 1, null, true);
         if ($tokens[$var]['code'] === T_STRING) {
             $bracket = $phpcsFile->findNext(array(T_WHITESPACE), $var + 1, null, true);
             if ($tokens[$bracket]['code'] !== T_OPEN_PARENTHESIS) {
                 $objVarName = $tokens[$var]['content'];
                 // 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 = $objVarName;
                 if (substr($objVarName, 0, 1) === '_') {
                     $objVarName = substr($objVarName, 1);
                 }
                 if (Common::isCamelCaps($objVarName, false, true, false) === false) {
                     $error = 'Variable "%s" is not in valid camel caps format';
                     $data = array($originalVarName);
                     $phpcsFile->addError($error, $var, 'NotCamelCaps', $data);
                 }
             }
             //end if
         }
         //end if
     }
     //end if
     // 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_CLASS, T_INTERFACE, T_TRAIT));
         }
         if ($inClass === true) {
             $varName = substr($varName, 1);
         }
     }
     if (Common::isCamelCaps($varName, false, true, false) === false) {
         $error = 'Variable "%s" is not in valid camel caps format';
         $data = array($originalVarName);
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data);
     }
 }
예제 #6
0
 /**
  * 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(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);
 }
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($next === false) {
         return;
     }
     if ($tokens[$next]['code'] !== T_CLOSE_TAG) {
         $found = $tokens[$next]['line'] - $tokens[$stackPtr]['line'] - 1;
         if ($found !== 1) {
             $error = 'Expected one blank line after closing brace of class definition; %s found';
             $data = array($found);
             $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterClose', $data);
             if ($fix === true) {
                 if ($found === 0) {
                     $phpcsFile->fixer->addNewline($stackPtr);
                 } else {
                     $nextContent = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
                     $phpcsFile->fixer->beginChangeset();
                     for ($i = $stackPtr + 1; $i < $nextContent - 1; $i++) {
                         $phpcsFile->fixer->replaceToken($i, '');
                     }
                     $phpcsFile->fixer->addNewline($i);
                     $phpcsFile->fixer->endChangeset();
                 }
             }
         }
         //end if
     }
     //end if
     // Ignore nested style definitions from here on. The spacing before the closing brace
     // (a single blank line) will be enforced by the above check, which ensures there is a
     // blank line after the last nested class.
     $found = $phpcsFile->findPrevious(T_CLOSE_CURLY_BRACKET, $stackPtr - 1, $tokens[$stackPtr]['bracket_opener']);
     if ($found !== false) {
         return;
     }
     $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
     if ($prev === false) {
         return;
     }
     if ($tokens[$prev]['line'] === $tokens[$stackPtr]['line']) {
         $error = 'Closing brace of class definition must be on new line';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentBeforeClose');
         if ($fix === true) {
             $phpcsFile->fixer->addNewlineBefore($stackPtr);
         }
     }
 }
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Find the content of each style definition name.
     $styleNames = array();
     $next = $stackPtr;
     $end = $tokens[$stackPtr]['bracket_closer'];
     do {
         $next = $phpcsFile->findNext(array(T_STYLE, T_OPEN_CURLY_BRACKET), $next + 1, $end);
         if ($next === false) {
             // Class definition is empty.
             break;
         }
         if ($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET) {
             $next = $tokens[$next]['bracket_closer'];
             continue;
         }
         $name = $tokens[$next]['content'];
         if (isset($styleNames[$name]) === true) {
             $first = $styleNames[$name];
             $error = 'Duplicate style definition found; first defined on line %s';
             $data = array($tokens[$first]['line']);
             $phpcsFile->addError($error, $next, 'Found', $data);
         } else {
             $styleNames[$name] = $next;
         }
     } while ($next !== false);
 }
예제 #9
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $fileName = $phpcsFile->getFilename();
     $matches = array();
     if (preg_match('|/systems/(.*)/([^/]+)?actions.inc$|i', $fileName, $matches) === 0) {
         // Not an actions file.
         return;
     }
     $ownClass = $matches[2];
     $tokens = $phpcsFile->getTokens();
     $typeName = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr + 2, null, false, true);
     $typeName = trim($tokens[$typeName]['content'], " '");
     switch (strtolower($tokens[$stackPtr + 1]['content'])) {
         case 'includesystem':
             $included = strtolower($typeName);
             break;
         case 'includeasset':
             $included = strtolower($typeName) . 'assettype';
             break;
         case 'includewidget':
             $included = strtolower($typeName) . 'widgettype';
             break;
         default:
             return;
     }
     if ($included === strtolower($ownClass)) {
         $error = "You do not need to include \"%s\" from within the system's own actions file";
         $data = array($ownClass);
         $phpcsFile->addError($error, $stackPtr, 'NotRequired', $data);
     }
 }
예제 #10
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $lastLine = $tokens[$stackPtr]['line'];
     $end = $tokens[$stackPtr]['bracket_closer'];
     $endLine = $tokens[$end]['line'];
     // Do not check nested style definitions as, for example, in @media style rules.
     $nested = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr + 1, $end);
     if ($nested !== false) {
         return;
     }
     $foundColon = false;
     $foundString = false;
     for ($i = $stackPtr + 1; $i <= $end; $i++) {
         if ($tokens[$i]['line'] !== $lastLine) {
             // We changed lines.
             if ($foundColon === false && $foundString !== false) {
                 // We didn't find a colon on the previous line.
                 $error = 'No style definition found on line; check for missing colon';
                 $phpcsFile->addError($error, $foundString, 'Found');
             }
             $foundColon = false;
             $foundString = false;
             $lastLine = $tokens[$i]['line'];
         }
         if ($tokens[$i]['code'] === T_STRING) {
             $foundString = $i;
         } else {
             if ($tokens[$i]['code'] === T_COLON) {
                 $foundColon = $i;
             }
         }
     }
     //end for
 }
예제 #11
0
 /**
  * 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(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');
     }
 }
예제 #12
0
 /**
  * Processes the function tokens within the class.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
  * @param int                  $stackPtr  The position where the token was found.
  *
  * @return void
  */
 protected function processMemberVar(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if ($tokens[$stackPtr]['content'][1] === '_') {
         $error = 'Property name "%s" should not be prefixed with an underscore to indicate visibility';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data);
     }
     // Detect multiple properties defined at the same time. Throw an error
     // for this, but also only process the first property in the list so we don't
     // repeat errors.
     $find = Tokens::$scopeModifiers;
     $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON));
     $prev = $phpcsFile->findPrevious($find, $stackPtr - 1);
     if ($tokens[$prev]['code'] === T_VARIABLE) {
         return;
     }
     if ($tokens[$prev]['code'] === T_VAR) {
         $error = 'The var keyword must not be used to declare a property';
         $phpcsFile->addError($error, $stackPtr, 'VarUsed');
     }
     $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), $stackPtr + 1);
     if ($tokens[$next]['code'] === T_VARIABLE) {
         $error = 'There must not be more than one property declared per statement';
         $phpcsFile->addError($error, $stackPtr, 'Multiple');
     }
     $modifier = $phpcsFile->findPrevious(Tokens::$scopeModifiers, $stackPtr);
     if ($modifier === false || $tokens[$modifier]['line'] !== $tokens[$stackPtr]['line']) {
         $error = 'Visibility must be declared on property "%s"';
         $data = array($tokens[$stackPtr]['content']);
         $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data);
     }
 }
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_opener']) === false) {
         // Probably an interface method.
         return;
     }
     $openBrace = $tokens[$stackPtr]['scope_opener'];
     $nextContent = $phpcsFile->findNext(T_WHITESPACE, $openBrace + 1, null, true);
     if ($nextContent === $tokens[$stackPtr]['scope_closer']) {
         // The next bit of content is the closing brace, so this
         // is an empty function and should have a blank line
         // between the opening and closing braces.
         return;
     }
     $braceLine = $tokens[$openBrace]['line'];
     $nextLine = $tokens[$nextContent]['line'];
     $found = $nextLine - $braceLine - 1;
     if ($found > 0) {
         $error = 'Expected 0 blank lines after opening function brace; %s found';
         $data = array($found);
         $fix = $phpcsFile->addFixableError($error, $openBrace, 'SpacingAfter', $data);
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             for ($i = $openBrace + 1; $i < $nextContent; $i++) {
                 if ($tokens[$i]['line'] === $nextLine) {
                     break;
                 }
                 $phpcsFile->fixer->replaceToken($i, '');
             }
             $phpcsFile->fixer->addNewline($openBrace);
             $phpcsFile->fixer->endChangeset();
         }
     }
 }
예제 #14
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $openTag = $tokens[$stackPtr];
     if ($openTag['content'] === '<?') {
         $error = 'Short PHP opening tag used; expected "<?php" but found "%s"';
         $data = array($openTag['content']);
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found', $data);
         if ($fix === true) {
             $phpcsFile->fixer->replaceToken($stackPtr, '<?php');
         }
         $phpcsFile->recordMetric($stackPtr, 'PHP short open tag used', 'yes');
     } else {
         $phpcsFile->recordMetric($stackPtr, 'PHP short open tag used', 'no');
     }
     if ($openTag['code'] === T_OPEN_TAG_WITH_ECHO) {
         $nextVar = $tokens[$phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true)];
         $error = 'Short PHP opening tag used with echo; expected "<?php echo %s ..." but found "%s %s ..."';
         $data = array($nextVar['content'], $openTag['content'], $nextVar['content']);
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'EchoFound', $data);
         if ($fix === true) {
             if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) {
                 $phpcsFile->fixer->replaceToken($stackPtr, '<?php echo ');
             } else {
                 $phpcsFile->fixer->replaceToken($stackPtr, '<?php echo');
             }
         }
     }
 }
예제 #15
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_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
  */
 public function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
 {
     $tokens = $phpcsFile->getTokens();
     $function = $tokens[$stackPtr + 2];
     if ($function['code'] !== T_STRING) {
         return;
     }
     $functionName = $function['content'];
     $classOpener = $tokens[$currScope]['scope_condition'];
     $className = $tokens[$classOpener + 2]['content'];
     $methodProps = $phpcsFile->getMethodProperties($stackPtr);
     if ($methodProps['is_static'] === true) {
         if (isset($tokens[$stackPtr]['scope_closer']) === false) {
             // There is no scope opener or closer, so the function
             // must be abstract.
             return;
         }
         $thisUsage = $stackPtr;
         while (($thisUsage = $phpcsFile->findNext(array(T_VARIABLE), $thisUsage + 1, $tokens[$stackPtr]['scope_closer'], false, '$this')) !== false) {
             if ($thisUsage === false) {
                 return;
             }
             $error = 'Usage of "$this" in static methods will cause runtime errors';
             $phpcsFile->addError($error, $thisUsage, 'Found');
         }
     }
     //end if
 }
예제 #16
0
 /**
  * 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(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;
     }
 }
예제 #17
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr);
     if ($closeTag === false) {
         $error = 'The PHP open tag does not have a corresponding PHP close tag';
         $phpcsFile->addError($error, $stackPtr, 'NotFound');
     }
 }
예제 #18
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $nextClass = $phpcsFile->findNext($this->register(), $stackPtr + 1);
     if ($nextClass !== false) {
         $error = 'Only one class is allowed in a file';
         $phpcsFile->addError($error, $nextClass, 'MultipleFound');
     }
 }
예제 #19
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $next = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
     if ($next === false || $tokens[$next]['code'] === T_CLOSE_CURLY_BRACKET) {
         $error = 'Class definition is empty';
         $phpcsFile->addError($error, $stackPtr, 'Found');
     }
 }
예제 #20
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $next = $phpcsFile->findNext(array(T_WHITESPACE, T_COLON), $stackPtr + 1, null, true);
     if ($next === false || $tokens[$next]['code'] === T_SEMICOLON || $tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
         $error = 'Style definition is empty';
         $phpcsFile->addError($error, $stackPtr, 'Found');
     }
 }
예제 #21
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $nextVar = $tokens[$phpcsFile->findNext(array(T_VARIABLE), $stackPtr)];
     $varName = str_replace('$', '', $nextVar['content']);
     $error = 'Use of the "global" keyword is forbidden; use "$GLOBALS[\'%s\']" instead';
     $data = array($varName);
     $phpcsFile->addError($error, $stackPtr, 'NotAllowed', $data);
 }
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Ignore default value assignments in function definitions.
     $function = $phpcsFile->findPrevious(T_FUNCTION, $stackPtr - 1, null, false, null, true);
     if ($function !== false) {
         $opener = $tokens[$function]['parenthesis_opener'];
         $closer = $tokens[$function]['parenthesis_closer'];
         if ($opener < $stackPtr && $closer > $stackPtr) {
             return;
         }
     }
     // Ignore values in array definitions.
     $array = $phpcsFile->findNext(T_ARRAY, $stackPtr + 1, null, false, null, true);
     if ($array !== false) {
         return;
     }
     // Ignore function calls.
     $ignore = array(T_STRING, T_WHITESPACE, T_OBJECT_OPERATOR);
     $next = $phpcsFile->findNext($ignore, $stackPtr + 1, null, true);
     if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS && $tokens[$next - 1]['code'] === T_STRING) {
         // Code will look like: $var = myFunction(
         // and will be ignored.
         return;
     }
     $endStatement = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1);
     if ($tokens[$stackPtr]['conditions'] !== $tokens[$endStatement]['conditions']) {
         // This statement doesn't end with a semicolon, which is the case for
         // the last expression in a for loop.
         return;
     }
     for ($i = $stackPtr + 1; $i < $endStatement; $i++) {
         if (isset(Tokens::$comparisonTokens[$tokens[$i]['code']]) === true || $tokens[$i]['code'] === T_INLINE_THEN) {
             $error = 'The value of a comparison must not be assigned to a variable';
             $phpcsFile->addError($error, $stackPtr, 'AssignedComparison');
             break;
         }
         if (isset(Tokens::$booleanOperators[$tokens[$i]['code']]) === true || $tokens[$i]['code'] === T_BOOLEAN_NOT) {
             $error = 'The value of a boolean operation must not be assigned to a variable';
             $phpcsFile->addError($error, $stackPtr, 'AssignedBool');
             break;
         }
     }
 }
예제 #23
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @param int                  $stackPtr  The position of the current token in the
  *                                        stack passed in $tokens.
  *
  * @return void
  */
 public function process(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $scopeStart = $tokens[$stackPtr]['scope_opener'];
     $firstContent = $phpcsFile->findNext(T_WHITESPACE, $scopeStart + 1, $tokens[$stackPtr]['scope_closer'], true);
     if ($firstContent === false) {
         $error = 'Empty CATCH statement must have a comment to explain why the exception is not handled';
         $phpcsFile->addError($error, $scopeStart, 'Missing');
     }
 }
예제 #24
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Make sure it is an API function. We know this by the doc comment.
     $commentEnd = $phpcsFile->findPrevious(T_DOC_COMMENT_CLOSE_TAG, $stackPtr);
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $commentEnd - 1);
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart);
     if (strpos($comment, '* @api') === false) {
         return;
     }
     // Find all the vars passed in as we are only interested in comparisons
     // to NULL for these specific variables.
     $foundVars = array();
     $open = $tokens[$stackPtr]['parenthesis_opener'];
     $close = $tokens[$stackPtr]['parenthesis_closer'];
     for ($i = $open + 1; $i < $close; $i++) {
         if ($tokens[$i]['code'] === T_VARIABLE) {
             $foundVars[$tokens[$i]['content']] = true;
         }
     }
     if (empty($foundVars) === true) {
         return;
     }
     $start = $tokens[$stackPtr]['scope_opener'];
     $end = $tokens[$stackPtr]['scope_closer'];
     for ($i = $start + 1; $i < $end; $i++) {
         if ($tokens[$i]['code'] !== T_VARIABLE || isset($foundVars[$tokens[$i]['content']]) === false) {
             continue;
         }
         $operator = $phpcsFile->findNext(T_WHITESPACE, $i + 1, null, true);
         if ($tokens[$operator]['code'] !== T_IS_IDENTICAL && $tokens[$operator]['code'] !== T_IS_NOT_IDENTICAL) {
             continue;
         }
         $nullValue = $phpcsFile->findNext(T_WHITESPACE, $operator + 1, null, true);
         if ($tokens[$nullValue]['code'] !== T_NULL) {
             continue;
         }
         $error = 'Values submitted via Ajax requests should not be compared directly to NULL; use empty() instead';
         $phpcsFile->addWarning($error, $nullValue, 'Found');
     }
     //end for
 }
예제 #25
0
 /**
  * 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(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);
     }
 }
예제 #26
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // If the close php tag is on the same line as the opening
     // then we have an inline embedded PHP block.
     $closeTag = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr);
     if ($closeTag === false || $tokens[$stackPtr]['line'] !== $tokens[$closeTag]['line']) {
         $this->validateMultilineEmbeddedPhp($phpcsFile, $stackPtr);
     } else {
         $this->validateInlineEmbeddedPhp($phpcsFile, $stackPtr);
     }
 }
예제 #27
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $namespace = '';
     $findTokens = array(T_CLASS, T_INTERFACE, T_NAMESPACE, T_CLOSE_TAG);
     $stackPtr = $phpcsFile->findNext($findTokens, $stackPtr + 1);
     while ($stackPtr !== false) {
         if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
             // We can stop here. The sniff will continue from the next open
             // tag when PHPCS reaches that token, if there is one.
             return;
         }
         // Keep track of what namespace we are in.
         if ($tokens[$stackPtr]['code'] === T_NAMESPACE) {
             $nsEnd = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING, T_WHITESPACE), $stackPtr + 1, null, true);
             $namespace = trim($phpcsFile->getTokensAsString($stackPtr + 1, $nsEnd - $stackPtr - 1));
             $stackPtr = $nsEnd;
         } else {
             $nameToken = $phpcsFile->findNext(T_STRING, $stackPtr);
             $name = $tokens[$nameToken]['content'];
             if ($namespace !== '') {
                 $name = $namespace . '\\' . $name;
             }
             $compareName = strtolower($name);
             if (isset($this->foundClasses[$compareName]) === true) {
                 $type = strtolower($tokens[$stackPtr]['content']);
                 $file = $this->foundClasses[$compareName]['file'];
                 $line = $this->foundClasses[$compareName]['line'];
                 $error = 'Duplicate %s name "%s" found; first defined in %s on line %s';
                 $data = array($type, $name, $file, $line);
                 $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
             } else {
                 $this->foundClasses[$compareName] = array('file' => $phpcsFile->getFilename(), 'line' => $tokens[$stackPtr]['line']);
             }
         }
         //end if
         $stackPtr = $phpcsFile->findNext($findTokens, $stackPtr + 1);
     }
     //end while
 }
예제 #28
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $argStart = $tokens[$stackPtr]['parenthesis_opener'];
     $argEnd = $tokens[$stackPtr]['parenthesis_closer'];
     // Flag for when we have found a default in our arg list.
     // If there is a value without a default after this, it is an error.
     $defaultFound = false;
     $nextArg = $argStart;
     while (($nextArg = $phpcsFile->findNext(T_VARIABLE, $nextArg + 1, $argEnd)) !== false) {
         if ($tokens[$nextArg - 1]['code'] === T_ELLIPSIS) {
             continue;
         }
         $argHasDefault = false;
         $next = $phpcsFile->findNext(Tokens::$emptyTokens, $nextArg + 1, null, true);
         if ($tokens[$next]['code'] === T_EQUAL) {
             $argHasDefault = true;
         }
         if ($argHasDefault === false && $defaultFound === true) {
             $error = 'Arguments with default values must be at the end of the argument list';
             $phpcsFile->addError($error, $nextArg, 'NotAtEnd');
             return;
         }
         if ($argHasDefault === true) {
             $defaultFound = true;
             // Check if the arg is type hinted and using NULL for the default.
             // This does not make the argument optional - it just allows NULL
             // to be passed in.
             $next = $phpcsFile->findNext(Tokens::$emptyTokens, $next + 1, null, true);
             if ($tokens[$next]['code'] === T_NULL) {
                 $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $nextArg - 1, null, true);
                 if ($tokens[$prev]['code'] === T_STRING || $tokens[$prev]['code'] === T_ARRAY_HINT) {
                     $defaultFound = false;
                 }
             }
         }
     }
     //end while
 }
예제 #29
0
 /**
  * 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(File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Find the content of each class definition name.
     $classNames = array();
     $next = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr + 1);
     if ($next === false) {
         // No class definitions in the file.
         return;
     }
     // Save the class names in a "scope",
     // to prevent false positives with @media blocks.
     $scope = 'main';
     $find = array(T_CLOSE_CURLY_BRACKET, T_OPEN_CURLY_BRACKET, T_COMMENT, T_OPEN_TAG);
     while ($next !== false) {
         $prev = $phpcsFile->findPrevious($find, $next - 1);
         // Check if an inner block was closed.
         $beforePrev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $prev - 1, null, true);
         if ($beforePrev !== false && $tokens[$beforePrev]['code'] === T_CLOSE_CURLY_BRACKET) {
             $scope = 'main';
         }
         // Create a sorted name for the class so we can compare classes
         // even when the individual names are all over the place.
         $name = '';
         for ($i = $prev + 1; $i < $next; $i++) {
             $name .= $tokens[$i]['content'];
         }
         $name = trim($name);
         $name = str_replace("\n", ' ', $name);
         $name = preg_replace('|[\\s]+|', ' ', $name);
         $name = str_replace(', ', ',', $name);
         $names = explode(',', $name);
         sort($names);
         $name = implode(',', $names);
         if ($name[0] === '@') {
             // Media block has its own "scope".
             $scope = $name;
         } else {
             if (isset($classNames[$scope][$name]) === true) {
                 $first = $classNames[$scope][$name];
                 $error = 'Duplicate class definition found; first defined on line %s';
                 $data = array($tokens[$first]['line']);
                 $phpcsFile->addError($error, $next, 'Found', $data);
             } else {
                 $classNames[$scope][$name] = $next;
             }
         }
         $next = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $next + 1);
     }
     //end while
 }
예제 #30
0
 /**
  * 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(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);
     }
 }